2

我有一个简单的间隔,每次减去 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

4

3 回答 3

1

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

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

但是,您的函数实际上仍然可以正常工作,因为您只是在寻找< 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为局部变量。

于 2013-10-16T22:21:57.830 回答
0

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

于 2013-10-16T22:22:00.577 回答
0

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

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

于 2013-10-16T22:22:20.713 回答