Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Math Problem

5 views
Skip to first unread message

McKirahan

unread,
Oct 5, 2005, 7:44:34 AM10/5/05
to
How do I add floating point numbers accurately?

The following adds the 4 numbers
46.57, 45.00, 45.00, and 54.83 to give
191.39999999999998 instead of 191.40.

<html>
<head>
<title>floats.htm</title>
</head>
<body>
<script type="text/javascript">
var a = [46.57,45.00,45.00,54.83];
var t = 0.00;
for (var i=0; i<a.length; i++) {
alert(t + "\n" + a[i])
t += a[i];
}
alert(t + " = 191.40 ?")
</script>
</body>
</html>

Thanks in advance.

P.S. This FAQ doesn't help:
http://jibbering.com/faq/#FAQ4
4.7 Why does 5 * 1.015 != 5.075 or 0.05+0.01 != 0.06?


Duncan Booth

unread,
Oct 5, 2005, 8:08:28 AM10/5/05
to
McKirahan wrote:

> How do I add floating point numbers accurately?

Using '+'.

A simpler demonstration of your problem:
alert(136.57+54.83);
shows 191.39999999999998


> P.S. This FAQ doesn't help:
> http://jibbering.com/faq/#FAQ4
> 4.7 Why does 5 * 1.015 != 5.075 or 0.05+0.01 != 0.06?
>
>

It should help. It says:

> Javascript numbers are represented in binary as IEEE-754 Doubles, with
> a resolution of 53 bits, giving an accuracy of 15-16 decimal digits;
> integers up to about 9e15 are precise, but few decimal fractions are.

in this case 136.57 is stored internally as 136.56999999999999,
54.83 is stored internally as 54.829999999999998.

Adding these together and reducing the result to the appropriate precision
gives the answer displayed above.

If you want to display a friendlier value as the result, change your final
alert to:
alert(t.toFixed(2) + " = 191.40 ?");

Tim Slattery

unread,
Oct 5, 2005, 8:59:07 AM10/5/05
to
"McKirahan" <Ne...@McKirahan.com> wrote:

>How do I add floating point numbers accurately?
>
>The following adds the 4 numbers
>46.57, 45.00, 45.00, and 54.83 to give
>191.39999999999998 instead of 191.40.

That's the way it is. Not all decimal fractions can be represented
exactly as binary fractions, which is how floating point numbers are
stored. Floating point numbers are necessarily somewhat imprecise. In
this case the imprecision is on the order of 10**-12, which is
extremely tiny.

--
Tim Slattery
Slatt...@bls.gov

Mick White

unread,
Oct 5, 2005, 9:56:42 AM10/5/05
to
McKirahan wrote:

> How do I add floating point numbers accurately?
>
> The following adds the 4 numbers
> 46.57, 45.00, 45.00, and 54.83 to give
> 191.39999999999998 instead of 191.40.
>

Some variation of the following:
/Math.round(Math.pow(10,x)*(46.57+45.00+45.00+54.83))/Math.pow(10,x);/

Where x equals number of digits required to the right of the decimal point.
Mick

Baconbutty

unread,
Oct 5, 2005, 11:53:08 AM10/5/05
to
If performance is not an issue you could write some arbitrary precision
mathematics.

I.e. you store a number as an array of digits, and perform long
division, long addition etc.

Randy Webb

unread,
Oct 5, 2005, 12:37:43 PM10/5/05
to
McKirahan said the following on 10/5/2005 7:44 AM:

> How do I add floating point numbers accurately?
>
> The following adds the 4 numbers
> 46.57, 45.00, 45.00, and 54.83 to give
> 191.39999999999998 instead of 191.40.

You convert them to whole numbers, do your math, and then use string
manipulation to put the decimal back where you want it along with
leading and/or trailing zeroes.

> P.S. This FAQ doesn't help:
> http://jibbering.com/faq/#FAQ4
> 4.7 Why does 5 * 1.015 != 5.075 or 0.05+0.01 != 0.06?

4.7 along with 4.6 do answer your question, they just aren't very well
worded and/or explained enough to make sense to anybody that doesn't
understand it to start with.

--
Randy
comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly

Stephen Chalmers

unread,
Oct 5, 2005, 12:58:51 PM10/5/05
to
McKirahan <Ne...@McKirahan.com> wrote in message news:GMCdncBlPbw...@comcast.com...

> How do I add floating point numbers accurately?
>
> The following adds the 4 numbers
> 46.57, 45.00, 45.00, and 54.83 to give
> 191.39999999999998 instead of 191.40.

If you happen to be handling money, it's preferable to avoid floating point calculations by working in pennies, then
formatting the result.

var pennies=12305

var dollars=Math.floor( pennies / 100 ), cents = pennies % 100;

result = dollars + '.' + ((cents < 10) ? ('0' + cents) : cents);

--
S.C.


Richard Cornford

unread,
Oct 5, 2005, 7:29:10 PM10/5/05
to
Tim Slattery wrote:

> McKirahan wrote:
>>How do I add floating point numbers accurately?
>>
>>The following adds the 4 numbers
>>46.57, 45.00, 45.00, and 54.83 to give
>>191.39999999999998 instead of 191.40.
>
> That's the way it is. Not all decimal fractions can be
> represented exactly as binary fractions, which is how
> floating point numbers are stored. Floating point numbers
> are necessarily somewhat imprecise. In this case the
> imprecision is on the order of 10**-12, which is extremely
> tiny.

And it isn't a characteristic restricted to binary representations of
numbers. How precise is the decimal fraction representation of 1/3? And
would it be reasonable to complain that 3.33 + 3.33 + 3.33 did not
result in 1?

Richard.


Randy Webb

unread,
Oct 5, 2005, 10:46:41 PM10/5/05
to
Richard Cornford said the following on 10/5/2005 7:29 PM:

Umm, yes it would since it should either result in 9.99 or 10, not 1 :)

0 new messages