Re: [boost] Boost regression notification (2005-09-03 [HEAD])

Doug Gregor [mailto:dgregor@cs.indiana.edu] wrote:
Somebody wrote:
It looks like some code isn't handling the improved "long double" type very well.... (With Mac OS X Tiger 10.4 and GCC 4, the "long double" type is finally distinct and bigger than "double". The pre-Tiger warnings about not using "long double" are obviously removed. But it looks like the "double" version of "exp" is being used. Taking a quick look at a system "math.h"...
I've traced through this, and the right "exp" is getting called. The machine epsilon for long double is:
4.9406564584124654417656879286822137236505980261432476442558568250067550 727020875e-324
Are you sure that's right? That implies a 1074-bit mantissa. That's a VERY long double! (It is also a rather odd sized one. In such a large type, I would expect the mantissa to be an exact number of bytes - or mantissa+sign to be an exact number of bytes). That value looks much more reasonable for the smallest non-zero value of long double. (I am assuming that by epsilon you mean the smallest values such that 1+epsilon != 1, rather than the smallest value such that epsilon > 0).
There's no *way* we'll get that much accuracy out of the C library's sin/atan/cos/etc. Here's the result of a little program that prints out atan(1), 4*atan(1), and sin(4*atan(1)). There isn't a large enough improvement in precision from "double" to "long double":
atan(1) with float = 0.785398185253143310546875 4*atan(1) with float = 3.1415927410125732421875 sin(4*atan(1)) with float = -8.74227765734758577309548854827880859375e-08 atan(1) with double = 0.78539816339744827899949086713604629039764404296875 4*atan(1) with double = 3.141592653589793115997963468544185161590576171875 sin(4*atan(1)) with double = 1.224606353822377258211417938582599163055419921875e-16 atan(1) with long double = 0.7853981633974483096282022398515465511081856675446033477783203125 4*atan(1) with long double = 3.14159265358979323851280895940618620443274267017841339111328125 sin(4*atan(1)) with long double = -5.42101086242752217003726400434970855712890625e-20
If long double is actually 80 bits (which is the usual Intel interpretation), that looks plausible.
I don't even think that we can call this a platform bug; we just can't expect the C library routines to have that kind of precision.
If long double really is >1kbits, I don't see why the C runtime shouldn't support them.
I think we should consider long double tests on this platform bogus and disable them.
-- Martin Bonner Martin.Bonner@Pitechnology.com Pi Technology, Milton Hall, Ely Road, Milton, Cambridge, CB4 6WZ, ENGLAND Tel: +44 (0)1223 441434

On Sep 13, 2005, at 4:38 AM, Martin Bonner wrote:
Doug Gregor [mailto:dgregor@cs.indiana.edu] wrote:
I've traced through this, and the right "exp" is getting called. The machine epsilon for long double is:
4.9406564584124654417656879286822137236505980261432476442558568250067 550 727020875e-324
Are you sure that's right? That implies a 1074-bit mantissa. That's a VERY long double! (It is also a rather odd sized one. In such a large type, I would expect the mantissa to be an exact number of bytes - or mantissa+sign to be an exact number of bytes).
That value looks much more reasonable for the smallest non-zero value of long double.
(I am assuming that by epsilon you mean the smallest values such that 1+epsilon != 1, rather than the smallest value such that epsilon > 0).
I discussed this with Marshall Clow offline and we eventually talked with an Apple engineer. Marshall summarized the issue as: "gcc 4 uses a "doubled double" format for long double (why? I don't know), where there are two double values inside the long double. For numbers that can be represented exactly (like, say 0 or 1), the "next value" is very, very close, because (I'm assuming) they can denormalize the lower value, and get 1e-324 type ranges. However, for numbers that cannot be represented exactly, the "next value" is on the order of 2^-112 greater. Since epsilon is defined as the difference between 1 and the "next value greater than one", they can return a very, very small number here - and it is correct (but not useful)." AFAICT, for this floating-point format, the machine epsilon is truly a useless value; we shouldn't be comparing against it in our tests because it doesn't really reflect the precision of the floating-point format. Doug
participants (2)
-
Douglas Gregor
-
Martin Bonner