JS 数字与Math
学习数字方法和Math对象 · 难度:入门 · +10XP
JavaScript 数字与 Math 对象
JavaScript 中所有数字都以 64 位双精度浮点数(IEEE 754 标准)存储,没有独立的整数类型。这意味着 1 和 1.0 在底层是同一个值。理解 JS 数字的特性、浮点数精度陷阱、以及 Math 对象的丰富方法,是写出正确数值计算代码的前提。
数字的各种表示方式
// 整数与小数
let a = 42;
let b = 3.14;
let c = -7.5;
let d = 1.5e6; // 科学计数法 = 1500000
let e = 1.5e-3; // = 0.0015
// 不同进制(ES6)
let hex = 0xFF; // 十六进制 = 255
let oct = 0o77; // 八进制 = 63
let bin = 0b1010; // 二进制 = 10
// 安全整数范围
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991 (约9千万亿)
console.log(Number.MIN_SAFE_INTEGER); // -9007199254740991
console.log(Number.MAX_VALUE); // 约1.79e+308
特殊数值:Infinity 与 NaN
console.log(1 / 0); // Infinity(正无穷)
console.log(-1 / 0); // -Infinity(负无穷)
console.log(0 / 0); // NaN (Not a Number)
console.log(typeof NaN); // "number" —— 虽然叫"不是数字",类型却是 number
console.log(NaN === NaN); // false —— NaN 是唯一不等于自身的值!
console.log(Number.isNaN(NaN)); // true —— 正确判断 NaN 的方法
console.log(isFinite(100)); // true
console.log(isFinite(Infinity));// false
浮点数精度问题 —— JS 最著名的陷阱
这是 JavaScript 面试中最常被问到的问题之一:0.1 + 0.2 为什么不等于 0.3? 根本原因是二进制浮点数无法精确表示某些十进制小数(就像十进制无法精确表示 1/3 一样),而 JavaScript 遵循 IEEE 754 标准。
// 经典问题
console.log(0.1 + 0.2); // 0.30000000000000004
console.log(0.1 + 0.2 === 0.3); // false!
// 解决方案一:toFixed + 转回数字
console.log(+(0.1 + 0.2).toFixed(1)); // 0.3
// 解决方案二:整数运算(最可靠)
console.log((0.1 * 10 + 0.2 * 10) / 10); // 0.3
// 解决方案三:使用 Number.EPSILON 容差比较
function isEqual(a, b) {
return Math.abs(a - b) < Number.EPSILON;
}
console.log(isEqual(0.1 + 0.2, 0.3)); // true
// 实际应用:金额计算务必使用整数(以分为单位)
let price1 = 1099; // 10.99元,用分表示
let price2 = 2499; // 24.99元
let total = (price1 + price2) / 100; // 35.98 —— 完全精确
数字类型转换方法
| 方法 | 说明 | 示例 | 结果 |
|---|---|---|---|
| Number(val) | 通用转换,严格 | Number("42px") | NaN |
| parseInt(str, radix) | 提取开头整数部分 | parseInt("42px") | 42 |
| parseFloat(str) | 提取开头浮点数 | parseFloat("3.14.5") | 3.14 |
| +str(一元加号) | 等同于 Number() | +"42" | 42 |
| toFixed(n) | 保留n位小数(四舍五入),返回字符串 | (3.14159).toFixed(2) | "3.14" |
| toPrecision(n) | 保留n位有效数字,返回字符串 | (3.14159).toPrecision(3) | "3.14" |
| Number.isInteger(v) | 判断是否为整数(ES6) | Number.isInteger(5.0) | true |
Math 对象 —— 核心数学运算
// 取整四兄弟
console.log(Math.round(3.6)); // 4 四舍五入
console.log(Math.floor(3.9)); // 3 向下取整(地板)
console.log(Math.ceil(3.1)); // 4 向上取整(天花板)
console.log(Math.trunc(3.9)); // 3 截断小数部分(ES6)
// 极值
console.log(Math.max(1, 5, 3, 9, 2)); // 9
console.log(Math.min(1, 5, 3, 9, 2)); // 1
// 处理数组:Math.max(...arr) 或 Math.max.apply(null, arr)
// 随机数
console.log(Math.random()); // 0 ~ 1 之间的随机数(不含1)
// 生成指定范围的随机整数(最常用)
function randInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(randInt(1, 100)); // 1~100的随机整数
// 幂运算
console.log(Math.pow(2, 10)); // 1024(2的10次方)
console.log(2 ** 10); // 1024(ES6指数运算符,更简洁)
console.log(Math.sqrt(144)); // 12(平方根)
console.log(Math.cbrt(27)); // 3(立方根,ES6)
// 绝对值与三角函数
console.log(Math.abs(-42)); // 42
console.log(Math.sin(Math.PI / 2)); // 1(sin 90°)
console.log(Math.cos(Math.PI)); // -1(cos 180°)
console.log(Math.tan(Math.PI / 4)); // 约1(tan 45°)
- 四舍五入工具:编写函数 roundTo(num, decimals),将 num 四舍五入到指定小数位数。例如 roundTo(3.14159, 2) 返回 3.14,roundTo(3.14159, 4) 返回 3.1416。使用 toFixed 或数学运算两种方式实现。
- 随机验证码:编写函数 genCode(length),生成指定长度的纯数字验证码(如 genCode(6) 返回 "384729")。升级:生成包含数字和大小写字母的混合验证码。
- 价格格式化:编写函数 formatPrice(price),将数字格式化为人民币显示:两位小数、千分位逗号、¥ 前缀。如 formatPrice(1234567.89) 返回 "¥1,234,567.89"。
- 进制转换器:编写函数 convertBase(num, fromBase, toBase),将数字从一种进制转换为另一种进制。例如 convertBase("1010", 2, 10) 返回 10,convertBase("FF", 16, 2) 返回 "11111111"。
- 简易计算器:用 prompt 接收两个数字,计算圆的面积(PI * r²)和周长(2 * PI * r),用 Math.PI,结果保留两位小数。然后用 Math.round、Math.floor、Math.ceil 分别对结果取整,对比四种结果。