为什么0.1 + 0.2 != 0.3 ???
1、JavaScript计算的翻车现场
所以,为什么会出现这样的结果呢?哪些计算又会出现这样的问题呢,让我们一步步的来分析一下~~~
2、JavaScript是如何表示数字的
- 计算机遵循 IEEE 754 标准 ,是将信息转化为二进制进行存储的,JavaScript使用Number类型表示数字(整数和浮点数),而JS采用的是双精度版本,也就是通过64位来表示一个数字,具体如下:(1 + 11 + 52)
注意:虽然只有52位来表示有效数字,但是JS的最大安全数字是JS_NUMBER_MAX_SAFE_INTEGER == Math.pow( 2,53)- 1 而不是Math.pow( 2,52)- 1(转成整数就是16位),这是因为二进制表示有效数字总是1.xx…xx的形式,尾数部分f在规约形式下第一位默认为1(省略不写,xx..xx为尾数部分f,最长52位)。因此,JavaScript提供的有效数字最长为53个二进制位(64位浮点的后52位+被省略的1位)
3、运算时发生了什么
一、进制转换
- 十进制整数转化为二进制整数(除2取余,自下而上,逆序排列)
- 十进制小数转化为二进制小数(乘2取整,自上而下,顺序排列)
由上面可知:173 -----> 10101101
0.8125 -----> 0.1101
173.8125 -----> 10101101.1101
- 在工具中直观的表示两者在计算机内存中的表现形式
- 0.1 -----> 0 0011 0011 0011.....(无限循环)
-
- 0.2 -----> 0011 0011 0011.....(无限循环)
2
- 由此可以看出,0.1与0.2都是无限循环小数,JS的双精度版本会对这种小数的二进制进行截取有效位数,从而造成精度丢失。
- 由于JS的最大安全数字是16位,因此我们可以通过number.toPrecision(16)来进行精度运算,超过的部分会自动进行凑整处理。
二、对阶运算
- 由于指数位数不相同,运算时需要进行对阶运算,因此也有可能造成精度丢失。
!!!结果:精度丢失可能出现在进制转化或者对阶运算中
3、以后如何解决
4、参考资料(哈哈哈,尊重作者,其实我就是写了一遍加深记忆~~~)
北栀女孩儿