473,385 Members | 1,655 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

39 - 32.2 = 7.799999999999 - why?

In the current application I'm working on I'm using floating point variables
to store price information in a shopping cart.

When I go to do % based discounts I make sure to round and truncate my
numbers to 2 decimal points of precision.

But when I go to do more arithmetic on the numbers I'm getting this strange
anomaly where it just comes out wrong. Watching the values in the debugger
show that the values are in fact 39 and 32.2 but when I subtract 32.2 from
39 I get 7.7999999999.

What should I be doing to avoid this?
Nov 15 '05 #1
25 1964
Joel Barsotti <jo**********@hotmail.com> wrote:
In the current application I'm working on I'm using floating point variables
to store price information in a shopping cart.

When I go to do % based discounts I make sure to round and truncate my
numbers to 2 decimal points of precision.

But when I go to do more arithmetic on the numbers I'm getting this strange
anomaly where it just comes out wrong. Watching the values in the debugger
show that the values are in fact 39 and 32.2 but when I subtract 32.2 from
39 I get 7.7999999999.

What should I be doing to avoid this?


Using the decimal type, basically.

See http://www.pobox.com/~skeet/csharp/floatingpoint.html for why this
is happening.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #2
yep.

In decimal notation, the fraction 1/3 cannot be represented accurately... =
0.33333..

In binary, believe it or not, the fraction 1/10 cannot be represented
accurately. It's the nature of the numbering system.

The decimal data type takes care of this for you.

Hope this helps,
---- Nick
"Joel Barsotti" <jo**********@hotmail.com> wrote in message
news:u3**************@TK2MSFTNGP10.phx.gbl...
In the current application I'm working on I'm using floating point variables to store price information in a shopping cart.

When I go to do % based discounts I make sure to round and truncate my
numbers to 2 decimal points of precision.

But when I go to do more arithmetic on the numbers I'm getting this strange anomaly where it just comes out wrong. Watching the values in the debugger show that the values are in fact 39 and 32.2 but when I subtract 32.2 from
39 I get 7.7999999999.

What should I be doing to avoid this?

Nov 15 '05 #3
Mathematically is correct, bacause 7.799999999999 is the same as 7,8

1/3=0.33333333333333
+
2/3=0.66666666666666
-------------------------
3/3=0.99999999999999

"Joel Barsotti" <jo**********@hotmail.com> schrieb im Newsbeitrag
news:u3**************@TK2MSFTNGP10.phx.gbl...
In the current application I'm working on I'm using floating point variables to store price information in a shopping cart.

When I go to do % based discounts I make sure to round and truncate my
numbers to 2 decimal points of precision.

But when I go to do more arithmetic on the numbers I'm getting this strange anomaly where it just comes out wrong. Watching the values in the debugger show that the values are in fact 39 and 32.2 but when I subtract 32.2 from
39 I get 7.7999999999.

What should I be doing to avoid this?

Nov 15 '05 #4
7.8 is not the same as 7.799999999999 , its rounded.
"Zürcher See" <aq****@cannabismail.com> wrote in message
news:Oh**************@TK2MSFTNGP12.phx.gbl...
Mathematically is correct, bacause 7.799999999999 is the same as 7,8

1/3=0.33333333333333
+
2/3=0.66666666666666
-------------------------
3/3=0.99999999999999

"Joel Barsotti" <jo**********@hotmail.com> schrieb im Newsbeitrag
news:u3**************@TK2MSFTNGP10.phx.gbl...
In the current application I'm working on I'm using floating point

variables
to store price information in a shopping cart.

When I go to do % based discounts I make sure to round and truncate my
numbers to 2 decimal points of precision.

But when I go to do more arithmetic on the numbers I'm getting this

strange
anomaly where it just comes out wrong. Watching the values in the

debugger
show that the values are in fact 39 and 32.2 but when I subtract 32.2 from 39 I get 7.7999999999.

What should I be doing to avoid this?


Nov 15 '05 #5
If were periodic in 9, they would be the same number, but computers cannot
express periodicity.

<di********@discussion.microsoft.com> schrieb im Newsbeitrag
news:e3*************@TK2MSFTNGP12.phx.gbl...
7.8 is not the same as 7.799999999999 , its rounded.
"Zürcher See" <aq****@cannabismail.com> wrote in message
news:Oh**************@TK2MSFTNGP12.phx.gbl...
Mathematically is correct, bacause 7.799999999999 is the same as 7,8

