From owner-freebsd-hackers Sat May 31 02:36:29 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.5/8.8.5) id CAA15795 for hackers-outgoing; Sat, 31 May 1997 02:36:29 -0700 (PDT) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by hub.freebsd.org (8.8.5/8.8.5) with ESMTP id CAA15790 for ; Sat, 31 May 1997 02:36:25 -0700 (PDT) Received: (from bde@localhost) by godzilla.zeta.org.au (8.8.5/8.6.9) id TAA08679; Sat, 31 May 1997 19:30:36 +1000 Date: Sat, 31 May 1997 19:30:36 +1000 From: Bruce Evans Message-Id: <199705310930.TAA08679@godzilla.zeta.org.au> To: hackers@FreeBSD.ORG, j@uriah.heep.sax.de Subject: Re: bcc vs cc/gcc (float) Cc: un_x@anchorage.net Sender: owner-hackers@FreeBSD.ORG X-Loop: FreeBSD.org Precedence: bulk >> 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