6

The following script contains a very strange error. I want to check if a value is a positive integer. To do this, I multiply by 100 to enclose the value to decimal. If I test 0.07, the script does not calculated the value 7, but the value 7.00000001. I could round the value, but I would like to know why the value is calculated this way.

<script type="text/javascript">

  var isPositiveInt = function(i) {
        i = i*100;  
      return ((i % 1) == 0 && i >= 0);
  }; 

</script>

<a href="#" onclick="alert(isPositiveInt('0.07')); return false;">Try it out!</a>

0.05, 0.06 and 0.08 works fine. But what happens with 0.07? I would be happy if someone could explain that to me.

Tobias Bambullis
  • 736
  • 5
  • 17
  • 45
  • 1
    This is just the way floating point arithmetic works. For a detailed discussion into the reasons, see this: http://www.scribd.com/doc/5836/What-Every-Computer-Scientist-Should-Know-About-FloatingPoint-Arithmetic – James Allardice Jun 26 '11 at 19:40

2 Answers2

6

That's because javascript casts everything to a double internally. As a result, all calculations pick up some noise due to floating point inaccuracy: Floating point inaccuracy examples

One way to fix this issue, is to just round down to the nearest int after all intermediate calculations.

Community
  • 1
  • 1
Mikola
  • 9,176
  • 2
  • 34
  • 41
2

That's called numerical math. Computers do not operate on real numbers but on their approximation and this approximation brings rounding errors such as this one.

For 0.05, 0.06 and 0.08 you are lucky that these have an exact floating point representation on your PC. This is not the case of 0.07. Note that on a different PC/browser the result might be different.

For more info see the IEEE floating point format specification.

Karel Petranek
  • 15,005
  • 4
  • 44
  • 68
  • 1
    The result can only be different where the browser does not conform to ECMA-262 which specifies *double-precision 64-bit binary format IEEE 754 values* (ECMA-262 §4.3.19). – RobG Jun 27 '11 at 01:51