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 rawXin 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 © 1999-2012,