I was looping through an if statement for an object that decayed over time, taking the value each time and subtracting -0.2
. After the first time through the number would get all bizarre like 0.9653677422
, instead of staying as multiples of 0.2 (4.2, 4.0, 3.8, 3.6...etc)
.
The initial value was 7
.
Example:
if (this.health > 0){
this.health = this.health - 0.2;
}else{
return;
}
Why would subtracting -0.2
from a value with processing.js turn an integer into an irrational number?
Edit***
Via adonike's answer I learned that decimals can't be represented with 100% accuracy using floating binary point numbers. By keeping all of the numbers as integers (multiply the initial value by 10 and also the value being subtracted) the same decay rate could be retained (1/35 per loop) without losing precision. The numbers became 70
for the initial value and 2
for the decay rate (number subtracted) & everything worked out.
It could also just be 35
for initial value and 1
for the number subtracted with the same desired result.
For additional insight into this see: Why can't decimal numbers be represented exactly in binary? and also the links provided in Kevin Workman's answer.
The code that this question derived from is shown below:
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;
};
and
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;
}
};
Note: the "this.healthMax" thresholds still need to be reworked to remove all decimals / maintain 100% precision.