Re: Rounding of the double
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Thu, 31 May 2007 16:22:09 -0400
So if you only need two digits of precision, why are you not using "%.2g" format or
something like that? If you want percentages, %5.2f or something like that would be used.
Thus, you would never print out anything like 0.8000000000004.
The more serious issue here is that you are expecting floating point to do something it
was never designed to do, and in fact is incapable of doing.
Using fixed-point integer arithmetic works well, and doesn;t require anything special; you
just realize that the integer represents percentages, not decimal values.
John von Neumann suggested that only fixed-point integers should be used because floating
point was too expensive and complex to implement, and would result in gratuitous errors
being introduced. He was right about the errors, but technology solved the first two
problems, to the point where a modern Pentium 4 can do a 32x32 floating point multiply in
one clock cycle (about 350picoseconds on a 2.8GHz machine).
If you choose your representation as double, then you have to live with the consequences.
If you choose it as fixed point integer, you get a different set of consequences (but
there ARE consequences).
In the early Ada evaluations, the Ada language allowed all kinds of floating-point
representations. I was part of the evaluation team, and we read, with absolute delight,
the comments of someone called "Robert Firth", who systematically demolished every
language's floating-point and fixed-point features. Who was this guy? A couple years
later, I had the pleasure of working with Robert for several years, and pleasure it was.
The man is somewhere around four sigmas out in the genius access (and he systematically
demolished any p-baked ideas I had, unless I could keep p>0.99. [half-baked ideas have
p=0.5]. He's now in Singapore, and I'd love to wangle a trip there just to spend an
evening with him). In addition to everything else, he has a delightful sense of humor.
Bottom line: you can never get precision in any computation on a computer than involves
any fraction. Essentially, the sum of any set of percentages is unlikely to equal 100, no
matter how many decimal places you keep; the only issue is how close you are going to get.
joe
On 31 May 2007 12:14:42 -0700, Alex <alsim123@xxxxxxxxxxx> wrote:
Thanks to everybody for the concern,Joseph M. Newcomer [MVP]
Joseph, I cannot take you suggestions, I mean using of expression
instead of variable. I must use variable, because this variable is
some parameter, which I have to use later on. And it's inconvenient
to carry all members of the expression instead of one value...
And this is not matter of a display.
The only thing I need to be able to store dValue = 0.80
Precision - 2 digits (which is 1%). That's all. I don't need
0.80000000.
So if I subtract 1.00 - 0.80 I'm going to get 0.20.
But because I have 0.800000000000004
if I subtract 1.00 - 0. 800000000000004, I'm getting 0.1999999 (I'm
not talking about rounding)
By the way SQL way is not working either, because it returns correct
value, but I have to assign it to some variable in may code, and this
variable must be double, so even though SQL Server returns
0.800000000000000, I'm getting 0.800000000000004
So as I've mentioned I had to change my code and work with integers.
Thanks again,
Alex
On May 31, 2:01 pm, Joseph M. Newcomer <newco...@xxxxxxxxxxxx> wrote:
That looks about right. You seem to be expecting that floating point is done in base 10,
which it is not. It is done in base 2, and results like this are what you should expect.
What you have to do is figure out how many decimal places you want, then add half of that,
e.g., if you expect 0.80, then you would add 0.005 to the result and display it to 2
decimal places. (The truth is vastly more complex and entire books have been written on
the subject)
The answer is that if you divide 80 by 100, you get 0.80, but there is no accurate
representation of 0.80 in IEEE floating point, so if you divide 80 by 100, you get the
closest approximation the representation can support, and when that representation is
converted to a textual representation you get 0.8000000004.
Essentially, fractions are represented by summing up powers-of-two fractional values to
the best approximation:
1/2 + 1/4 = 0.75
1/2 + 1/4 + 1/32 = 0.78125
1/2 + 1/4 + 1/32 + 1/64 = 0.796875
1/2 + 1/4 + 1/32 + 1/64 + 1/512 = 0.798828125
... + 1/1024 = 0.7998046875
... + 1/8192 = 0.7999267578125
... + 1/16384 = 0.79998779296875
... + 1/131072 = 0.79999542236328125
... + 1/262144 = 0.799999237060546875
... + 1/2097152 = 0.799999713897705078125
... + left as an exercise for the student
The simplistic explanation is that the approximation that is used is the one that produces
the smallest error. (There are actually different rounding modes in IEEE floating point
and at that point you need to start somewhere likehttp://en.wikipedia.org/wiki/IEEE_754)
I was unable to find a round() function in the MSDN that applied to C/C++; I found
JScript, VBScript, and Crystal reports, but nothing for C/C++.
joe
On 31 May 2007 08:10:16 -0700, Alex <alsim...@xxxxxxxxxxx> wrote:
Everybody,
I'm lost
I have double d1 = 80.00
double d2 = 100.00
double result = d1/d2;
result = 0.80000000000000004 !!??
Why appears this "4" at the end!!??
It really makes difference for me.
And also if I use:
double dValue = atof( "0.80" );
if also returns 0.80000000000000004
Using of the round(...) function doesn't help
It returns 80.000000/100.0000000 which OF COURSE =
0.80000000000000004 !!!???
Is there any way actually if I divide 80 by 100 to get 0.80 ?
Thanks,
Alex
Joseph M. Newcomer [MVP]
email: newco...@xxxxxxxxxxxx
Web:http://www.flounder.com
MVP Tips:http://www.flounder.com/mvp_tips.htm- Hide quoted text -
- Show quoted text -
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- References:
- Rounding of the double
- From: Alex
- Re: Rounding of the double
- From: Joseph M . Newcomer
- Re: Rounding of the double
- From: Alex
- Rounding of the double
- Prev by Date: Re: Rounding of the double
- Next by Date: Re: Check a radio button
- Previous by thread: Re: Rounding of the double
- Next by thread: Changing Serial Baud Rates
- Index(es):