Re: This calculation is just wrong / computer can't count!

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



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 provide
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
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.



Relevant Pages

  • Re: Gentler Decimal Floating-Point
    ... effectively change the radix of a decimal floating point ... under the heading "Logarithms all the time", ... logarithmic representation of numbers to be made workable for all the ... The middle digits are shifted only when the exponent, ...
    (comp.arch.arithmetic)
  • Re: Linear Algebra Challenge
    ... Since I'm using floating point, so I'll never be able to calculate one ... floating point math set to 99 digits. ... As close as I'm willing to wait if I use arbitrary precision. ... This mode is fast; when you select arbitry ...
    (comp.sys.hp48)
  • Re: Interesting math
    ... Floating point number represents a real number with 6 digits precision. ... Floating point numbers are denoted by the keyword float. ...
    (alt.usage.english)
  • Re: float -> double
    ... Let us take a float with the hexadecimal representation 0x3f800001. ... When converting to double, we get another 29 bits of precision, which means we can theoretically convert this number to any one of 536,870,912 possible representable numbers in the range. ... The exact value could be printed if you really wanted to, but there's no real point since the implicit error in the number dwarfs most of the latter digits. ...
    (comp.lang.java.programmer)
  • Re: Interesting math
    ... Floating point number represents a real number with 6 digits precision. ... Floating point numbers are denoted by the keyword float. ...
    (alt.usage.english)