Incorrect math

C

Christoph

alert( 100 * 1.15 );

The above *should* show a value of 115. However, what I
am actually getting is:

114.99999999999998

alert( 100 * 1.10 );

is showing as:

110.00000000000001

Why?

thnx,
Christoph
 
D

Douglas Crockford

alert( 100 * 1.15 );
The above *should* show a value of 115. However, what I
am actually getting is:

114.99999999999998

alert( 100 * 1.10 );

is showing as:

110.00000000000001

Why?

JavaScript numbers are 64-bit floating point as specified in IEEE 754. It is the
same representation that Java calls Double.

The scheme is intended to preserve as much precision as possible, but it has
some significant weaknesses. For example, it is not able to exactly represent
common fractions such as 1/10 or 1/100. It can at best approximate them. As you
can see, with a single operation you begin accumulating noticeable error. Also,
be aware that the associative law and distributive law no longer apply.

I think floating point is the wrong representation for numbers in most
applications. However, it is extremely popular, and popularity is much more
important these days than suitability or reliability. I recommend that in
applications that require exactness (for example, when working with money) scale
your values by a suitable factor (such as 100) so that all of your arithmetic
will be on whole numbers, which are exact.

See http://www.dcs.ed.ac.uk/home/mhe/plume/node9.html
 
M

Michael Winter

on 11/11/2003:
alert( 100 * 1.15 );

The above *should* show a value of 115. However, what I
am actually getting is:

114.99999999999998

alert( 100 * 1.10 );

is showing as:

110.00000000000001

Why?

Floating-point values are traditionally represented in a structure
with three parts: a mantissa, an exponent, and the sign. Each field
has a fixed size. Immediately, that suggests limits. Furthermore,
there are certain types of numbers that are difficult to represent
accurately. Basically, there are flaws, and there are plenty of
places to read about them on the Internet. This might not be quite so
true of JavaScript as it is with, say the FPU on a PC, but it's at
least a possible explanation.

Because of this, it's usually not a good idea to do direct
comparisons, and use ranges instead. Alternatively, round floating
point values at certain points in the computation or before
comparisons.

Mike
 
F

Fabian

Christoph hu kiteb:
alert( 100 * 1.15 );

The above *should* show a value of 115. However, what I
am actually getting is:

114.99999999999998

alert( 100 * 1.10 );

is showing as:

110.00000000000001

Why?

Others have said why. The solutions are:

Use whole numbers wherever possible

Use Math.round() or Math.floor() immediately after any calculation
involving fractions.
 
J

Jerry Park

Christoph said:
alert( 100 * 1.15 );

The above *should* show a value of 115. However, what I
am actually getting is:

114.99999999999998

alert( 100 * 1.10 );

is showing as:

110.00000000000001

Why?

thnx,
Christoph
As subsequent posts noted, fractional arithmetic is problematic in
floating point. Numbers which are finite in one base may be 'repeating'
decimals in another. For the same reason you can't represent 1/3 exactly
in base 10 as a fraction, other numbers which are exact in base 10 may
be repeating in base 2.

Either scaling the numbers in order to use only integer values or
rounding the result will help.

For example, in your example, the most precise value you have is
represented to two decimal places. If you round the answer to two
decimal places, you get the 'correct' answer.
 
D

Dr John Stockton

JRS: In article <[email protected]>, seen in
news:comp.lang.javascript said:
alert( 100 * 1.15 );

The above *should* show a value of 115. However, what I
am actually getting is:

114.99999999999998
...

One should always seek to read a newsgroup's FAQ before posting; it
saves everybody a lot of trouble, the putative poster included. This is
item 4.7 in ours.

But read the whole FAQ, to avoid future problems; it points out,
moreover, that comp.lang.java groups should not be used for javascript.
In fact, AIUI, c.l.j.j has no legitimate existence. FU set.

When questions in the FAQ are asked, the FAQ should be cited in answers
even if it is felt that more explanation should be given in the case in
question.
 

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

No members online now.

Forum statistics

Threads
474,430
Messages
2,571,676
Members
48,796
Latest member
Greg L.

Latest Threads

Top