1/3=0.33333333333333
+
2/3=0.66666666666666
-------------------------
3/3=0.99999999999999

"Joel Barsotti" <jo**********@hotmail.com> schrieb im Newsbeitrag
news:u3**************@TK2MSFTNGP10.phx.gbl...
In the current application I'm working on I'm using floating point

variables
to store price information in a shopping cart.

When I go to do % based discounts I make sure to round and truncate my
numbers to 2 decimal points of precision.

But when I go to do more arithmetic on the numbers I'm getting this

strange
anomaly where it just comes out wrong. Watching the values in the

debugger
show that the values are in fact 39 and 32.2 but when I subtract 32.2 from 39 I get 7.7999999999.

What should I be doing to avoid this?



Nov 15 '05 #6
Zürcher See <aq****@cannabismail.com> wrote:
If were periodic in 9, they would be the same number, but computers cannot
express periodicity.


No, even then they wouldn't be the same number. 7.79999 (recurring) is
irrational, 7.8 isn't.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #7
"Joel Barsotti" <jo**********@hotmail.com> wrote in message news:<u3**************@TK2MSFTNGP10.phx.gbl>...
But when I go to do more arithmetic on the numbers I'm getting this strange
anomaly where it just comes out wrong. Watching the values in the debugger
show that the values are in fact 39 and 32.2 but when I subtract 32.2 from
39 I get 7.7999999999.

What should I be doing to avoid this?


You are a victim of internal binary representation of decimal numbers.
This is a problem with all computers that use binary represenation of
floating point data. Simply, some decimal finite numbers, cannot be
converted to finite binary representation. Therefore computer cuts the
translation at the predetermined binary length creating binary
floating point that is very close but not exactly the decimal number
that you started with. It is exactly the same type of problem when you
for example divide decimal 1 by decimal 3. In decimal notation 1/3
cannot be represented by finite string. In other words 1/3 =
0.333333... (infinite). Therefore, even of you would use decimal type
data you still can encounter this problem once you introduce division
into your calculations. Most of the handheld calculators are using
decimal (BCD) internal representation and they still suffer from the
simple problem that when you take 1, divide it by 3 and then multiply
by 3 you will get 0.999999.... but not 1.0 as you would otherwise
expect.

There are several solutions to your particular problem. The first one
is to "ignore" the problem and use binary. Even when binary is not
exact it is in most cases good enough to hold practical precision for
your needs, that even after thousands of calculations the error is
still within acceptable range. All you have to do then to avoid
cofusing display is to display the outcome using round-off and
formatting to display only what you want from your calculations. For
example, if you use financial calculations, you probably want only two
decimal places after period to represent cents. Nobody needs fractions
of the cent. In such case 7.7999999... will be displayed as 7.80 and
you should be OK as long as 7.79999.. is not used later millions of
times in a loop which could magnify error to the unacceptable level.
In most cases this is not the case and you can live with binary OK. In
rare cases, when it is not OK you could use decimal type data or
integer type data. This solution is perfect for monetary as long as
you don't use division. The integer or decimal representation is
translated perfectly from decimal input and preserves perfect value
for multiplication, subtraction and addition as long as you don't
overflow the data capacity. The same trouble with limited
representation however is exposed when you introduce division. I
already mentiond 1/3 as a problem for decimal (or integer for that
matter) representation. If you program uses division then your
calculations suffer again from close but not exact representation
syndrome. Again the solution here is to ignore small error and take
care of it during display using round-off and formatting. But ignoring
this carries the same risk, that if you use intermediate calculations
furhter in a long loops then the intial small error can get magnified
to even nonsensical values.

For example if you take a fraction of 1/3, multiply it by 10 and
subtract 3, you should get back exactly the same 1/3. So in theory
when you start with 1/3, you could multiply it by 10 and then subtract
3 thousands of times in a loop. Try it on you calculator using
numerical accuracy (don't use modern algebraic fractional
representation that is available in some advanced models) and you will
find out nonsense only after ten or so loops. So even decimal internal
representation is no good, when you start with number like 1/3
represented imperfectly in decimal as 0.33333... internally.

