Fw: RFC on floating point output work

Richard Henderson rth@redhat.com
Wed Sep 10 16:55:00 GMT 2003


On Wed, Sep 10, 2003 at 04:56:08AM -0500, Benjamin Kosnik wrote:
> Richard, this might interest or disgust you, not quite sure which. Since
> you've recently had the priviledge of becoming overly-familiar with
> gcc's FP representation, perhaps you could give him some hints?

:-)

> Begin forwarded message:
> 
> Date: Wed, 10 Sep 2003 01:36:40 -0400
> From: Jerry Quinn <jlquinn@optonline.net>
> To: libstdc++@gcc.gnu.org
> Subject: RFC on floating point output work
[...]
> The only differences at this
> point are ones that appear to me to be bugs in glibc, according to the
> printf manpages.

Careful.  Man pages aren't normative.  Look at standards.
I kinda doubt the bugs are in glibc.


> #if defined(__i386__) || defined(__i860__) || defined(clipper)
> #define IEEE_8087
> #endif
> #if defined(MIPSEL) || defined(__alpha__)
> #define IEEE_8087
> #endif
[...]
> #if FLT_RADIX==16
> #define IBM
> #else
> #if DBL_MANT_DIG==56
> #define VAX

You'd do well to use instead the nice cleanups we've done in
std_limits.h in the last year.

> static int HIWORD = -1, LOWORD;
> static void test_endianness()

When integrated, this should either use defines from the compiler
proper, or from stdc++ config headers.  A runtime test is not good.

> #define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
> ((unsigned short *)a)[0] = (unsigned short)c, a++)

Strict aliasing failures.  You need to use unions.

> // qnan: 1,rest of mantissa

Not necessarily true.  MIPS is backwards: 1->SNaN, 0->QNaN.

>  union {
>    double d;
>    unsigned int b[2];
>  } x;

(1) unsigned int is not always 32-bit.
(2) it'd be nice to use 64-bit types on 64-bit systems.

> hi0bits (register unsigned32 x)

__builtin_clz(x)

> lo0bits (unsigned32 *y)

  int ret = __builtin_ctz(*y);
  *y = *y >> ret;

> struct Bigint {
[...]
> class bigint

It's definitely confusing that you've got both new and old code
in the same file.

>  * We want k to be too large rather than too small.
>  * The error in the first-order Taylor series approximation
>  * is in our favor, so we just round up the constant enough
>  * to compensate for any error in the multiplication of
>  * (i) by 0.301029995663981; since |i| <= 1077,
>  * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,

The comment should be updated for long double.  I guess the
overestimate is still ok, since while |i| <= 16881 is much
larger, 2^-64 and 2^-113 are much smaller.

You might do well to templatize this function, since it is
otherwise identical between double and long double.


r~



More information about the Libstdc++ mailing list