2

Possible Duplicates:
Strange problem comparing floats in objective-C
Is JavaScript’s math broken?
1.265 * 10000 = 126499.99999999999 ?????

After watching this I discovered that in JavaScript:

0.1 + 0.2 === 0.3

evaluates to false.

Is there a way to work around this?

Community
  • 1
  • 1
camomileCase
  • 1,706
  • 2
  • 18
  • 27

7 Answers7

5

The best and only answer I have found that provides accurate results is to use a Decimal library. The BigDecimal java class has been ported to javascript, see my answer in this SO post.

Note: Scaling values will "treat" the issue but will not "cure" it.

Community
  • 1
  • 1
Matt Baker
  • 3,694
  • 1
  • 20
  • 16
2

How about

function isEqual(a, b)
{
  var epsilon = 0.01; // tunable 
  return Math.abs(a - b) < epsilon;
}
alex
  • 479,566
  • 201
  • 878
  • 984
Ewan Todd
  • 7,315
  • 26
  • 33
  • @alex: I don't understand why you changed the cutoff from `0.01` to `0.0`. This function will now always return `false`, even when the two values are *completely* identical. No? – ruakh Feb 08 '13 at 06:34
  • @ruakh Me either, it may have been in mistake. I'll fix it :) – alex Feb 08 '13 at 06:40
2

This is a problem inherent in binary numbers that hits all major programming languages.

Convert decimal .1 (1/10) to binary by hand - you'll find it has a repeating mantissa and can't be represented exactly. Like trying to represent 1/3 as a decimal.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • The problem is with binary floating point, not binary numbers in general. There are decimal floating point libraries out there (though not sure about in JS) that avoid this problem. – ScottJ Nov 04 '09 at 19:21
  • 1
    No, it's a problem with binary numbers. You can't represent .1 as a natural binary number. "decimal" libraries get around it by representing decimal digits or by using fixed-point decimals. – Joel Coehoorn Nov 04 '09 at 19:39
  • OK, true. What I should have said is that this problem does not affect binary integers. – ScottJ Nov 05 '09 at 20:05
  • +1 for only answer that explains the root of the problem. (Although it technically can be represented exactly, just with infinitely many bits :)) – Benjamin Gruenbaum Mar 02 '13 at 21:23
1

You should always compare floating point numbers by using a constant (normally called epsilon) to determine much can two numbers differ to be considered "equal".

Lukáš Lalinský
  • 40,587
  • 6
  • 104
  • 126
1

Use fixed-point math (read: integers) to do math where you care about that kind of precision. Otherwise write a function that compares your numbers within a range that you can accept as being "close enough" to equal.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
1

Just an idea. Multiply 10000 (or some similarly big number as long as its more than your max number of decimals) to all your values before you compare them, that why they will be integers.

function padFloat( val ) {
  return val * 10000;
}

padFloat( 0.1 ) + padFloat( 0.2 ) === padFloat( 0.3 );
Pete Duncanson
  • 3,208
  • 2
  • 25
  • 35
1

You can of course multiply each number like

10 * 0.1 + 10 * 0.2 === 10 * 0.3

which evaluates to true.

Kimmo Puputti
  • 260
  • 2
  • 7