If you still insisit on perfection here, you could use fractional
representation. Such data type however is not built in to the C#
natively and you would have to write your own classes. In such
representation all numbers are represented as fractions of two integer
numbers a/b. For eample 3 is represented as (3,1) pair of integers,
1/3 is represented as (1,3) pair of integers and so on. In such
represenrtaion all four basic math operators are preserved perfectly
(addition, subtraction, multiplication and division) as long as you
don't overflow the data capacity. Such approach is used by the
Microsoft Windows calculator.

Of course, once you ask for functions such as square root or
trigonometric the ugly problem is back no matter what above
representation you use :-)

JM
Nov 15 '05 #8
Sorry, but that's mathematics. And 7.799999 ist not irrational, because it
can be rappresent as a fraction

7.7999999=(7.7999999*9)/9=(7.7999999*10-7.799999)/9=(77.999999-7.7999999)/9=
70.2/9=702/90=351/45=117/15=39/5=7.8

7.7999999=7.8

qed

"Jon Skeet [C# MVP]" <sk***@pobox.com> schrieb im Newsbeitrag
news:MP************************@msnews.microsoft.c om...
Zürcher See <aq****@cannabismail.com> wrote:
If were periodic in 9, they would be the same number, but computers cannot
express periodicity.


No, even then they wouldn't be the same number. 7.79999 (recurring) is
irrational, 7.8 isn't.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #9
Zürcher See <aq****@cannabismail.com> wrote:
Sorry, but that's mathematics.
Indeed - but as soon as you start talking about "if it were periodic in
9" then I assume you're talking about mathematics.

What *exactly* did you mean by "If were periodic in 9"?
And 7.799999 ist not irrational, because it
can be rappresent as a fraction

7.7999999=(7.7999999*9)/9=(7.7999999*10-7.799999)/9=(77.999999-7.7999999)/9=
70.2/9=702/90=351/45=117/15=39/5=7.8

7.7999999=7.8

qed


No - because 77.999999-7.7999999 = 70.1999991, not 70.2 - unless you
meant that the 9 was recurring, in which case, see my argument above.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #10
Unless of course you meant that you are getting 6.7999999999. If the 7.79...
wasn't a typo then you've got bigger problems...

Colin

"Joel Barsotti" <jo**********@hotmail.com> wrote in message
news:u3**************@TK2MSFTNGP10.phx.gbl...
In the current application I'm working on I'm using floating point variables to store price information in a shopping cart.

When I go to do % based discounts I make sure to round and truncate my
numbers to 2 decimal points of precision.

But when I go to do more arithmetic on the numbers I'm getting this strange anomaly where it just comes out wrong. Watching the values in the debugger show that the values are in fact 39 and 32.2 but when I subtract 32.2 from
39 I get 7.7999999999.

What should I be doing to avoid this?

Nov 15 '05 #11
ROFL!

"Colin Young" <x@nospam.com> wrote in message
news:%2***************@TK2MSFTNGP11.phx.gbl...
Unless of course you meant that you are getting 6.7999999999. If the 7.79... wasn't a typo then you've got bigger problems...

Colin

Nov 15 '05 #12
Sorry for the wrong translation, recurring, if recurring is the right term
to describe a number that has after the point has a repeated sequence of
numbers.

In that case all the recurring numbers aren't irrational, because you can
always find a fraction in order to represent them

Irrational number are pi (3.14159...), euler's number (2.7181..), the golden
section number (1,61803...), ...
"Jon Skeet [C# MVP]" <sk***@pobox.com> schrieb im Newsbeitrag
news:MP***********************@msnews.microsoft.co m...
Zürcher See <aq****@cannabismail.com> wrote:
Sorry, but that's mathematics.
Indeed - but as soon as you start talking about "if it were periodic in
9" then I assume you're talking about mathematics.

What *exactly* did you mean by "If were periodic in 9"?
And 7.799999 ist not irrational, because it
can be rappresent as a fraction

7.7999999=(7.7999999*9)/9=(7.7999999*10-7.799999)/9=(77.999999-7.7999999)/9= 70.2/9=702/90=351/45=117/15=39/5=7.8

7.7999999=7.8

qed


