讲解

JavaScript 只有一种数字类型 number:不区分整数和浮点数,统一用 64 位双精度浮点数(IEEE 754)存储。这带来两个直接后果:一是整数安全范围有限,Number.MAX_SAFE_INTEGER 是 2 的 53 次方减 1,超过它的整数可能失去精度;二是小数有精度误差,经典的 0.1 + 0.2 不等于 0.3,而是 0.30000000000000004——这不是 JavaScript 的 bug,是所有用 IEEE 754 的语言的共性。

处理金额等需要精确小数的场景,通行做法是用「分」为单位存整数,展示时再除以 100;超出安全整数范围的场景(如长 ID)用 BigInt——在整数后面加 n 就是 BigInt 字面量,它的运算精确,但注意 BigInt 不能和普通 number 直接混合运算。日常取整、四舍五入用 Math 对象:Math.floor 向下、Math.ceil 向上、Math.round 四舍五入、Math.trunc 直接截断、Math.abs 绝对值、Math.max/Math.min 求最值、Math.random 生成 [0, 1) 的随机数。

数字还有两个特殊值:Infinity(正无穷,比如 1/0)和 NaN(无效数字,比如 Number('abc'))。NaN 有个怪脾气:它不等于任何值,包括它自己,判断时必须用 Number.isNaN()。另外 toFixed(n) 可以把数字格式化成保留 n 位小数的字符串,常用于展示价格。

示例

console.log('精度误差:', 0.1 + 0.2, 0.1 + 0.2 === 0.3);
console.log('安全整数上限:', Number.MAX_SAFE_INTEGER);
console.log('超出上限:', Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2); // true,精度已丢失

// BigInt:精确的大整数
const big = 9007199254740993n;
console.log('BigInt 加法:', big + 1n);

// Math 常用方法
console.log('取整:', Math.floor(3.9), Math.ceil(3.1), Math.round(3.5), Math.trunc(-3.9));
console.log('最值:', Math.max(3, 7, 5), Math.min(3, 7, 5));

// 金额处理:用分存整数
const priceInCents = 1999;
console.log('展示价格:', (priceInCents / 100).toFixed(2), '元');

console.log('Infinity:', 1 / 0, 'NaN 判断:', Number.isNaN(Number('abc')));

常见坑

  • 用 === 比较小数计算结果:0.1 + 0.2 === 0.3 是 false。判断浮点相等要看差值是否小于一个很小的数(如 1e-10)。
  • 把 toFixed 的返回值当数字:toFixed 返回字符串,'19.99' + 1 是字符串拼接。要再参与计算需 Number() 转回来。
  • BigInt 与 number 混算:1n + 1 直接抛 TypeError,要先统一类型。
  • 全局 isNaN 的隐式转换:isNaN('abc') 是 true(先转数字再判断),Number.isNaN('abc') 是 false。判断「是不是 NaN」永远用带 Number. 的版本。

小结

数字只有 number 一种,小数有 IEEE 754 精度误差,大整数用 BigInt。Math 对象覆盖取整、最值、随机数;NaN 要用 Number.isNaN 判断。下一节讲布尔值与「真假值」判定。