Accuracy of JavaScript Computations

JavaScript FAQ | JavaScript Numbers FAQ  

Question: Sometimes JavaScript computations seem to yield "inaccurate" results, e.g. 0.362*100 yields 36.199999999999996. How can I avoid this?

Answer: Internally JavaScript stores all numbers in double-precision floating-point format, with a 52-bit mantissa and an 11-bit exponent (the IEEE 754 Standard for storing numeric values). This internal representation of numbers may cause unexpected results like the above. Most integers greater than 253 = 9007199254740992 cannot be represented exactly in this format. Likewise, many decimals/fractions, such as 0.362, cannot be represented exactly, leading to the perceived "inaccuracy" in the above example. To avoid these "inaccurate" results, you might want to round the results to the precision of the data you used.

Example: In order to round the result of the multiplication

0.362*100
to one thousandth, you can use the following code (
document.write
statements have been inserted after each line of code to show intermediate results):
rawX = 0.362*100                       // number close to 36.2
document.write(rawX)                   // 36.199999999999996

roundedX = Math.round(1000*rawX)/1000  // number even closer to 36.2
document.write(roundedX)               // 36.2

resultStr = roundedX.toFixed(3)        // string '36.200'
document.write(resultStr)              // 36.200
In the above example, it is obvious that JavaScript computation in the first line of code does not yield an exact result (when we output the result
rawX
, we do not get
36.2
, but rather
36.199999999999996
). Less obvious is the fact that even after we use the
Math.round
method and then divide by
1000
, the value
roundedX
is not necessarily an exact result, either. (Indeed, the decimal
36.2
is not exactly representable in the IEEE 754 format.) However, the result
roundedX = Math.round(1000*rawX)/1000
is more accurate than
rawX
in fact,
roundedX
is so close that calling
alert(roundedX)
produces
36.2
as expected. Similarly,
roundedX.toFixed(3)
produces
'36.200'
as expected.

In summary: You can use

Math.round
either alone or in combination with the

Number.toFixed(n)
method to get rid of the perceived "inaccuracy" and, if necessary, ensure exacly
n
decimal places in the result.

Copyright © 1996-2018, JavascriptFAQ.net.