No - because 77.999999-7.7999999 = 70.1999991, not 70.2 - unless you
meant that the 9 was recurring, in which case, see my argument above.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #13
Zürcher See <aq****@cannabismail.com> wrote:
Sorry for the wrong translation, recurring, if recurring is the right term
to describe a number that has after the point has a repeated sequence of
numbers.
Yes.
In that case all the recurring numbers aren't irrational, because you can
always find a fraction in order to represent them

Irrational number are pi (3.14159...), euler's number (2.7181..), the golden
section number (1,61803...), ...


There are certainly *some* recurring numbers which are rational (and I
don't know why I thought otherwise earlier) but I don't believe that
*all* recurring numbers are rational. I could well be wrong, of course,
but I don't "buy" your argument that 7.79 recurring *is* 7.8. For one
thing, 7.8 is clearly *not* recurring, and 7.79 *is* recurring -
they're different things.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #14
"Jon Skeet [C# MVP]" wrote:

Zürcher See <aq****@cannabismail.com> wrote:
Sorry for the wrong translation, recurring, if recurring is the right term
to describe a number that has after the point has a repeated sequence of
numbers.


Yes.
In that case all the recurring numbers aren't irrational, because you can
always find a fraction in order to represent them

Irrational number are pi (3.14159...), euler's number (2.7181..), the golden
section number (1,61803...), ...


There are certainly *some* recurring numbers which are rational (and I
don't know why I thought otherwise earlier) but I don't believe that
*all* recurring numbers are rational. I could well be wrong, of course,
but I don't "buy" your argument that 7.79 recurring *is* 7.8. For one
thing, 7.8 is clearly *not* recurring, and 7.79 *is* recurring -
they're different things.


Perhaps you are thinking of numbers like:

1.01001000100001000001 ...

These can be irrational and have a recurring pattern but are not a simple
repeating series of digits.

It can be shown that 7.8 == 7.7(9) using limits. Consider the difference

delta = 7.8 - 7.7(9)

Then delta is the limit of the series

7.8 - 7.79
7.8 - 7.799
7.8 - 7.7999
...

as the number of 9's goes to infinity. However, this limit for delta
is zero.

Bruce Seiler
Nov 15 '05 #15
Bruce Seiler <bs*****@cadence.com> wrote:
These can be irrational and have a recurring pattern but are not a simple
repeating series of digits.

It can be shown that 7.8 == 7.7(9) using limits.


It isn't *equal* to it - it just *tends* towards it. The difference
between 7.8 and 7.7(9) isn't 0, it just tends towards 0. The difference
is infinitessimal, but non-zero. (In particular, it's positive, whereas
7.7(9)-7.8 is negative.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #16
Given an recuring number with the a pattern xxx.yyy(zzz) where (zzz) is a
n-number recurring
It's always possible to calculate the following things:

(xxx.yyy(zzz)*10En-xxx.yyy(zzz))/(10En-1)

These are not limits, this is simple mathematics

And a very simple demontration that 0.(9)=1:

1/3=0.(3)
2/3=0.(6)

1/3+2/3=3/3=1

0.(3)+0.(6)=0.(9)

1=0.(9)

This is not limits, 0.(9) tends not towards 1, 0.(9) is 1

"Jon Skeet [C# MVP]" <sk***@pobox.com> schrieb im Newsbeitrag
news:MP************************@msnews.microsoft.c om...
Bruce Seiler <bs*****@cadence.com> wrote:
These can be irrational and have a recurring pattern but are not a simple repeating series of digits.

It can be shown that 7.8 == 7.7(9) using limits.


It isn't *equal* to it - it just *tends* towards it. The difference
between 7.8 and 7.7(9) isn't 0, it just tends towards 0. The difference
is infinitessimal, but non-zero. (In particular, it's positive, whereas
7.7(9)-7.8 is negative.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #17
Zürcher See <aq****@cannabismail.com> wrote:

<snip proof>
This is not limits, 0.(9) tends not towards 1, 0.(9) is 1


I'm convinced (after talking to another friend about it too :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #18
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Zürcher See <aq****@cannabismail.com> wrote:

<snip proof>
This is not limits, 0.(9) tends not towards 1, 0.(9) is 1


I'm convinced (after talking to another friend about it too :)

That is only by definition: "limits are exact" (I am not sure of limit is
the proper English translation of the phenomena at hand but it is what I
once learned in school). Allow me to put some doubt in you mind again.

It is like claiming that 1/x equals zero if x were infinity. Of course 1/x
would also be zero if x were minus infinity. So.

(1 / infinity) = (1 / -infinity) hence infinity = -infinity

Now does this prove that the initial statement was wrong or that indeed
everything is circular? :-)

Martin
Nov 15 '05 #19

"Martin Maat [EBL]" <du***@somewhere.nl> wrote in message
news:10*************@corp.supernews.com...
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Zürcher See <aq****@cannabismail.com> wrote:

<snip proof>
This is not limits, 0.(9) tends not towards 1, 0.(9) is 1
I'm convinced (after talking to another friend about it too :)

That is only by definition: "limits are exact" (I am not sure of limit is
the proper English translation of the phenomena at hand but it is what I
once learned in school). Allow me to put some doubt in you mind again.

It is like claiming that 1/x equals zero if x were infinity. Of course 1/x
would also be zero if x were minus infinity. So.

(1 / infinity) = (1 / -infinity) hence infinity = -infinity

Now does this prove that the initial statement was wrong or that indeed
everything is circular? :-)


Neither -- division by infinity is not defined (note - division is defined
over several number spaces, but not the space that ifinity exists in).

Your equation has taken a giant (and incorrect) leap from :
x approaches 0 as y approaches inifinity in x = 1/y

to :

x = 1/infinity = 0

regards
roy fine


Martin

Nov 15 '05 #20
First, the limts of a number is the number self!

lim 0.(9)=0.(9)

Seconds:
If you come to zero from left (-x-axis) you will have a 0- limits
If you come to zero from right (+x-axis) you will have a 0+ limits
They are not the same things.

lim 1/x=0-
x-->-Infinty

lim 1/x=0+
x-->+infinity
"Martin Maat [EBL]" <du***@somewhere.nl> schrieb im Newsbeitrag
news:10*************@corp.supernews.com...
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Zürcher See <aq****@cannabismail.com> wrote:

<snip proof>
This is not limits, 0.(9) tends not towards 1, 0.(9) is 1


I'm convinced (after talking to another friend about it too :)

That is only by definition: "limits are exact" (I am not sure of limit is
the proper English translation of the phenomena at hand but it is what I
once learned in school). Allow me to put some doubt in you mind again.

It is like claiming that 1/x equals zero if x were infinity. Of course 1/x
would also be zero if x were minus infinity. So.

(1 / infinity) = (1 / -infinity) hence infinity = -infinity

Now does this prove that the initial statement was wrong or that indeed
everything is circular? :-)

Martin

Nov 15 '05 #21
> First, the limts of a number is the number self!

lim 0.(9)=0.(9)

That's right, but 0.(9) is the same as 1 even without limits. Both are a
representation of the same number in Arabic numerals.

Greetings,
Wessel
Nov 15 '05 #22
It was what I tried to explain :)

