【问题标题】:Javascript subtract giving unexpected value [duplicate]Javascript减去给出意外的值[重复]
【发布时间】:2013-10-25 05:57:33
【问题描述】:

我有一个简单的区间,每次减去 0.1。但是数字序列在 3 次迭代后变得很奇怪......这就是我所拥有的:

function transition_opacity(div_id,opacity){
    opacity = 1; //temporary test
    var IntervId = setInterval(process_transition,30);

    function process_transition(){
        console.log(opacity); //check the value
        opacity = opacity -  0.1
        div_id.style.opacity = opacity;
    if(opacity < 0.0){
            rmv_div(div_id);
            clear();
        }
    }

    function clear(){
         clearInterval(IntervId);
    }
}

控制台日志显示 opacity 的值:

1
0.9 
0.8 
0.7000000000000001
0.6000000000000001
0.5000000000000001
0.40000000000000013 
0.30000000000000016
0.20000000000000015
0.10000000000000014
1.3877787807814457e-16 

为什么要执行这个疯狂的数字序列 =/ 对我来说似乎没有意义...它在 0.8 以内也能正常工作

【问题讨论】:

标签: javascript


【解决方案1】:

对于某些无法以浮点存储其数字的方式完美表示的值,浮点数学并不精确。您所看到的只是确切值的细微差别。

这通常可以通过将您的值四舍五入到一定的小数位来解决。您可以通过对该主题的简单 Google 搜索尽可能多地阅读有关浮点精度的信息。一个经典的解决方法是将您的值四舍五入到一定数量的小数点。

但是,您的函数实际上仍然可以正常工作,因为您只是在寻找 &lt; 0,即使值存在细微差异,它仍然可以为您提供适当的迭代次数。

您实际上并不需要它来让您的函数正常工作,但如果您想要精确的值,您可以像这样四舍五入到小数点后一位:

function transition_opacity(div_id,opacity){
    var opacity = 1; //temporary test
    var IntervId = setInterval(process_transition, 30);

    function process_transition(){
        console.log(opacity); //check the value
        opacity = Math.round((opacity -  0.1) * 100) / 100;
        div_id.style.opacity = opacity;
        if (opacity < 0) {
            rmv_div(div_id);
            clear();
        }
    }

    function clear(){
         clearInterval(IntervId);
    }
}

仅供参考,我还将opacity 声明为局部变量。

【讨论】:

  • 我认为但是在我的 JSFiddle 中检查 &lt; 0 似乎仍然不起作用:jsfiddle.net/4kWCB/12
  • @Dave - 在这里使用我的代码:jsfiddle.net/jfriend00/8Yc7k。我会调查一下为什么它不适合你的。
  • @Dave - 你不起作用,因为 div_id 是一个字符串,而不是一个 DOM 元素,因此 process_transition() 函数在检查不透明度并每次中止之前都会引发异常。在我的 jsFiddle 中查看我是如何将 div_id 转换为 DOM 元素的,或者这是您修复了该问题的代码:jsfiddle.net/jfriend00/mM7wQ。请记住检查您的浏览器错误控制台,因为它通常会在这种情况下向您显示出了什么问题。
  • 啊,这可以解释为什么它在我的网站上有效,但在我的小提琴中无效 xD 感谢您的解释!
【解决方案2】:

这是因为浮点数的表示方式。计算机将尽可能准确地为您提供值0.7。但是,因为它没有使用以 10 为底的值,所以它可以接近0.7 的最精确值将是0.7000000000000001。当你减去另一个 0.1 时,会发生同样的事情,以此类推。

【讨论】:

    【解决方案3】:

    Javascript 浮点以此类问题而闻名;这是由于(我在这里引用the good book),“[Javascript] 采用了 IEEE 二进制浮点算术标准 (IEEE 1754)”。

    推荐的解决方案是使用整数值 - 对于您的方案,将不透明度值乘以 100,进行计算,然后除以 100 以将值转换回十进制值是合乎逻辑的。

    【讨论】:

      猜你喜欢
      • 2013-10-24
      • 1970-01-01
      • 1970-01-01
      • 2014-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多