|
Boost : |
From: John Maddock (John_Maddock_at_[hidden])
Date: 2000-07-24 06:17:27
Dave,
>What is the alternative to rounding to float taken by the non-conforming
compilers in this case? The return type is float, so the long double needs
to be converted at some point. I believe the static_cast<> is just there to
suppress warnings.
<
On Win32, floating point values are returned on the fpu stack, if the stack
has a long double on it as a return value then the compiler may just return
it directly without doing a round to float (by storing and reloading). The
same argument applies to inlines - the compiler (and I'm talking about
Borland C++ here and it's "fast floating point" option), could just take
the long double value and feed it directly into the computation without
rounding first to a float (again requires an extra store and load).
On conforming compilers the problem is that the value is rounded twice -
once to a long double (on decimal to binary conversion), then again to a
float. This double rounding can result in the value being out by 1ulp (I
think, well at least maybe: I'm not a math expert - it may be 2ulp), and
the value is no longer the "closest binary representation". I think the
code should be:
static const T sqrt_two() _THROW0()
{ return 1.41421356237309504880168872420969807857F; }
which is the format used for some of the constants already, and will "do
the right thing" on both conforming and "fast and loose" compilers.
BTW in my last message I should have added that:
ulp= units in the last place.
and that the "What Every Compuser Scientist Should Know About Floating
Point Arithmetic" paper is available online - I don't have a link but a web
search should it.
- John.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk