Hacker News new | past | comments | ask | show | jobs | submit login

Could you explain to a noob why does this happen, exactly?

Is it because 55/55 != 1, or 1*1 != 1?

I understand float can't store certain integer/finite decimal precisely, but why would a/a not be 1 if both numerator and denominator are the same (imprecise) number?




it's because the calculation (1/ 55) is less than the real number 1/55, so when you multiply it by 55 you get a result less than 1.

for an easier to follow example, say you can only work with two decimal places, hp was 1, old max hp was 3 and new max hp was also 3. if you do (3 * 1) / 3 you get 3 / 3 = 1 as intended. if instead you do 3 * (1 / 3) you get 3 * 0.33 = 0.99 which is less than 1


This effect becomes more pronounced, when substracting (but probably also adding) small amounts from big amounts, because more bits are needed to store the big number's more significant digits and floats then lose bits for the less significant digits. That is why, if one needs precision, needs to sort numbers first and then start calculating with the smallest numbers first, working ones way up to the bigger numbers.


Knuth has an entire chapter dedicated to floats, error ranges and such, which includes pretty much that (a+b)+c != a+(b+c) for floats, which in turn breaks tons of things on the math side already. That is such a large issue that it has some serious consequences in the real world, e.g. constructions failing, or I remember the Patriot missile system having problems from that side.


Thanks!

I misread the equation and thought it's `old_hp * (new_maxhp / old_maxhp)`.


It's neither. Diving 1 by 55 gives some number x where x is arbitrarily (there are standards for how to choose) chosen between the closest 2 representable floats to 1/55. Then, they multiply x by 55. If x is bigger than 1/55 here then the result is > 1. But, if it was rounded down then it will fail because x * 55 will be less than 1.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: