前言
面试官:0.1 + 0.2 等于多少?
我:
我:反正不等于0.3
一、JavaScript 中的浮点数
在 JavaScript 中,所有数字(无论是整数还是浮点数)都是以 双精度浮点数(double-precision floating-point format) 来存储的。这是根据 IEEE 754 标准定义的,意味着它遵循与其他编程语言类似的浮点数表示规则。
然而,双精度浮点数在表示某些十进制数时也存在精度问题。就像我们在前面提到的 0.1
和 0.2
,这些数字在二进制浮点数中无法精确表示。
二、为什么 0.1 + 0.2 != 0.3
?
0.1
和 0.2
在二进制浮点数中无法被精确表示,它们是循环小数。具体来说:
0.1
在二进制中是:0.00011001100110011001100110011...
,它是一个无限循环小数。0.2
也在二进制中是一个无法精确表示的值:0.00110011001100110011001100110...
。
当你执行 0.1 + 0.2
时,计算机在存储这些值时会做出一定的舍入,从而导致最终的计算结果不等于你期望的 0.3
。
三、JS 示例
我们可以通过代码在 JavaScript 中验证这个现象。
// 浮点数加法
let result = 0.1 + 0.2;
console.log(result); // 输出:0.30000000000000004
console.log(result === 0.3); // 输出:false
运行结果:
0.1 + 0.2 = 0.30000000000000004
0.1 + 0.2 == 0.3? false
如你所见,0.1 + 0.2
结果是 0.30000000000000004
,它并不等于 0.3
,这就是因为浮点数运算的精度问题。
四、解决浮点数误差
为了避免浮点数误差,JavaScript 中有几种常见的方法:
1. 通过四舍五入来处理误差
我们可以通过四舍五入的方式将结果精确到指定的小数位。比如,如果你想让计算结果精确到小数点后 2 位,可以这样做:
let result = 0.1 + 0.2;
result = Math.round(result * 100) / 100;
console.log(result); // 输出:0.3
console.log(result === 0.3); // 输出:true
2. 使用 Number.toFixed()
方法
toFixed()
方法可以将浮点数转换为固定小数位的字符串,这样就可以避免计算中出现的精度误差。
let result = 0.1 + 0.2;
result = result.toFixed(2); // 将结果格式化为2位小数
console.log(result); // 输出:0.30
console.log(parseFloat(result) === 0.3); // 输出:true
注意:toFixed()
返回的是字符串类型,因此你可能需要使用 parseFloat()
或 parseInt()
将其转换回数字进行比较。
3. 通过乘法转换为整数
与其他编程语言类似,你也可以通过将浮点数乘以一个常数(比如 100)转换为整数进行计算,最后再除以这个常数恢复为小数。这种方法通常适用于货币等需要精确计算小数的场景。
let result = (0.1 * 100 + 0.2 * 100) / 100;
console.log(result); // 输出:0.3
console.log(result === 0.3); // 输出:true
五、总结
在 JavaScript 中,0.1 + 0.2 != 0.3
是因为浮点数的存储方式导致精度误差。浮点数无法精确表示某些十进制数(例如 0.1 和 0.2),因此加法运算的结果会偏离期望值。
你可以通过以下方法来避免或修正这种问题:
- 使用
Math.round()
来四舍五入到特定的小数位。 - 使用
toFixed()
来将结果格式化为固定的小数位。 - 将浮点数转为整数进行计算,再恢复小数。
这些方法可以有效地减小误差,确保结果符合预期。
现在可以跟面试官大声说出来0.1 + 0.2 等于多少了
没错,等于0.3(15个0)4