Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript multiply not precise

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?

like image 658
adis Avatar asked Apr 03 '12 12:04

adis


People also ask

Why does JavaScript have rounding errors?

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.

How do you multiply values in JavaScript?

The multiplication operator ( * ) multiplies numbers.

Does JavaScript use floating point?

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.


2 Answers

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;
}
like image 120
George Mavritsakis Avatar answered Oct 16 '22 08:10

George Mavritsakis


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
like image 45
Gajus Avatar answered Oct 16 '22 08:10

Gajus