Related articles |
---|
re: Compiler bugs chase@world.std.com (David Chase) (2002-01-03) |
Re: Compiler bugs christian.bau@cbau.freeserve.co.uk (Christian Bau) (2002-01-05) |
Re: Compiler bugs chase@world.std.com (David Chase) (2002-01-14) |
Re: floating point accuracy, was Compiler bugs christian.bau@cbau.freeserve.co.uk (Christian Bau) (2002-01-17) |
Re: floating point accuracy, was Compiler bugs sos@zjod.net (2002-01-18) |
Re: floating point accuracy, was Compiler bugs chase@world.std.com (David Chase) (2002-01-18) |
Re: floating point accuracy haberg@matematik.su.se (2002-01-24) |
Re: floating point accuracy, was Compiler bugs christian.bau@cbau.freeserve.co.uk (Christian Bau) (2002-01-24) |
From: | Christian Bau <christian.bau@cbau.freeserve.co.uk> |
Newsgroups: | comp.compilers |
Date: | 17 Jan 2002 00:30:32 -0500 |
Organization: | Compilers Central |
References: | 02-01-015 02-01-029 02-01-054 |
Keywords: | arithmetic, errors |
Posted-Date: | 17 Jan 2002 00:30:32 EST |
David Chase wrote:
<about the Java specification that the sine and cosine function must
produce the infinitely exact result, rounded to one of the two nearest
floating point numbers>
> I'm a little curious about one thing -- does anyone, besides a
> specifications- and-exact-correctness weenie like myself, actually
> care about this level of detail in machine floating point?
You can look at rounding errors in two ways: Instead of producing f (x)
you produce f (x) + eps, and you want eps small. Or instead of producing
f (x) you produce f (x + delta), and you want delta small. So instead of
almost getting the answer to the question you asked, you get an answer
to almost the question you asked. The Java spec demands the first
behaviour. Have a look what happens if you demand the second behaviour:
First, the Pentium hardware implementation of sin (x) becomes quite
excellent. The problem cases happen when x is close to pi and therefore
sin (x) very close to 0, and for absurdely large x. In the first case,
the Pentium will calculate sin (x + eps) where eps is very small
compared to x (about 2^-66 instead of 2^-53), in the second case any
result between -1 and +1 would be "good". Then there is the cosine
function: Here the goal of calculating cos (x + delta) where delta is
very small cannot be achieved. For small x, cos x is approximately 1 -
x^2 / 2. If u is defined such that 1 + u is the smallest floating point
number greater than 1, then 1 - u/2 is the largest floating point number
< 1. Let x = sqrt (u) / 2, then cos x is about 1 - u^2/4. The two
nearest floating point numbers are 1 and 1 - u/2. cos (0) = 1, cos (sqrt
(u) / sqrt (2)) = 1 - u/2, and both numbers are quite far away from 1 -
u/4.
So if you look at the errors the other way round, the picture changes
dramatically.
The whole IEEE standard is all about quality to get reliable results, so
that programs behave the way that a non-expert programmer expect as
often as possible. Now what does the Java spec for sine and cosine
achieve: As an example, examine the follows of sin (x)*sin (x) + cos
(x)*cos (x). These should always be close to 1. The Java spec doesn't
achieve that the results are always one. Even if sin (x) and cos (x) are
both within 1/2 ulp all the time, you can get relatively large errors.
And implementations that are a lot faster (like Pentium hardware, or
MacOS standard C library) while still getting decent results do just as
good (the MacOS implementation calculates sin (x+eps) or cos (x+eps)
within something like 0.7 ulp, and eps is less that x * 2^-100).
Or let my ask this question: The fdlibm functions for sine/cosine
contain some huge tables. If one bit in these tables were incorrect,
producing completely wrong results for x > 1e100 (but still in the range
-1 to +1), would anyone notice?
Return to the
comp.compilers page.
Search the
comp.compilers archives again.