0

This is probably a question with an really logical answer.. But I really don't understand this!!

Why, does this give different results..

Only difference is a for loop and a while loop.. Even while they loop exactly as many times???

array = [1.2344, 2.47373, 3.444];

    var total = 0,
        total2 = 0,
        i = array.length,
        whileLoops = 0,
        forLoops = 0;

    while (i--) {
        whileLoops++;
        total += array[i];
    }

    for (var i = 0, len = array.length; i < len; i++) {
        forLoops++;
        total2 += array[i];
    }

    if (total !== total2) {
        console.log("BOE")
    }

I tried parseFloat, but this also wasn't helping :(

It it because the Javascript engine rounds numbers in a sort of way???

On request: the fiddle http://jsfiddle.net/5dsx0ump/

UPDATE

Would the solution be to first to a * 1000 and after all the calculations, divide again by 1000, to keep round numbers?

DutchKevv
  • 1,659
  • 2
  • 22
  • 39

2 Answers2

0

Floating-point math (in JavaScript or any other language) has some quirks that you wouldn't expect. Putting this at the end of your code:

console.log(total, total2);

Returns the following:

7.1521300000000005 7.15213

Heck, just put 0.1 + 0.2 in a browser console and see what you get. Not what you'd expect.

Instead of re-hashing the entire explanation, there's a really good write-up and discussion here: Is floating point math broken?

Community
  • 1
  • 1
Scott
  • 2,753
  • 1
  • 24
  • 31
  • 2
    No, Javascript floating point math is not odd. It's exactly the same as in any other language that uses floating point numbers. – Guffa Jan 20 '15 at 23:18
  • Take a look at this: http://yuiblog.com/blog/2009/03/10/when-you-cant-count-on-your-numbers/ – imnancysun Jan 20 '15 at 23:18
0

The difference in the loops is the order that you add the numbers.

For each of those additions there is a tiny loss of data, as the result has to fit in the same data type as both the operands. What's lost depends on what the numbers are, so adding the numbers in different order causes a small difference in the result in the end.

If you print out the numbers, they may or may not look the same, but looking the same when printed doesn't mean that they must have the same value. The numbers have a precision of 15-17 digits, but that is rounded to slightly less when printed, just to avoid seeing the limitation in precision.

This is normal behaviour for floating point numbers, and you would see the same result in any programming language using floating point numbers. Floating point numbers are simply not exact, so in application where numbers actually have to be exact (e.g. banking), other data types are used.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Thanks, but still.. I find it rather strange that a simple calculation as adding numbers op to each other, is giving a different result... If I would divide a number that holds 10000 floating points, by a number thats holds another 10000 floating points, I can understand it has to 'fit' all the points... Is it even 'normal' with just a few numbers behind the comma?? – DutchKevv Jan 20 '15 at 23:22
  • @DutchKev: Yes, it's normal with almost all numbers that have digits behind the comma. Some numbers can be represented exactly, like for example `0.5` and `0.25`, but they are relatively few. If you look at what the numbers in the array would be in their floating point representation, it's likely that neither of them can be represented exactly. You get the closest possible representation for each of them, so you have a small difference already from the start. – Guffa Jan 20 '15 at 23:33
  • For example, which data types are used for banking concerns? – 1252748 Jan 21 '15 at 01:01
  • @thomas: For that you would use a `Decimal` or `Money` data type, which is a fixed point number. Basically it's a large integer, where certain number of digits are used for the fractional part. – Guffa Jan 21 '15 at 16:51