Re: This calculation is just wrong / computer can't count!
- From: Joseph M. Newcomer <newcomer@xxxxxxxxxxxx>
- Date: Sun, 07 Oct 2007 16:11:30 -0400
See below..
On Sun, 07 Oct 2007 04:19:07 GMT, Geoff <geoff@xxxxxxxxxxxxxxx> wrote:
On Thu, 4 Oct 2007 22:44:14 +0100, "GT"****
<ContactGT_remove_@xxxxxxxxxxx> wrote:
I understand all this significant digit stuff, my problem is - Why does the
computer store and use the 'dodgy' last digit if it is actually WRONG and
causes incorrect results?
What you are encountering is a fundamental limitation in the IEEE 754
64-bit binary representation of floating point numbers used to
represent those numbers in what is essentially an integer process
inside the CPU. This is not an error, this is a fundamental design
compromise made when the IEEE 754 standard was introduced and
designed.
If you use Newcomer's floating point explorer you will see in the bit
pattern of the mantissa that there is no distinction between the bit
pattern for
0.83333333333333337 (0xAAAAAAAAAAAAB)
and
0.83333333333333333 (0xAAAAAAAAAAAAB)
Likewise for
0.83333333333333333
0.83333333333333334
0.83333333333333335
0.83333333333333336
0.83333333333333337
0.83333333333333338
0.83333333333333339
(The full 64-bit representation of your number is 0x3FEAAAAAAAAAAAAB
but Newcomer chooses not to express the full hexadecimal
representation in his program, we must forgive him.)
Yes, I only show the mantissa precision. Counting the sign and the exponent the full
64-bit value is
0x3FEAAAAAAAAAAAAA
****
He does provideJoseph M. Newcomer [MVP]
source, so this is easily fixed.
Now, when you ask the C++ libraries to "print" the floating point
result as a string the printing routines must print the representation
of the bit pattern and the authors of the library decided to print the
7 rather than the 3 through 9 that interpreting (0xAAAAAAAAAAAAB) as a
float would bring.
In other words, if you want to compute floating point to 17 digits of
precision, expect to encounter these kinds of errors in those last 2
digits. If you don't want to see them, then format your output to 15
digits of precision. In this case you are using printf("%.17f", num)
and it is your program that is wrong, not the math. If you use
printf("%.15f\n", num) (0.83333333333333337 becomes 0.833333333333333)
and the output is correct for all floating point results representable
by 64 bits.
You should also evaluate the macro DBL_DIG in <float.h> for your
compiler and environment when engaging in floating point operations so
you understand the fundamental limitations of your compiler and
libraries. If you had evaluated DBL_DIG you probably would have found
the Microsoft compiler supports DBL_DIG = 15 or 15 digits of
precision. The IEEE 754 FPU carries it out to 17 digits in order to
guaranty accuracy to 15 digits of precision.
Another problem of floating point math is adding or subtracting
numbers that are close in value, as you have done to obtain your
-0.00000000000000007 result. You should structure your code to avoid
this.
See P. J. Plaugher's "The Standard C Library" for an understanding of
how difficult it is to design and test floating point operations
inside integer computers.
If 15 decimal points of precision is not enough for your application,
I suggest you design your own floating point library and do not depend
on the floating point processors in your computers.
You could also ask Microsoft how they get the Calculator application
to yield 0.83333333333333333333333333333333 when doing 25/30.
Furthermore, since 25/30 is a repeating-decimal, irrational number and
cannot be represented by any finite set of digits you cannot expect to
take this calculation seriously to arbitrary decimal points on any
finite computer. If 25 and 30 represent measurable quantities they
cannot be known (measured) to arbitrary precision. In other words, if
you are building a real device you can measure 25.0 or 25.0000 plus or
minus the least significant digit, plus or minus the error in your
measuring device. As finite reals, measured with a given uncertainty,
you cannot expect your results to exceed the precision with which the
operands are known. So in your example, if you know 25.0 and 30.0 to
three significant figures you cannot express 25.0/30.0 any more
precisely than 0.833 anyway and all this fuss about 17 digits of
precision is for nothing.
http://en.wikipedia.org/wiki/Significant_figures
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.
- References:
- This calculation is just wrong / computer can't count!
- From: GT
- Re: This calculation is just wrong / computer can't count!
- From: AliR \(VC++ MVP\)
- Re: This calculation is just wrong / computer can't count!
- From: GT
- Re: This calculation is just wrong / computer can't count!
- From: Luke alcatel
- Re: This calculation is just wrong / computer can't count!
- From: GT
- Re: This calculation is just wrong / computer can't count!
- From: Geoff
- This calculation is just wrong / computer can't count!
- Prev by Date: Is there a Java version of CHtmlEditView
- Next by Date: Re: how do I open Zero Wireless Configuration (WZC) window ?
- Previous by thread: Re: This calculation is just wrong / computer can't count!
- Next by thread: Re: This calculation is just wrong / computer can't count!
- Index(es):
Relevant Pages
|