I came accross a weird problem, I want to do some basic math checks. I have read to avoid floating numbers so I decided to multiply my math values with 10000, because my value can be between 0.9 and 0.0025.
Everything works correct except for two values: 0.56 and 0.57:
var result = 0.57 * 10000
The outcome is: 5699.999999999999, I hoped for 5700!! And 0.56 is also going wrong but all the other values are correct, what am I missing here?
This post doesn't get into the details of floating-point arithmetic, but the short of it is most programming languages use a binary floating-point representation which can only approximate many decimal fractions. This results in rounding errors for the most common approaches to rounding in JavaScript.
The multiplication operator ( * ) multiplies numbers.
JavaScript Numbers are Always 64-bit Floating Point JavaScript numbers are always stored as double precision floating point numbers, following the international IEEE 754 standard.
The best solution would be to use toFixed(x), and set x a number of decimals that should always be more than the expected results decimals (I usually put 8 there).
But instead of hacking -as kirilloid-, you should convert the result back to number again, so that any unneeded decimals are removed. After that perform any formatting you like on the number.
So this would return the needed result:
var result = +(0.57 * 10000).toFixed(8)
result would be now 5700
The + in front, converts the string result of "toFixed" to a number again.
Hope that helped!
EDIT 2019:
It seems that we should not trust toFixed for this according to this:http://stackoverflow.com/questions/661562/how-to-format-a-float-in-javascript/661757#661757 Better to use something like the following:
function fixRounding(value, precision) {
var power = Math.pow(10, precision || 0);
return Math.round(value * power) / power;
}
var multiply = function(a, b) {
var commonMultiplier = 1000000;
a *= commonMultiplier;
b *= commonMultiplier;
return (a * b) / (commonMultiplier * commonMultiplier);
};
This works in a known range. Therefore, it might be a good idea to round the number to a decimal point smaller than commonMultiplier
.
> multiply(3, .1)
< 0.3
> multiply(5, .03)
< 0.15
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With