为何js计算带有小数的加法的时候会出现误差?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为何js计算带有小数的加法的时候会出现误差?相关的知识,希望对你有一定的参考价值。

参考技术A 很正常的,浮点数运算的误差。哪种语言都这样,只是误差大小不同而已。 \\x0d\\x0a 用解析字符串的方式移动小数点,转化为整数,完毕后,在把小数点复位。 \\x0d\\x0a 浮点数运算的时候,先转化为二进制,用二进制来算,结果再转回十进制 \\x0d\\x0a 例如 :求1038.1-1000 \\x0d\\x0a 1038.1=10000001110.0001100110011001100110011001100110011001100..... \\x0d\\x0a 1000= 1111101000 \\x0d\\x0a 1038.1转化为二进制是个无限循环小数,1100是循环节,只能取近似值,误差就是这里产生的 \\x0d\\x0a如果浏览器版本高,可以用toFixed() 方法可把 Number 四舍五入为指定小数位数的数字.\\x0d\\x0a后有固定的 num 位数字。如果必要,该数字会被舍入,也可以用 0 补足,以便它达到指定的长度。如果 num 大于 le+21,则该方法只调用 NumberObject.toString(),返回采用指数计数法表示的字符串。\\x0d\\x0a语法\\x0d\\x0aNumberObject.toFixed(num)\\x0d\\x0a返回值\\x0d\\x0a返回 NumberObject 的字符串表示,不采用指数计数法,小数点后有固定的 num 位数字。如果必要,该数字会被舍入,也可以用 0 补足,以便它达到指定的长度。如果 num 大于 le+21,则该方法只调用 NumberObject.toString(),返回采用指数计数法表示的字符串。\\x0d\\x0a\\x0d\\x0a抛出\\x0d\\x0a当 num 太小或太大时抛出异常 RangeError。0 ~ 20 之间的值不会引发该异常。有些实现支持更大范围或更小范围内的值。\\x0d\\x0a\\x0d\\x0a当调用该方法的对象不是 Number 时抛出 TypeError 异常。\\x0d\\x0a在本例中,我们将把数字舍入为仅有一位小数的数字:\\x0d\\x0a\\x0d\\x0aShow the number 13.37 with one decimal:\\x0d\\x0a\\x0d\\x0a\\x0d\\x0a输出:\\x0d\\x0aShow the number 13.37 with one decimal:\\x0d\\x0a13.4

python中的减法有问题

python中1.2-1为什么不是0.2呢,求大侠指点一二,谢谢!!!!

【造成这个问题的原因分析】:在计算机中,所有的数都是二进制保存,十进制的小数在和二进制数字相互转化的时候,就会出现误差,也就是浮点数的精确度。由于浮点数的精确度不可能完全精准,所以出现这样的情况在所难免。所以会出现问题的截图中所示的状态。

【解决方法】:可以通过将小数减法变为整数减法降低误差。如下图所示:

参考技术A 首先,[问题的成因]:因为计算机中的数都是以二进制存储的,十进制的某些小数是无法用有穷个二进制表示的,于是就出现了这样的问题。比如 0.1+0.2就得不到正确的结果。
其次,[为什么C,C++看起来结果是对的]:精度!还是精度的问题!你在C语言中使用的是格式化输出比如%f,这种格式化输出默认采用的四舍五入策略,导致它看上去似乎是对的!如果你用%.30f你就会发现问题了。
最后,[怎么解决问题]:首先将因子乘以10的N次方得到整数,计算之后再除以10的N次方。
比如 计算 0.1 + 0.2 转换为 (0.1*10 + 0.2*10)/10本回答被提问者和网友采纳
参考技术B 应该说计算机中实际运算的数都会转成二进制数进行真正运算,
那么1.2实际的二进制数是多少?是1.00110011.......,
所以1.2-1之后的二进制数是0.00110011.......,
然后再将这个二进制数转换成十进制等于2^(-3)+2^(-4)+2^(-7)+2^(-8)+......
最后根据py本身对浮点数的限制就显示为0.19999999999999996追问

那为什么在C和C++里面就会是0.2呢

参考技术C 有趣的问题,这个问题说起来也简单,在计算机数字都是用二进制来表示的,而十进制小数用二进制来表示在很多情况下就和十进制不能完全吻合,所以会有很小的误差,为了解决这个问题可以明示我们需要十进制

from decimal import *
Decimal(1.2)-Decimal(1)

详细具体的应用可以看
help()
decimal追问

那为什么在C和C++里面就会是0.2呢

追答

关于C可以参考nikoloss的回答

[为什么C,C++看起来结果是对的]:精度!还是精度的问题!你在C语言中使用的是格式化输出比如%f,这种格式化输出默认采用的四舍五入策略,导致它看上去似乎是对的!如果你用%.30f你就会发现问题了。

以上是关于为何js计算带有小数的加法的时候会出现误差?的主要内容,如果未能解决你的问题,请参考以下文章

python中的减法有问题

js浮点数精度误差问题,解决方法

JS小数运算失精度的问题

js小数计算引起的精度误差问题

关于js中小数运算丢失精度的处理办法

大数与小数的求和算法