>  Q&A  >  본문

javascript - js小数计算如何保证得到正确的值?

alert(0.3 - (0.1 + 0.2));

喵了个咪的,竟然等于-5.551115123125783e-17
有什么办法可以优雅的解决这种语言自身的bug吗?

ringa_leeringa_lee2770일 전555

모든 응답(5)나는 대답할 것이다

  • 巴扎黑

    巴扎黑2017-04-10 14:38:44

    原因

    1.首先我们要知道,这个误差并非是javascript的误差,这是一个数学问题,通过离散数学碰撞来模拟造成的必然结果!或者说应该是硬件先天性缺陷导致无法规避这个问题吧。
    2.如果我没记错,所有采用 IEEE 754[1] 的实现的系统应该都会存在这个问题,无论是java还是python ... etc.
    3.好吧,说实话,我也不太记得清楚了,可以参考下What Every Computer Scientist Should Know About Floating-Point Arithmetic
    4.这个问题,我想说你是不是有点懒啊wiki,给予我们详细的解释了

    解决办法

    思路:
    1.解决的思路无非是转换成整数计算,即先乘一个大的数再除去一个数,因为计算误差是由浮点运算引起的
    2.这里我又想说你懒惰了,万能的google,这里绝对可以帮到你?
    好吧,纵容你这次,我这里直接给出链接:博客园的js浮点运算bug的解决办法

    summary

    1.提问的人很懒,我很勤快 XD
    2.IEEE这规范不要求熟记,尼玛,大概看看总没问题吧,好吧我也讨厌这货,长篇大论,但是我大概还是有点印象的,好吧,具体多少对应什么问题,我貌似没记清楚,后来查了下
    3.这里你起码好好的了解下IEEE 754,食物喂到这里了,点进去看看没问题吧

    회신하다
    0
  • 天蓬老师

    天蓬老师2017-04-10 14:38:44

    也不能算bug吧,某些小数因为浮点数二进制表示法的固有缺陷,是无法避免的。所以在银行等敏感的系统中,一般0.1美元都会表示成10美分,即尽量使用整数。

    如果需要比较两个浮点数表达式是否相同的话,可以采取以下方法:

    var diff = 1e-6; /* 允许最大误差0.000001 */
    var exp1 = 0.3;
    var exp2 = 0.1 + 0.2;
    
    console.log(exp1 === exp2); /* false */
    console.log(exp1 - exp2 < diff); /* true */
    

    회신하다
    0
  • 怪我咯

    怪我咯2017-04-10 14:38:44

    以前用过,目前还没遇到过大问题 代码地址https://gist.github.com/369679209/4fb71c02fc16c41b475c

    회신하다
    0
  • 巴扎黑

    巴扎黑2017-04-10 14:38:44

    不涉及乘除的话,可以给每个数乘100,然后再计算,结果除100

    회신하다
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-10 14:38:44

    Javascript的浮点数精度本来就不高,所以计算的时候出现较大的误差是很正常的。
    一般进行浮点运算都会有个精度要求,比如精确到小数点后两位,那么你那段程序就可以写成

    var r = (0.3 - (0.1 + 0.2)).toFixed(2)
    // r 是 string 的 -0.00
    // 然后可以再把它转换成 float 类型
    var f = parseFloat(r)
    // 得到 f 是 -0,不过跟 0 是相等的 f === 0
    

    회신하다
    0
  • 취소회신하다