floating point numbers don't add right

J

janice

Hi all,

I read a lot of info on this issue, but still don't get it. Why does
this happen?

document.write(".05" + " \+ " + ".05" + " \= " + (.05 + .05) +
"<br>");
document.write("1.05" + " \+ " + ".05" + " \= " + (1.05 + .05) +
"<br>");
document.write("2.05" + " \+ " + ".05" + " \= " + (2.05 + .05) +
"<br>");

Outputs:

..05 + .05 = 0.1
1.05 + .05 = 1.1
2.05 + .05 = 2.0999999999999996


I also tried the code provided in this group's FAQ, and it worked
except for when it reaches an "even" number which should display 6.00
for example, it displays 5.100.

thx!

J.
 
P

Philip Ronan

Hi all,

I read a lot of info on this issue, but still don't get it. Why does
this happen?
(snip)
2.05 + .05 = 2.0999999999999996

In binary, these numbers go on for ever:

2.05 = 10.0000110011001100110011001100...
0.05 = 0.0000110011001100110011001100...
2.10 = 10.0001100110011001100110011001...

With a fixed number of bits it is impossible to represent these numbers
exactly, so they contain errors right from the start. Addition makes the
errors even larger. For example, if I added together the first two binary
numbers shown above, the last digit of the result would be 0, not 1.

It's just like adding 1/3 to 2/3 in base 10:

2/3 = 0.666666666666666
+ 1/3 = 0.333333333333333
= 0.999999999999999 (not 1.000000)

It is just as impossible to write 1/3 in decimal as it is to write 0.05 in
binary.

I hope that makes sense.
 
D

Douglas Crockford

I read a lot of info on this issue, but still don't get it. Why does
this happen?
.05 + .05 = 0.1
1.05 + .05 = 1.1
2.05 + .05 = 2.0999999999999996

That's really annoying, isn't it? JavaScript uses binary floating point
notation internally to represent numbers. Floating point is very useful
for some scientific applications, but for other applications it has some
severe shortcomings.

In case, you are seeing that it cannot exactly represent decimal
fractions. That would be ok on a planet where people do not commonly use
decimal fractions. It might seem that floating point was a poor choice.

http://www.crockford.com/#javascript
 
L

Lee

Douglas Crockford said:
That's really annoying, isn't it? JavaScript uses binary floating point
notation internally to represent numbers. Floating point is very useful
for some scientific applications, but for other applications it has some
severe shortcomings.

In case, you are seeing that it cannot exactly represent decimal
fractions. That would be ok on a planet where people do not commonly use
decimal fractions. It might seem that floating point was a poor choice.


The advantages of using standard IEEE floating point representation
far outweigh any disadvantage. The infinitesimal error encountered
in typical web-page arithmetic is easily corrected by rounding.

When representing numbers in binary, each bit represents either
0 or 1 times 2 raised to some positive or negative integer power,
so a binary representation of a value between 0 and 1 is the sum
of the series (b1)/2 + (b2)/4 + (b3)/16 + (b4)/32 + ...
where each (bn) value is either 0 or 1. It's mathematically
impossible to represent some decimal fractions as a finite
series of such terms.
 
D

Douglas Crockford

Lee said:
Douglas Crockford said:


The advantages of using standard IEEE floating point representation
far outweigh any disadvantage. The infinitesimal error encountered
in typical web-page arithmetic is easily corrected by rounding.

When representing numbers in binary, each bit represents either
0 or 1 times 2 raised to some positive or negative integer power,
so a binary representation of a value between 0 and 1 is the sum
of the series (b1)/2 + (b2)/4 + (b3)/16 + (b4)/32 + ...
where each (bn) value is either 0 or 1. It's mathematically
impossible to represent some decimal fractions as a finite
series of such terms.

That is precisely why floating point is poorly suited to most
applications. For applications that require decimal precision (such as
those involving money), there are other representations that are much
better. Scaled integers and BCD, for example.

2.0999999999999996 shows 3.0 to 16 decimal places, nearly all of them
wrong. This result, to most people, is surprising.
 
L

Lee

Douglas Crockford said:
That is precisely why floating point is poorly suited to most
applications. For applications that require decimal precision (such as
those involving money), there are other representations that are much
better. Scaled integers and BCD, for example.

2.0999999999999996 shows 3.0 to 16 decimal places, nearly all of them
wrong. This result, to most people, is surprising.


When handling money, all you need to do is round to thousandths
and display to hundredths. It's pretty trivial.

The fact that it's surprising to neophytes isn't much of
a reason to change it.
 
D

Dr John Stockton

JRS: In article <[email protected]>,
dated Thu, 23 Sep 2004 13:14:59, seen in
janice said:
I also tried the code provided in this group's FAQ,

The FAQ says : Operations on integers are exact if the true result and
all intermediates are integers within that range.

If you want results exact to the cent, then work in cents, not in euros.

Integers are exact up to as little over 9,000,000,000,000,000; enough
for most budgets.
 
L

Lasse Reichstein Nielsen

Lee said:
When handling money, all you need to do is round to thousandths
and display to hundredths. It's pretty trivial.

No code is so trivial that it can't contain an error (except perhaps
the empty statement :).
The fact that it's surprising to neophytes isn't much of
a reason to change it.

It's perhaps too late to change it, although I don't think a change to
BCD-numbers like C#'s "decimal" type would be noticed by most
applications.

However, as a purely theoretical observation, I'd say that for a
script language that is used by so many (until recently)
non-programmers, it would probably be better to use a decimal number
format to avoid exactly these questions. It happens often enough
to be in the FAQ.

/L
 
D

Dr John Stockton

JRS: In article <[email protected]>, dated Fri, 24 Sep 2004
19:20:58, seen in Lasse Reichstein Nielsen
However, as a purely theoretical observation, I'd say that for a
script language that is used by so many (until recently)
non-programmers, it would probably be better to use a decimal number
format to avoid exactly these questions. It happens often enough
to be in the FAQ.

The same applies in Delphi groups of except that they
have no newsgroup FAQs.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top