"Wessel Troost" <no*****@like.the.sun> schrieb im Newsbeitrag
news:Xn*******************************@207.46.248. 16...
First, the limts of a number is the number self!

lim 0.(9)=0.(9)

That's right, but 0.(9) is the same as 1 even without limits. Both are a
representation of the same number in Arabic numerals.

Greetings,
Wessel

Nov 15 '05 #23
Wessel Troost <no*****@like.the.sun> wrote in message news:<Xn*******************************@207.46.248 .16>...
First, the limts of a number is the number self!

lim 0.(9)=0.(9)

That's right, but 0.(9) is the same as 1 even without limits. Both are a
representation of the same number in Arabic numerals.

Greetings,
Wessel


Except nobody yet explained how much memory one need in PC to
represent exactly 0.(9) ? :-)

JM
Nov 15 '05 #24
> Except nobody yet explained how much memory one need in PC to
represent exactly 0.(9) ? :-)

JM


1 bit.
Nov 15 '05 #25
Wessel Troost <no*****@like.the.sun> wrote in message news:<Xn*******************************@207.46.248 .16>...
First, the limts of a number is the number self!

lim 0.(9)=0.(9)

That's right, but 0.(9) is the same as 1 even without limits. Both are a
representation of the same number in Arabic numerals.

Greetings,
Wessel


Just curious,

Exactly how much memory you need in your PC to hold 0.(9) instead of 1.0 ?
;-)

JM
Nov 15 '05 #26

This thread has been closed and replies have been disabled. Please start a new discussion.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.