我正在遍历一个 if语句循环一个随时间衰减的对象,每次都取值并减去-0.2
。在第一次通过该号码后,将获得0.9653677422
之类的所有奇怪的内容,而不是0.2 (4.2, 4.0, 3.8, 3.6...etc)
的倍数。
初始值为7
。
示例:
if (this.health > 0){
this.health = this.health - 0.2;
}else{
return;
}
为什么从processing.js的值中减去-0.2
会将整数转换为无理数?
编辑***
通过adonike's answer我了解到使用浮动二进制点数不能以100%的准确度表示小数。通过将所有数字保持为整数(将初始值乘以10以及减去该值),可以保留相同的衰减率(每个循环1/35)而不会丢失精度。初始值为70
,衰减率为2
(减去数量)&一切顺利。
对于初始值也可以是35
,对于相同的所需结果减去的数字,1
也可以。
如需了解详情,请参阅:Why can't decimal numbers be represented exactly in binary?以及Kevin Workman's answer中提供的链接。
此问题的代码如下所示:
var Tile = function(x, y, sourceImg) {
this.x = x;
this.y = y;
this.width = 25;
this.health = 35;
this.healthMax = this.health;
this.decayRate = 1;
this.daysOld = 0;
};
和
Tile.prototype.drawPlantTiles = function() {
if (this.health > this.healthMax/2){
this.occupied = true;
fill(168, 118, 25);
stroke(163, 109, 21);
rect(this.x, this.y, this.width, this.width,0);
strokeWeight(1);
noStroke();
image(plantImg1, this.x, this.y, this.width, this.width);
this.health = this.health - this.decayRate;
this.daysOld++;
} else if (this.health > this.healthMax/4 && this.health <= this.healthMax/2){
this.occupied = true;
fill(168, 118, 25);
stroke(163, 109, 21);
rect(this.x, this.y, this.width, this.width,0);
strokeWeight(1);
noStroke();
image(plantImg2, this.x, this.y, this.width, this.width);
this.health = this.health - this.decayRate;
this.daysOld++;
} else if (this.health > 0 && this.health <= this.healthMax/4){
this.occupied = true;
fill(168, 118, 25);
stroke(163, 109, 21);
rect(this.x, this.y, this.width, this.width,0);
strokeWeight(1);
noStroke();
image(plantImg3, this.x, this.y, this.width, this.width);
this.health = this.health - this.decayRate;
this.daysOld++;
}else{
fill(168, 118, 25);
stroke(163, 109, 21);
rect(this.x, this.y, this.width, this.width,0);
strokeWeight(1);
noStroke();
this.state = false;
return;
}
};
注意:&#34; this.healthMax&#34;仍然需要重新设计阈值以删除所有小数/保持100%的精度。
答案 0 :(得分:1)
另一个答案是正确的,但我想提供更多细节。
以下是此问题的首页:What Every Computer Scientist Should Know About Floating-Point Arithmetic
以下是一个较短的JavaScript特定版本:What Every JavaScript Developer Should Know About Floating Points
本文列出了一些解决问题的解决方法的库:
toPrecision()
和toFixed()
函数另见:
答案 1 :(得分:0)
这是因为浮点运算不是100%准确。没有办法以二进制形式表示小数。
在javascript中,所有数字都被视为64位浮点数。
为了帮助你的特殊情况(使用0.2或-0.2的增量)你可以在增加之前乘以10,然后运算然后除以10:
if (this.health > 0){
this.health = (this.health * 10 - 2) / 10;
}else{
return;
}