Why are some scientific numbers automatically rounded and others aren't?

javascript, numbers

Solution

It's because floating point numbers are sometimes an approximation. Some numbers can't be represented by the floating point format, that is, a binary fraction, so they are approximated http://en.wikipedia.org/wiki/IEEE_754-2008

That is why you should never rely on floating point arithmetic without rounding it. A simple example is the following:

> 20.61 - .1
  20.509999999999998

Here's a great explanation of the floating point format http://www.randelshofer.ch/fhw/gri/float.html#chapterfloatingpointformat

Ordinary Decimal 178.125

Scientific Decimal 1.78125 E 102

Scientific Binary 1.0110010001 E 2111

Problem

Why is it that some numbers in scientific notation starting with 9.999999999999999 get rounded to 1 while others remain the same? For example, in Google Chrome 20 the following happens. `(9.999999999999999e+306).toString() === "9.999999999999999e+306" // true` but `(9.999999999999999e+303).toString() === "1e+304" // true` Why is that? Is it a floating point issue? However the strangest thing is that in Opera 11.64 `(1e23).toString() === "9.999999999999999e+22"`. I tried to report the 1e23 bug to Opera but no one replied. Live Demo Here: http://jsfiddle.net/3ekDK/3/ Source code of Demo ``` var console = console || {}; console.logToBody = function( str ){ document.body.innerHTML += "" + str + "<br/>"; }; var parts = ["9.999999999999999e", 310 ], tmp, tmp2; while( parts[1]-- ){ tmp = +(parts.join('')); if( /9.9{3,}e/.test( +tmp ) ){ console.logToBody( tmp + " doesn't convert to " + (+tmp).toPrecision(1) ); } tmp2 = "1e"+parts[1]; //Carakan Javascript Engine Math BUG: if( !/^1e*/.test( +tmp2 ) ){ console.logToBody( tmp2 + " = " + (+tmp2) + " in the runtime environment."); } } ```

Original source