Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 31 May 1997 19:30:36 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        hackers@FreeBSD.ORG, j@uriah.heep.sax.de
Cc:        un_x@anchorage.net
Subject:   Re: bcc vs cc/gcc (float)
Message-ID:  <199705310930.TAA08679@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>> i have taken a great deal of time creating this code to
>> show this point - and it should compile cleanly as is
>> under bcc/cc/gcc.  Borland C (4.51) can run this code
>> without any loss of accuracy.  please CC me, i'm not
>> subscribed.

This code needs to use nonstandard long double math functions
(powl() and fmodl()) to work for values > DBL_MAX.  FreeBSD
does not support these functions.

This code also requires long double precision to actually work.
Long double precision is not the default in FreeBSD.  You can
set it using fpsetprec().

Printing of long double values with full precision is not
supported in FreeBSD.  This is why the same value is printed
for `ld-9' as for `ld'.

All this has very little to do with gcc.

>I'm not much surprised that the use of non-standard components (long
>double) produces unexpected results.  You multiply a long double with
>a double (result of pow()), so who tells you whether the compiler does
>it by first extending the result of pow() to long double format (thus
>`inventing' missing precision digits), or by first truncating the long
>double (although i wouldn't expect this)?

The ANSI C standard :-).  However, the standard doesn't specify that
long double precision is strictly more precise than double precsision
or the amount of precision of double precsision.

/*****************************************************************************/
unsigned char *ftous (unsigned char *s, long double val, unsigned char base) {

/* float to unsigned string */
                                                       /* if base>10 adjust  */
unsigned char *p=s;                                    /* to  alpha numeral  */

     if ( val < 0 ) val = -val; /* val+=0.49999999; <- needed for Borland C  */
                                   ^^^^^^^^^^^^^^^
Shouldn't be necessary.  The algorithm requires `val' to have no fractional
part.

     do { *p++ = itoan(fmod(val, base)); printf("- %s %Lf\n", s, val);
          val/=base;
          ^^^^^^^^^

Bug.  The fractional part needs to be subtracted somewhere, perhaps using
`val = floor(val / base);' here.

     }    while ( val >= 1 );

     *p = 0;                                           return( strrvs(s, 0) );}
/*****************************************************************************/

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199705310930.TAA08679>