Board index » cppbuilder » log(2.0)-log(2.0)

log(2.0)-log(2.0)


2004-12-17 05:26:18 AM
cppbuilder14
In debugging a code I have the following line
printf( "%e", log(2.0) - log(2.0))
which should be zero. What I get is
-2.320193e-17
Any ideas?
 
 

Re:log(2.0)-log(2.0)

Quote
In debugging a code I have the following line

printf( "%e", log(2.0) - log(2.0))

which should be zero. What I get is

-2.320193e-17

Any ideas?
Look pretty close to zero to me ;^).
Look at these links:
docs.sun.com/source/806-3568/ncgTOC.html
Esp. Appendix D
Regards,
Bruce
 

Re:log(2.0)-log(2.0)

I understand floating point arithmetic, but the computer should still give
me zero in this case. The numbers are EXACTLY the same.
Cory
" Bruce Salzman" < XXXX@XXXXX.COM >wrote in message
Quote

>In debugging a code I have the following line
>
>printf( "%e", log(2.0) - log(2.0))
>
>which should be zero. What I get is
>
>-2.320193e-17
>
>Any ideas?

Look pretty close to zero to me ;^).

Look at these links:

docs.sun.com/source/806-3568/ncgTOC.html

Esp. Appendix D

Regards,
Bruce

 

{smallsort}

Re:log(2.0)-log(2.0)

On 2004-12-16 4:26 PM, cory wrote:
Quote
In debugging a code I have the following line

printf( "%e", log(2.0) - log(2.0))

which should be zero. What I get is

-2.320193e-17
Maybe the compiler is doing something like this,
which it is allowed to do:
set the floating-point hardware to use 80-bit
'long double' internally
have the floating-point hardware compute ln 2
and store that value into a double, which
loses some precision
have the floating-point hardware compute ln 2
and leave it on the floating-point stack
push the stored value onto the stack
subtract and pop the result into a double
Then the result would be something like
long double x0 = 0.693147180559945309417;
double x1 = 0.693147180559945;
double x3 = x1 - x0; // -0.000000000000000309...
which is about what you report. Of course, the lossy
conversion to double takes place in binary, so it
doesn't give a value exactly equal to the decimal
0.693147180559945; but I bet you can create a test
program this way that reproduces your observed
discrepancy exactly.
If you want the answer to be exactly zero, then store
intermediate values into doubles. There are probably
compiler options to force such stores, but writing it
explicitly is more portable.
 

Re:log(2.0)-log(2.0)

"cory" < XXXX@XXXXX.COM >wrote in message
Quote
I understand floating point arithmetic, but the computer should still
give me zero in this case. The numbers are EXACTLY the same.

Intuitively, I agree. But floating point math on a computer isn't
always intuitive. Things like
x*y != y*x
or
x < y but 1.0 * x>y
happen.
If you want to test for equality, or test the results of a computation
for zero, it is usually advisable to use a threshold.
See Greg's answer for an explanation of what is no doubt happening in
your example.
HTH,
Bruce
 

Re:log(2.0)-log(2.0)

Quote
I understand floating point arithmetic, but the computer
should still give me zero in this case. The numbers
are EXACTLY the same.
I don't think so.
Intermediate results in the floating point coprocessor
are handled in a register which has extra length for
maintaining precision. Because of the way you formed
the expression in your code one of the terms in that
expression is in that intermediate register and the
other is not. Have the compiler create an assembly
source file from your code and read the processor
instructions.
support.intel.com/design/PentiumIII/documentation.htm
docs.sun.com/source/806-3568/ncg_goldberg.html
www.math.grin.edu/~stone/courses/fundamentals/IEEE-reals.html
docs.sun.com/app/docs/doc/800-7895/6hos0aou4
. Ed
Quote
cory wrote in message
news: XXXX@XXXXX.COM ...
 

Re:log(2.0)-log(2.0)

I ran a little test and you are correct. Thanks for pointing that out.
Cory
"Greg Chicares" < XXXX@XXXXX.COM >wrote in message
Quote
On 2004-12-16 4:26 PM, cory wrote:

>In debugging a code I have the following line
>
>printf( "%e", log(2.0) - log(2.0))
>
>which should be zero. What I get is
>
>-2.320193e-17

Maybe the compiler is doing something like this,
which it is allowed to do:

set the floating-point hardware to use 80-bit
'long double' internally
have the floating-point hardware compute ln 2
and store that value into a double, which
loses some precision
have the floating-point hardware compute ln 2
and leave it on the floating-point stack
push the stored value onto the stack
subtract and pop the result into a double

Then the result would be something like
long double x0 = 0.693147180559945309417;
double x1 = 0.693147180559945;
double x3 = x1 - x0; // -0.000000000000000309...
which is about what you report. Of course, the lossy
conversion to double takes place in binary, so it
doesn't give a value exactly equal to the decimal
0.693147180559945; but I bet you can create a test
program this way that reproduces your observed
discrepancy exactly.

If you want the answer to be exactly zero, then store
intermediate values into doubles. There are probably
compiler options to force such stores, but writing it
explicitly is more portable.