理解 JavaScript 中数字的底层存储格式(IEEE 754 双精度浮点数)
掌握科学计数法、不同进制字面量的使用方式
了解浮点数精度问题及其常见解决方案
熟悉 JavaScript 中的类型自动转换规则
掌握常用 Number 对象方法的使用场景
JavaScript 的数字是原始数据类型,与其他语言(如 C++、Java)不同,它不区分整型(int)、浮点型(float)等。所有数字都以 IEEE 754 标准的双精度 64 位二进制格式存储:
第 0–51 位:存储有效数字(尾数部分)
第 52–62 位:存储指数部分
第 63 位:存储符号位(0 为正,1 为负)
这意味着:
整数和小数在内部使用同一套表示方式
安全整数范围为:-(2^53 - 1) 到 2^53 - 1(即 -9007199254740991 到 9007199254740991)
超出此范围的整数可能丢失精度
let a = 999999999999999; // 15 位,安全
let b = 9999999999999999; // 16 位,超出安全范围
console.log(a); // 999999999999999
console.log(b); // 10000000000000000(精度丢失!)JavaScript 支持用 e 或 E 表示科学计数法,适用于极大或极小的数值:
let large = 156e5; // 相当于 156 × 10⁵ = 15,600,000
let small = 156e-5; // 相当于 156 × 10⁻⁵ = 0.00156
console.log(large); // 15600000
console.log(small); // 0.00156由于二进制无法精确表示某些十进制小数(如 0.1),浮点运算可能存在微小误差:
let x = 0.22 + 0.12;
console.log(x); // 0.33999999999999997(非预期结果)解决方案:缩放法(Scaling)
通过先放大再缩小的方式规避精度问题:
let y = (0.22 * 10 + 0.12 * 10) / 10;
console.log(y); // 0.34(正确结果)更健壮的做法是使用
Number.EPSILON或第三方库(如decimal.js)处理高精度计算。
JavaScript 的 + 运算符具有双重语义:
两个操作数均为数字 → 执行加法
任一操作数为字符串 → 执行字符串拼接
// 数字相加
let numSum = 10 + 15;
console.log(numSum); // 25
// 字符串拼接
let strConcat = "10" + "30";
console.log(strConcat); // "1030"
// 混合类型:数字转字符串
let mix = 10 + "30";
console.log(mix); // "1030"在非加法的算术运算中(如 /, *, -),JavaScript 会自动将字符串转为数字:
let x = "100" / "10"; // 10
let y = "100" * "10"; // 1000
let z = "100" - "10"; // 90
console.log(x, y, z); // 10 1000 90注意:
"100" + "10"是字符串拼接(结果为"10010"),而"100" - "10"是数值减法(结果为90)。
JavaScript 支持多种进制的数字字面量:
console.log(0o562); // 370(八进制)
console.log(0b11); // 3(二进制)
console.log(0xfff); // 4095(十六进制)现代 JavaScript 推荐使用
0o表示八进制(避免与十进制混淆),0开头的八进制写法已不推荐。
当不同类型的值参与运算时,JavaScript 会自动进行类型转换:
// undefined → NaN
console.log(undefined + 10); // NaN
// null → 0
console.log(null + 5); // 5
// Boolean → Number
console.log(true + 10); // 11
console.log(false + 10); // 10
// String → Number
console.log(Number("42")); // 42
console.log(Number("hello")); // NaN
// Symbol 无法转数字
// console.log(Number(Symbol())); // 抛出 TypeErrorJavaScript 提供了丰富的 Number 原型方法用于格式化和检测:
let num = 21;
console.log(num.toString()); // "21"
console.log(num.toExponential()); // "2.1e+1"
console.log(num.toPrecision(4)); // "21.00"(保留4位有效数字)
console.log(Number.isInteger(num)); // true
console.log(num.toLocaleString("bn-BD")); // "২১"(孟加拉语数字)BigInt:用于表示任意长度的整数(如 123n),与普通 Number 类型不兼容
Number 对象 vs 原始值:new Number(42) 创建的是对象,应避免使用(性能差且行为异常)
进制转换:num.toString(2) 可将数字转为二进制字符串,支持 2~36 进制
console.log((42).toString(2)); // "101010"
console.log((255).toString(16)); // "ff"JavaScript 只有一种数字类型:IEEE 754 双精度浮点数
安全整数范围:±(2^53 - 1),超出将丢失精度
浮点运算存在精度问题,可通过缩放法临时解决
+ 运算符在遇到字符串时执行拼接而非加法
非加法算术运算会自动将字符串转为数字
支持二进制(0b)、八进制(0o)、十六进制(0x)字面量
类型强制转换遵循特定规则(如 null→0, true→1)
使用 Number.isInteger() 判断整数,而非 typeof
为什么 0.1 + 0.2 !== 0.3 在 JavaScript 中成立?如何安全地比较两个浮点数是否“相等”?
执行 console.log("5" - "2" + "3") 和 console.log("5" + "2" - "3") 的结果分别是什么?请解释运算顺序和类型转换过程。
如何将一个十进制数字 255 转换为十六进制字符串 "ff"?如果要转换为大写 "FF" 又该如何实现?