我有一个简单的间隔,每次减去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
答案 0 :(得分: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
是一个局部变量。
答案 1 :(得分:0)
这是因为浮动数字的表示方式。计算机将尽可能准确地为您提供值0.7
。但是,因为它没有使用基数10,所以它可以接近0.7
的最精确值将是0.7000000000000001
。当你减去另一个0.1时,会发生同样的事情,依此类推。
答案 2 :(得分:0)
Javascript浮点因这类问题而闻名;这是由于(我在这里引用the good book),“[Javascript]采用了IEEE二进制浮点运算标准(IEEE 1754)”。
建议的解决方案是使用整数值 - 对于您的场景,将不透明度值乘以100,进行计算,然后除以100以将值转换回十进制值是合乎逻辑的。