Number/Math 与 BigInt
数值增强
javascript
1_000_000 === 1000000; // true(数字分隔符)
Number.isNaN(NaN); // true(比 isNaN 更严格)
Number.isFinite(42); // true
1
2
3
2
3
Math 常用
javascript
Math.trunc(3.9); // 3
Math.sign(-7); // -1
Math.clz32(1); // 31(前导零位数)
1
2
3
2
3
BigInt
javascript
const big = 12345678901234567890n; // 以 n 结尾
console.log(big + 10n);
// BigInt 与 Number 不能混算,需显式转换
1
2
3
2
3
场景:大整数处理、ID、加密相关。
数字字面量与分隔符
- 二进制:
0b1010
;八进制:0o755
;十六进制:0xFF
; - 数字分隔符:
1_000_000
,提升可读性但不影响数值; - 科学计数:
1.2e3 === 1200
。
安全整数与精度
- JS Number 为 IEEE-754 双精度浮点,安全整数范围:
-(2^53-1) ~ 2^53-1
; Number.isSafeInteger(x)
检查是否安全;- 浮点误差:
0.1 + 0.2 !== 0.3
,需使用容差比较:
javascript
function nearlyEqual(a, b, eps = Number.EPSILON) {
return Math.abs(a - b) < eps;
}
1
2
3
2
3
四舍五入与格式化
javascript
Math.round(1.5); // 2
Math.floor(-1.2); // -2
Math.ceil(-1.2); // -1
// 小数位四舍五入
function roundTo(x, n = 2) {
const p = 10 ** n;
return Math.round(x * p) / p;
}
(1234.567).toFixed(2); // '1234.57'(返回字符串)
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
随机数与可复现随机(提示)
Math.random()
不是可复现的。若需可复现随机,请使用种子随机算法(参见“随机与可复现随机”章节)。
BigInt 进阶
- 声明:在整数字面量结尾加
n
; - 仅支持整数运算(加减乘除取模),无小数;
- 不能与 Number 混算:
1n + 1
会抛错; - 显式转换:
BigInt(42)
或Number(10n)
(注意可能溢出)。
javascript
const a = 2n ** 53n; // 超过 Number 安全整数
const b = BigInt(Number.MAX_SAFE_INTEGER) + 1n;
console.log(a > b);
1
2
3
2
3
何时用 BigInt:
- 金额四则运算建议用整数分单位 + 格式化,或使用十进制库;
- 大整数 ID、计数器、加密相关、时间戳运算等。
常见陷阱
- 浮点误差导致比较/累加异常;
parseInt
/parseFloat
与Number()
行为差异(字符串前后空白、非数字字符);- BigInt 与 JSON:
JSON.stringify({ x: 1n })
会抛错(需自定义序列化)。
最佳实践
- 使用容差进行浮点比较;
- 金额等需要精确小数的场景使用十进制库或整数分;
- 对于超过安全范围的整数使用 BigInt;
- 用
Intl.NumberFormat
做本地化格式化(参见 Intl 章节)。
练习
- 实现
roundTo(x, n)
与nearlyEqual(a,b,eps)
并编写测试用例; - 用 BigInt 写一个大整数幂模计算(
powMod
)的简单实现; - 将一段金额运算从浮点改为“分”为单位的整数实现,并格式化输出。