Re: Lack of real long double support
In message: [EMAIL PROTECTED] Terry Lambert [EMAIL PROTECTED] writes: : M. Warner Losh wrote: : : This : : example shows that we don't support it in printf, since the above : : example does ***NOT*** give +Inf, but rather whatever 2*DBL_MAX is. : : [ ... ] : : Terry you are wrong. This has to do with the RANGE not the PRECISION : of the floating point number. It is ***NOT*** +Inf. : : I await an explanation of how you can fit 2*DBL_MAX into a double, : which has a range of DBL_MIN..DBL_MAX. Look at the code. long double a = DBL_MAX; long double b = DBL_MAX * 2; The original posting said that b would be +Inf at this point, which is not correct. I think that Bruce was confused there. The more correct example to look at was the one that rittle@ posted which was 1 + LDBL_EPSILON. : : The main issue that I think is outstanding is that you can't get : : both exception behaviour and non-exception behaviour, and it is : : going to have to be the compiler's job to force the issue, because : : it can't dictate implementaiton to the host OS. : : I don't follow. : : I think that a number that's a 64 bit mantissa reaised to an exponent : N takes a larger N if you have only 53 bits of mantissa, if you want : to represent the same value. Nope. The only difference between 53 bits and 64 bits of precision is just that: precision. The number of bits for expoentent is independent of this. : The obvious example in the FreeBSD case is the default value of the : expression (fpgetprec() == FP_PE). The compiler is not permitted to : assume, one way or the other; it has to do runtime testing, at the : time you compile the compiler, to comply with a completely strict : interpretation of C99 (IMO). This is true. Granting, for the moment, that fpgetprec() == FP_PE isn't a standards conforming expression. But I think that the rest of this is going off into the weeds. I'm just trying to get things working in a sane way for long doubles. It looks like gcc 3.2 really wants the fpu to start off in FP_PE. Before I go forward on this further, I've got a lot of testing to do with kernels and such to find out what really works and what does (and doesn't) break paranoia.c. Warner To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
On Wed, 30 Oct 2002, Terry Lambert wrote: This is the basis of Bruce's complaint: http://docs.freebsd.org/cgi/getmsg.cgi?fetch=1099099+0+archive/2002/freebsd-current/20021027.freebsd-current | gcc can't actually support the full range, since it doesn't control | the runtime environement (it could issue a fninit before main() to | change the default, but it shouldn't and doesn't). The exponent | range is lost long before printf() is reached. E.g., | | long double x= DBL_MAX; | long double y = 2 * x; | | gives +Inf for y since the result is doesn't fit in 53-bit precision. | The system header correctly reports this default precision. Any header | genrated by the gcc build should be no different, since the build should | run in the target environment. Please forget this wrong example :-). The precision doesn't affect the exponent range. Bruce To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
On Wed, 30 Oct 2002, M. Warner Losh wrote: The one issue that I've seen is long double a = 1.0L; long double b = 1.0L + LDBL_EPSION if (a == b) abort(); which is what I'm trying to fix. (note, 1.0L must be spelled oneld() and long double oneld() { return (1.0L);}) to avoid the optimizer getting it right. Example of how fixing this breaks a similar assertion for DBL_ESPILON: %%% $ cat z.c #include float.h #include floatingpoint.h long double oneld = 1.0L; double oned = 1.0; int main() { test(2); test(3); } int test(int prec) { long double la, lb; double a, b; fpsetprec(prec); la = oneld; lb = oneld + LDBL_EPSILON; if (la == lb) printf(LDBL_EPSILON failed test 1 with prec %d\n, prec); la = oneld; lb = oneld + LDBL_EPSILON / 2; if (la != lb) printf(LDBL_EPSILON failed test 2 with prec %d\n, prec); a = oned; b = oned + DBL_EPSILON; if (a == b) printf(DBL_EPSILON failed test 1 with prec %d\n, prec); a = oned; b = oned + DBL_EPSILON / 2; if (a != b) printf(DBL_EPSILON failed test 2 with prec %d\n, prec); } $ cc -o z z.c $ ./z LDBL_EPSILON failed test 1 with prec 2 $ cc -O -o z z.c. $ ./z LDBL_EPSILON failed test 1 with prec 2 DBL_EPSILON failed test 2 with prec 3 %%% The full brokenness only shows up with -O. Bruce To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
On Wed, 30 Oct 2002, M. Warner Losh wrote: In message: [EMAIL PROTECTED] Bruce Evans [EMAIL PROTECTED] writes: : The reasons are the same as they used to be: incomplete language support : and incomplete library support. Language support is being completed but : is far from here yet. See the paper referenced in Loren's reply for more : details than anyone should want to know. OK. I'll have to go back and find that reference. I'd really like to change the __INITIAL_NPXCW__ from 0x127f to 0x137f in npx.h. I think that we can get the library support in place over time, as this already is a bullet item in the standards todo list web page. The gcc 3.2 compiler does a decent, but not perfect, job of dealing with the floating point stuff. Er, it does the same very imperfect job that it did in when it first implemented long doubles. : C99 encourages having a behaviour that is known at compile time and : telling applications about it in FLT_EVAL_METHOD (this can be set to : -1 == indeterminable, but that would not be very useful although it : is the only correct setting now). The compiler should implement the : system implementor's choice or enforce its own choice. gcc doesn't : really understand this this. gcc-3.2 thinks that it implementing : method 0 (no extension of precision) but the npx hardware is nothing : like that. I don't understand this completely. ARe you saying that gcc is doing something worng? Yes. It doesn't attempt to implement C99 stuff and depends on a fuzzy reading of C90 to conform to C90. Example of gcc-3.2's schizophrenia with precision: %%% $ cat z.c double x = 1.0F / 3.0F; float y = 1.0F; float z = 3.0F; double u; int main() { u = y / z; printf(x = %.17g\n, x); printf(u = %.17g\n, u); return (x == u ? 0 : 1); } $ cc -o z z.c $ ./z x = 0.333432674408 u = 0.1 %%% Evaluation at compile time is different that at runtime because gcc thinks that float operations are performed in float precision and performs them at that precision at compile time. But float operations at runtime are actually performed in the ambient precision due to white lies like the following in i386.md: %%% (define_expand divsf3 [(set (match_operand:SF 0 register_operand ) (div:SF (match_operand:SF 1 register_operand ) (match_operand:SF 2 nonimmediate_operand )))] TARGET_80387 || TARGET_SSE_MATH ) %%% (This says that the result of dividing a single-precision float by a single precision float is a single-precision float, but the result is actually an ambient-precision float.) The above example is for float precision. The FreeBSD default basically insulates users from surprises due to precision when everything is a long double. BTW, NetBSD is kinda schizophrenic about this: It just supports a lot of cases. /* * The i387 defaults to Intel extended precision mode and round to nearest, * with all exceptions masked. */ #define __INITIAL_NPXCW__ 0x037f /* NetBSD uses IEEE double precision. */ #define __NetBSD_NPXCW__0x127f /* FreeBSD leaves some exceptions unmasked as well. */ #define __FreeBSD_NPXCW__ 0x1272 This is the FreeBSD[1-3] default. /* iBCS2 goes a bit further and leaves the underflow exception unmasked. */ #define __iBCS2_NPXCW__ 0x0262 FreeBSD and NetBSD are both derived from 386BSD which had this. I added the 0x1000 bit in case 386BSD ever got run with a 287. /* Linux just uses the default control word. */ #define __Linux_NPXCW__ 0x037f /* SVR4 uses the same control word as iBCS2. */ #define __SVR4_NPXCW__ 0x0262 So their float.h values are correct only for Linux binaries and emulation. Also, it looks like FreeBSD_NPXCW is incorrect, since we Linux binaries are just differently incorrect :-). have: #define __INITIAL_NPXCW__ 0x127F And there's a comment: * 64-bit precision often gives bad results with high level languages * because it makes the results of calculations depend on whether * intermediate values are stored in memory or in FPU registers. which seems like a compiler issue, not an OS issue to me. Indeed it is mostly a language issue, so this is not a very good place to decide the setting. You would not be wrong to set it in crt0 if you removed it in the kernel (just set the hardware default in the kernel). But the library can still override any unwanted defaults. Bruce To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
Thus spake Bruce Evans [EMAIL PROTECTED]: $ cc -o z z.c $ ./z LDBL_EPSILON failed test 1 with prec 2 $ cc -O -o z z.c. $ ./z LDBL_EPSILON failed test 1 with prec 2 DBL_EPSILON failed test 2 with prec 3 %%% The full brokenness only shows up with -O. Actually, the _full_ brokenness of floating point in FreeBSD shows up only with -O2. :-( A number of library functions (e.g. isinf()) use unions for type punning, which violates C's aliasing rules. It turns out that there's a bad interaction between gcc3's -fschedule-insns and -fstrict-aliasing (both implied by -O2) that can cause problems. The best fix I know of is to use unions in the limited way that gcc's optimizer knows how to handle in a reasonable way. To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
On Thu, 31 Oct 2002, David Schultz wrote: Thus spake Bruce Evans [EMAIL PROTECTED]: $ cc -o z z.c $ ./z LDBL_EPSILON failed test 1 with prec 2 $ cc -O -o z z.c. $ ./z LDBL_EPSILON failed test 1 with prec 2 DBL_EPSILON failed test 2 with prec 3 %%% The full brokenness only shows up with -O. Actually, the _full_ brokenness of floating point in FreeBSD shows up only with -O2. :-( A number of library functions (e.g. isinf()) use unions for type punning, which violates C's aliasing rules. It turns out that there's a bad interaction between gcc3's -fschedule-insns and -fstrict-aliasing (both implied by -O2) that can cause problems. The best fix I know of is to use unions in the limited way that gcc's optimizer knows how to handle in a reasonable way. Eeek. gcc.info says one version is required to work even with -fstrict-aliasing. The problems seems to be limited, since msun was fixed before rev.1.1 to use this version. From msun/src/math_private.h: %%% /* * The original fdlibm code used statements like: * n0 = ((*(int*)one)29)^1; * index of high word * * ix0 = *(n0+(int*)x); * high word of x * * ix1 = *((1-n0)+(int*)x); * low word of x * * to dig two 32 bit words out of the 64 bit IEEE floating point * value. That is non-ANSI, and, moreover, the gcc instruction * scheduler gets it wrong. We instead use the following macros. * Unlike the original code, we determine the endianness at compile * time, not at run time; I don't see much benefit to selecting * endianness at run time. */ ... #define EXTRACT_WORDS(ix0,ix1,d)\ do {\ ieee_double_shape_type ew_u; \ ew_u.value = (d); \ (ix0) = ew_u.parts.msw; \ (ix1) = ew_u.parts.lsw; \ } while (0) ... %%% This stores the double into the union and doesn't use any pointers to access the results, so it should work. isinf.c and even the fixed version of strtod.c uses a dubious cast to pun the double to a union. I think the store gets optimized away as far as possible. Bruce To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
In article [EMAIL PROTECTED], Bruce Evans[EMAIL PROTECTED] writes: Example of how fixing this breaks a similar assertion for DBL_ESPILON: %%% $ cat z.c [...] $ cc -o z z.c $ ./z LDBL_EPSILON failed test 1 with prec 2 $ cc -O -o z z.c. $ ./z LDBL_EPSILON failed test 1 with prec 2 DBL_EPSILON failed test 2 with prec 3 %%% The full brokenness only shows up with -O. When I run your program against gcc mainline (for 3.3 release) with the patch I have staged from RTH to correctly match our FP hardware default setup, I see: S rittle@latour; /usr/local/beta-gcc/bin/gcc t.c S rittle@latour; a.out LDBL_EPSILON failed test 2 with prec 3 S rittle@latour; /usr/local/beta-gcc/bin/gcc -O t.c S rittle@latour; a.out LDBL_EPSILON failed test 2 with prec 3 DBL_EPSILON failed test 2 with prec 3 S rittle@latour; /usr/local/beta-gcc/bin/gcc -O2 t.c S rittle@latour; a.out LDBL_EPSILON failed test 2 with prec 3 DBL_EPSILON failed test 2 with prec 3 S rittle@latour; /usr/local/beta-gcc/bin/gcc -O3 t.c S rittle@latour; a.out LDBL_EPSILON failed test 2 with prec 3 DBL_EPSILON failed test 2 with prec 3 I.e. the only time it fails is when the user made a call to change the default precision. Is that gcc 3.3 behavior acceptable (at least until gcc can be further refined to attempt to handle user override of the FP control word)? Regards, Loren To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
Bruce Evans wrote: Please forget this wrong example :-). The precision doesn't affect the exponent range. Done. -- Terry To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
M. Warner Losh wrote: : I await an explanation of how you can fit 2*DBL_MAX into a double, : which has a range of DBL_MIN..DBL_MAX. Look at the code. long double a = DBL_MAX; long double b = DBL_MAX * 2; The original posting said that b would be +Inf at this point, which is not correct. I think that Bruce was confused there. The more correct example to look at was the one that rittle@ posted which was 1 + LDBL_EPSILON. I guess I must not be understanding. What will b be, at this point, then? How can it have a value larger than DBL_MAX that's not +Inf? If it's possible to represent a value larger than DBL_MAX in a double, then the value of DBL_MAX is wrong, right? Maximum means maximum, doesn't it? : I think that a number that's a 64 bit mantissa reaised to an exponent : N takes a larger N if you have only 53 bits of mantissa, if you want : to represent the same value. Nope. The only difference between 53 bits and 64 bits of precision is just that: precision. The number of bits for expoentent is independent of this. .125 ^ 2 = 0.015625 .25 ^ 3 = 0.015625 So if I go from 3 digits of precision to 2 digits of precision for my mantissa, in order to represent the same number, I need a larger exponent. This is true. Granting, for the moment, that fpgetprec() == FP_PE isn't a standards conforming expression. But I think that the rest of this is going off into the weeds. I'm just trying to get things working in a sane way for long doubles. It looks like gcc 3.2 really wants the fpu to start off in FP_PE. There has to be an agreement between the host OS and the compiler; that's what makes C99 more complicated than it needed to be. Before I go forward on this further, I've got a lot of testing to do with kernels and such to find out what really works and what does (and doesn't) break paranoia.c. That's one test. Another is: http://www.glenmccl.com/c9suite.htm Unfortunately, it's $8495 for everything. 8-(. There's also the stuff I wrote, which doesn't test range/domain overflows, etc., but at least complains when things are not defined or prototypes are out of scope (i.e. it mostly just complains about header file contents). -- Terry To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
On Thu, Oct 31, 2002 at 03:18:47PM -0700, M. Warner Losh wrote: In message: [EMAIL PROTECTED] Terry Lambert [EMAIL PROTECTED] writes: : Nope. The only difference between 53 bits and 64 bits of precision is : just that: precision. The number of bits for expoentent is : independent of this. : : .125 ^ 2 = 0.015625 : .25 ^ 3 = 0.015625 : : So if I go from 3 digits of precision to 2 digits of precision for : my mantissa, in order to represent the same number, I need a larger : exponent. That's not how it works. The exponent is more like .125 * 2^3 vs .124 * 2^3 Both have exponent 3, but the differ by a bit or two in the mantissa. Loren already posted a pointer to What Every Scientist Should Know About Floating-Point Arithmetic by David Goldberg. But, for Terry edification http://cch.loria.fr/documentation/IEEE754/ACM/goldberg.pdf This is only 1 of 66100 hits from a google search with keywords floating point scientist. -- Steve To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
On Thu, 31 Oct 2002, M. Warner Losh wrote: In message: [EMAIL PROTECTED] Terry Lambert [EMAIL PROTECTED] writes: : M. Warner Losh wrote: : : I await an explanation of how you can fit 2*DBL_MAX into a double, : : which has a range of DBL_MIN..DBL_MAX. : : Look at the code. : : long double a = DBL_MAX; : long double b = DBL_MAX * 2; : : The original posting said that b would be +Inf at this point, which is : not correct. I think that Bruce was confused there. The more correct : example to look at was the one that rittle@ posted which was 1 + : LDBL_EPSILON. : : I guess I must not be understanding. What will b be, at this point, : then? How can it have a value larger than DBL_MAX that's not +Inf? : : If it's possible to represent a value larger than DBL_MAX in a double, : then the value of DBL_MAX is wrong, right? Maximum means maximum, : doesn't it? *LONG*DOUBLE* is not *DOUBLE*. long double has extended precision and a range compared to double. That's how. To beat this dead horse some more: look at the code carefully. It was long double x= DBL_MAX; long double y = 2 * x; /* (1) */ This is quite different from the above, which (after renaming variables and changing the formatting to be bug for bug compatible) is: long double x= DBL_MAX; long double y = DBL_MAX * 2;/* (2) */ In (1), we have DBL_MAX in a long double, so we can expect to double it if long doubles are longer than doubles (whether they actually are is machine-dependent). In (2), we are doubling DBL_MAX as a double. The result of this is fuzzy, since the computation may be done in double precision or long double precision or perhaps something weirder. There will be no way to tell until C99 is implemented and perhaps not even then. gcc things that it is implementing C99's FLT_EVAL_METHOD of 0, which performs arithmetic on doubles in double precision, so the result of DBL_MAX * 2 is +Inf if the this is evaluated at compile time. gcc (gcc-3.2 on i386's) doesn't actually implement this, since the result is not +Inf if DBL_MAX * 2 is evaluated at runtime. Bruce To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
On Thu, 31 Oct 2002, Loren James Rittle wrote: In article [EMAIL PROTECTED], Bruce Evans[EMAIL PROTECTED] writes: When I run your program against gcc mainline (for 3.3 release) with the patch I have staged from RTH to correctly match our FP hardware default setup, I see: S rittle@latour; /usr/local/beta-gcc/bin/gcc t.c S rittle@latour; a.out LDBL_EPSILON failed test 2 with prec 3 S rittle@latour; /usr/local/beta-gcc/bin/gcc -O t.c S rittle@latour; a.out LDBL_EPSILON failed test 2 with prec 3 DBL_EPSILON failed test 2 with prec 3 S rittle@latour; /usr/local/beta-gcc/bin/gcc -O2 t.c S rittle@latour; a.out LDBL_EPSILON failed test 2 with prec 3 DBL_EPSILON failed test 2 with prec 3 S rittle@latour; /usr/local/beta-gcc/bin/gcc -O3 t.c S rittle@latour; a.out LDBL_EPSILON failed test 2 with prec 3 DBL_EPSILON failed test 2 with prec 3 I.e. the only time it fails is when the user made a call to change the default precision. Is that gcc 3.3 behavior acceptable (at least until gcc can be further refined to attempt to handle user override of the FP control word)? Yes, this is the correct behaviour IMO. I don't see how any user override of the control word (except possibly of the rounding mode) can be expected to work right outside of an FENV_ACCESS section. Constants like DBL_EPSILON presumably don't apply in such sections. Bruce To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
In message: [EMAIL PROTECTED] Bruce Evans [EMAIL PROTECTED] writes: : On Thu, 31 Oct 2002, M. Warner Losh wrote: : : In message: [EMAIL PROTECTED] : Terry Lambert [EMAIL PROTECTED] writes: : : M. Warner Losh wrote: : : : I await an explanation of how you can fit 2*DBL_MAX into a double, : : : which has a range of DBL_MIN..DBL_MAX. : : : : Look at the code. : : : : long double a = DBL_MAX; : : long double b = DBL_MAX * 2; : : : : The original posting said that b would be +Inf at this point, which is : : not correct. I think that Bruce was confused there. The more correct : : example to look at was the one that rittle@ posted which was 1 + : : LDBL_EPSILON. : : : : I guess I must not be understanding. What will b be, at this point, : : then? How can it have a value larger than DBL_MAX that's not +Inf? : : : : If it's possible to represent a value larger than DBL_MAX in a double, : : then the value of DBL_MAX is wrong, right? Maximum means maximum, : : doesn't it? : : *LONG*DOUBLE* is not *DOUBLE*. long double has extended precision and : a range compared to double. That's how. : : To beat this dead horse some more: look at the code carefully. It was : : long double x= DBL_MAX; : long double y = 2 * x; /* (1) */ : : This is quite different from the above, which (after renaming variables : and changing the formatting to be bug for bug compatible) is: : : long double x= DBL_MAX; : long double y = DBL_MAX * 2;/* (2) */ : : In (1), we have DBL_MAX in a long double, so we can expect to double it : if long doubles are longer than doubles (whether they actually are is : machine-dependent). Right, The first example will not be +inf if long doubles have a greater range than doubles. On our i386 implemenation, it does. : In (2), we are doubling DBL_MAX as a double. The result of this is : fuzzy, since the computation may be done in double precision or long : double precision or perhaps something weirder. There will be no way : to tell until C99 is implemented and perhaps not even then. gcc things : that it is implementing C99's FLT_EVAL_METHOD of 0, which performs : arithmetic on doubles in double precision, so the result of DBL_MAX * : 2 is +Inf if the this is evaluated at compile time. gcc (gcc-3.2 on : i386's) doesn't actually implement this, since the result is not +Inf : if DBL_MAX * 2 is evaluated at runtime. That's true, but that's also independed problem.. It is no different than unsigned long long int a = ~0UL; unsigned long long int b = a * 2; vs unsigned long long int a = ~0UL; unsigned long long int b = ~0UL * 2; In the first case, b is twice a. In the second, b is 1 less than a on two's compliment machines. I'd written 2.0L in my test code, and I think that it was originally that way. Warner To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
In message: [EMAIL PROTECTED] Bruce Evans [EMAIL PROTECTED] writes: : On Mon, 28 Oct 2002, M. Warner Losh wrote: : : In message: [EMAIL PROTECTED] : Loren James Rittle [EMAIL PROTECTED] writes: : : This works. I'm not sure why this isn't the default. It looks like : we have hacks in the local tree to do this, which is why I thought : that it worked great by default : : Better change FreeBSD to match the unhacked version :-). Better to change FreeBSD to do the right thing and give long doubles their full precision, unless there's some compelling reason not to do so. : : gcc 3.3 will support a framework in which such changes would be easy : : to convey at compile-time but, to my knowledge, there is no support : : yet to obtain e.g. the precision setting at run-time. I.e. float.h : : FreeBSD (on i386's) has fpgetprec() to get it and fpsetprec() to set it, : but these are nonstandard and won't become standard. They don't exist : on most or all non-i386's now, unlike fpget/setround() which will become : the standard feget/setround(). Is there some reason we can't just put them into the machine specific startup code like I've done with the tree. What is the issue? If the issue is that doubles then start to be computed at 64 bit precision of intermediate value, then isn't it a compiler issue of scheduling the precision of the floating point unit? It then would be the only entity to know what the proper precision is at any given time. Of course, that sounds like a hard problem to me, especially since the compiler might not know the state of the fp unit on entry to a given function call. Warner To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
On Wed, 30 Oct 2002, M. Warner Losh wrote: In message: [EMAIL PROTECTED] Bruce Evans [EMAIL PROTECTED] writes: : On Mon, 28 Oct 2002, M. Warner Losh wrote: : : In message: [EMAIL PROTECTED] : Loren James Rittle [EMAIL PROTECTED] writes: : : This works. I'm not sure why this isn't the default. It looks like : we have hacks in the local tree to do this, which is why I thought : that it worked great by default : : Better change FreeBSD to match the unhacked version :-). Better to change FreeBSD to do the right thing and give long doubles their full precision, unless there's some compelling reason not to do so. The reasons are the same as they used to be: incomplete language support and incomplete library support. Language support is being completed but is far from here yet. See the paper referenced in Loren's reply for more details than anyone should want to know. : : gcc 3.3 will support a framework in which such changes would be easy : : to convey at compile-time but, to my knowledge, there is no support : : yet to obtain e.g. the precision setting at run-time. I.e. float.h : : FreeBSD (on i386's) has fpgetprec() to get it and fpsetprec() to set it, : but these are nonstandard and won't become standard. They don't exist : on most or all non-i386's now, unlike fpget/setround() which will become : the standard feget/setround(). Is there some reason we can't just put them into the machine specific startup code like I've done with the tree. Putting them there would just blow away the kernel default. There are arguments for putting the in both places, but not at the same time. Linux seems to have gone the other way and move the initialization from crt to the kernel. I'm not sure what happened to moves to set the Linux default for Linux applications in the kernel. What is the issue? If the issue is that doubles then start to be computed at 64 bit precision of intermediate value, then isn't it a compiler issue of scheduling the precision of the floating point unit? It then would be the only entity to know what the proper precision is at any given time. Of course, that sounds like a hard problem to me, especially since the compiler might not know the state of the fp unit on entry to a given function call. C99 encourages having a behaviour that is known at compile time and telling applications about it in FLT_EVAL_METHOD (this can be set to -1 == indeterminable, but that would not be very useful although it is the only correct setting now). The compiler should implement the system implementor's choice or enforce its own choice. gcc doesn't really understand this this. gcc-3.2 thinks that it implementing method 0 (no extension of precision) but the npx hardware is nothing like that. The compiler doesn't have any special problems knowing the state of the precision control on entry to functions. It just needs the initial value to be set correctly and the state to not change underneath it like it already requires for other aspects of the state. Changing the state using fpset*() counts as changing the state underneath it here. Bruce To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
In message: [EMAIL PROTECTED] Bruce Evans [EMAIL PROTECTED] writes: : The reasons are the same as they used to be: incomplete language support : and incomplete library support. Language support is being completed but : is far from here yet. See the paper referenced in Loren's reply for more : details than anyone should want to know. OK. I'll have to go back and find that reference. I'd really like to change the __INITIAL_NPXCW__ from 0x127f to 0x137f in npx.h. I think that we can get the library support in place over time, as this already is a bullet item in the standards todo list web page. The gcc 3.2 compiler does a decent, but not perfect, job of dealing with the floating point stuff. I'll have to dive into the archive to find said paper. : : : gcc 3.3 will support a framework in which such changes would be easy : : : to convey at compile-time but, to my knowledge, there is no support : : : yet to obtain e.g. the precision setting at run-time. I.e. float.h : : : : FreeBSD (on i386's) has fpgetprec() to get it and fpsetprec() to set it, : : but these are nonstandard and won't become standard. They don't exist : : on most or all non-i386's now, unlike fpget/setround() which will become : : the standard feget/setround(). : : Is there some reason we can't just put them into the machine specific : startup code like I've done with the tree. : : Putting them there would just blow away the kernel default. There are : arguments for putting the in both places, but not at the same time. : Linux seems to have gone the other way and move the initialization : from crt to the kernel. I'm not sure what happened to moves to set the : Linux default for Linux applications in the kernel. Yea, putting it in crt is bogus. Forget I suggested it. : C99 encourages having a behaviour that is known at compile time and : telling applications about it in FLT_EVAL_METHOD (this can be set to : -1 == indeterminable, but that would not be very useful although it : is the only correct setting now). The compiler should implement the : system implementor's choice or enforce its own choice. gcc doesn't : really understand this this. gcc-3.2 thinks that it implementing : method 0 (no extension of precision) but the npx hardware is nothing : like that. I don't understand this completely. ARe you saying that gcc is doing something worng? : The compiler doesn't have any special problems knowing the state of : the precision control on entry to functions. It just needs the initial : value to be set correctly and the state to not change underneath it : like it already requires for other aspects of the state. Changing the : state using fpset*() counts as changing the state underneath it here. I do understand this, which is why changing the defaults seems reasonable to me. BTW, NetBSD is kinda schizophrenic about this: /* * The i387 defaults to Intel extended precision mode and round to nearest, * with all exceptions masked. */ #define __INITIAL_NPXCW__ 0x037f /* NetBSD uses IEEE double precision. */ #define __NetBSD_NPXCW__0x127f /* FreeBSD leaves some exceptions unmasked as well. */ #define __FreeBSD_NPXCW__ 0x1272 /* iBCS2 goes a bit further and leaves the underflow exception unmasked. */ #define __iBCS2_NPXCW__ 0x0262 /* Linux just uses the default control word. */ #define __Linux_NPXCW__ 0x037f /* SVR4 uses the same control word as iBCS2. */ #define __SVR4_NPXCW__ 0x0262 So their float.h values are correct only for Linux binaries and emulation. Also, it looks like FreeBSD_NPXCW is incorrect, since we have: #define __INITIAL_NPXCW__ 0x127F And there's a comment: * 64-bit precision often gives bad results with high level languages * because it makes the results of calculations depend on whether * intermediate values are stored in memory or in FPU registers. which seems like a compiler issue, not an OS issue to me. Warner To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
M. Warner Losh wrote: And there's a comment: * 64-bit precision often gives bad results with high level languages * because it makes the results of calculations depend on whether * intermediate values are stored in memory or in FPU registers. which seems like a compiler issue, not an OS issue to me. The compiler must emit instructions to truncate and set flags, as well as generating pseudo-exceptions (should they be called for) in the case that the storage is in registers bigger than the memory backing them. IT doesn't do this. This is the basis of Bruce's complaint: http://docs.freebsd.org/cgi/getmsg.cgi?fetch=1099099+0+archive/2002/freebsd-current/20021027.freebsd-current | gcc can't actually support the full range, since it doesn't control | the runtime environement (it could issue a fninit before main() to | change the default, but it shouldn't and doesn't). The exponent | range is lost long before printf() is reached. E.g., | | long double x= DBL_MAX; | long double y = 2 * x; | | gives +Inf for y since the result is doesn't fit in 53-bit precision. | The system header correctly reports this default precision. Any header | genrated by the gcc build should be no different, since the build should | run in the target environment. -- Terry To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
In message: [EMAIL PROTECTED] Terry Lambert [EMAIL PROTECTED] writes: : M. Warner Losh wrote: : And there's a comment: : * 64-bit precision often gives bad results with high level languages : * because it makes the results of calculations depend on whether : * intermediate values are stored in memory or in FPU registers. : which seems like a compiler issue, not an OS issue to me. : : The compiler must emit instructions to truncate and set flags, as : well as generating pseudo-exceptions (should they be called for) : in the case that the storage is in registers bigger than the memory : backing them. IT doesn't do this. I think I don't understand what you are saying at all. It doesn't seem top jive with the rest of the messages in this thread. : This is the basis of Bruce's complaint: : : :http://docs.freebsd.org/cgi/getmsg.cgi?fetch=1099099+0+archive/2002/freebsd-current/20021027.freebsd-current : : | gcc can't actually support the full range, since it doesn't control : | the runtime environement (it could issue a fninit before main() to : | change the default, but it shouldn't and doesn't). The exponent : | range is lost long before printf() is reached. E.g., : | : | long double x= DBL_MAX; : | long double y = 2 * x; : | : | gives +Inf for y since the result is doesn't fit in 53-bit precision. : | The system header correctly reports this default precision. Any header : | genrated by the gcc build should be no different, since the build should : | run in the target environment. Except that's wrong, and further messages in the thread showed. This example shows that we don't support it in printf, since the above example does ***NOT*** give +Inf, but rather whatever 2*DBL_MAX is. The exponent range is ***NOT*** lost until printf truncates it, as my test programs showed. The one issue that I've seen is long double a = 1.0L; long double b = 1.0L + LDBL_EPSION if (a == b) abort(); which is what I'm trying to fix. (note, 1.0L must be spelled oneld() and long double oneld() { return (1.0L);}) to avoid the optimizer getting it right. Warner To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
On Wed, 30 Oct 2002 17:01:54 -0700 (MST), M. Warner Losh [EMAIL PROTECTED] said: I think I don't understand what you are saying at all. It doesn't seem top jive with the rest of the messages in this thread. Of course not, it's Terry ``Irrelevant Tangent'' Lambert you're taking about. -GAWollman To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
On Wed, 30 Oct 2002 20:29:16 -0500 (EST), Garrett Wollman [EMAIL PROTECTED] said: [rude snipe deleted...] Sorry, that was un-called-for (and was intended to be a private message to Warner). -GAWollman To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
M. Warner Losh wrote: : The compiler must emit instructions to truncate and set flags, as : well as generating pseudo-exceptions (should they be called for) : in the case that the storage is in registers bigger than the memory : backing them. IT doesn't do this. I think I don't understand what you are saying at all. It doesn't seem top jive with the rest of the messages in this thread. I mean that if there is a difference between doing the math in registers vs. doing it in memory (or storing it in memory and pulling it back in the registers, then you have two options: 1) Don't late-bind the FPU registers in the kernel, and take a huge performance hit 2) Have the compiler generate code that will give the same results as if the store and load had taken place The gcc people argue that it's the kernel's job (do #1, not #2), and the kernel argues that it's the compilers job (do #2, not #1). Except that's wrong, and further messages in the thread showed. I didn't see a printf involved; Bruce was talking, as far as I could tell, about a direct compare, with no printf() involved. Are you maybe mixing this up with the paranoia tests? The problem is that the double didn't give +Inf, like it should have, because the rvalue was incorrectly promoted to long double, instead of staying double, and overflowing (Bruce? Correct this if it's wrong, please). This example shows that we don't support it in printf, since the above example does ***NOT*** give +Inf, but rather whatever 2*DBL_MAX is. That would be +Inf for double values... a 53 bit +Inf. But since it's being improperly treated as a 64 bit value, you don't get +Inf when you *should*. I think this case is about *not* getting an error you should get. The exponent range is ***NOT*** lost until printf truncates it, as my test programs showed. Exactly! And it *should* be, because a double *is not* the same precision as a *long double*. A validation suite that tested edge conditions to ensure that there was a precision failure where there was supposed to be, and didn't get an expected failure, would mean it's broken. The one issue that I've seen is long double a = 1.0L; long double b = 1.0L + LDBL_EPSION if (a == b) abort(); which is what I'm trying to fix. (note, 1.0L must be spelled oneld() and long double oneld() { return (1.0L);}) to avoid the optimizer getting it right. Heh. I saw that discussion; I think that's seperate. The main issue that I think is outstanding is that you can't get both exception behaviour and non-exception behaviour, and it is going to have to be the compiler's job to force the issue, because it can't dictate implementaiton to the host OS. One problem is the initialization of the hardware (there was already a flags change for an initialization difference from what the compiler expects suggested in this thread -- to my mind, it's a workaround for the gcc generating header files, instead of taking the system's word for it). -- Terry To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
In message: [EMAIL PROTECTED] Terry Lambert [EMAIL PROTECTED] writes: : This : example shows that we don't support it in printf, since the above : example does ***NOT*** give +Inf, but rather whatever 2*DBL_MAX is. : : That would be +Inf for double values... a 53 bit +Inf. But : since it's being improperly treated as a 64 bit value, you don't : get +Inf when you *should*. I think this case is about *not* : getting an error you should get. Terry you are wrong. This has to do with the RANGE not the PRECISION of the floating point number. It is ***NOT*** +Inf. : The exponent range is ***NOT*** lost until printf truncates it, as my : test programs showed. : : Exactly! And it *should* be, because a double *is not* the same : precision as a *long double*. A validation suite that tested edge : conditions to ensure that there was a precision failure where there : was supposed to be, and didn't get an expected failure, would mean : it's broken. You are wrong. You are confusing the precision of the mantissa with the range of the exponent. Printf should *NOT* truncate to double before converting to print. That's a bug too. : The one issue that I've seen is : : long double a = 1.0L; : long double b = 1.0L + LDBL_EPSION : if (a == b) abort(); : : which is what I'm trying to fix. (note, 1.0L must be spelled : oneld() and long double oneld() { return (1.0L);}) to avoid the : optimizer getting it right. : : Heh. I saw that discussion; I think that's seperate. Yes. : The main issue that I think is outstanding is that you can't get : both exception behaviour and non-exception behaviour, and it is : going to have to be the compiler's job to force the issue, because : it can't dictate implementaiton to the host OS. I don't follow. : One problem is the initialization of the hardware (there was already : a flags change for an initialization difference from what the compiler : expects suggested in this thread -- to my mind, it's a workaround for : the gcc generating header files, instead of taking the system's word : for it). I don't follow. Warner To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
M. Warner Losh wrote: : This : example shows that we don't support it in printf, since the above : example does ***NOT*** give +Inf, but rather whatever 2*DBL_MAX is. [ ... ] Terry you are wrong. This has to do with the RANGE not the PRECISION of the floating point number. It is ***NOT*** +Inf. I await an explanation of how you can fit 2*DBL_MAX into a double, which has a range of DBL_MIN..DBL_MAX. You are wrong. You are confusing the precision of the mantissa with the range of the exponent. I'm talking about the range of the double itself. When you round it, you don't jsut truncate the bits off the mantissa, you also increase the exponent. Printf should *NOT* truncate to double before converting to print. That's a bug too. I agree with the printf statement, but I don't see where printf is coing into the discussion. Yes. : The main issue that I think is outstanding is that you can't get : both exception behaviour and non-exception behaviour, and it is : going to have to be the compiler's job to force the issue, because : it can't dictate implementaiton to the host OS. I don't follow. I think that a number that's a 64 bit mantissa reaised to an exponent N takes a larger N if you have only 53 bits of mantissa, if you want to represent the same value. : One problem is the initialization of the hardware (there was already : a flags change for an initialization difference from what the compiler : expects suggested in this thread -- to my mind, it's a workaround for : the gcc generating header files, instead of taking the system's word : for it). I don't follow. The obvious example in the FreeBSD case is the default value of the expression (fpgetprec() == FP_PE). The compiler is not permitted to assume, one way or the other; it has to do runtime testing, at the time you compile the compiler, to comply with a completely strict interpretation of C99 (IMO). It would have been nice if C99 provided a way to list the host defaults for use in compiling the compiler, since the host and the compiler have to cooperate, but there's no way to do this at run time because the standard failed to assign responsibility totally to the compiler vendor or totally to host OS. The closest possible approach will be for the compilation of the compiler to make some runtime tests to find out about the host environment. Really, it comes down to whether the host, or the compiler, owns math.h and float.h. According to my reading of C99, ownership is split between them. This kind of implies that the compiler gets to generate them however it wants, but that the host gets to dictate operation to the compiler, based on runtime tests the compiler is required to run to get the information. Since gcc supplies the crt0, it could always call fpsetprec(FP_PE); before starting to force the hardware into the compiler's preferred state. That's one answer, which makes it really hard to have a gcc and a TenDRA compiler that give the same results, if they happen to pick different defaults. The FP-using code would have to take all this into account, and be prepared to deal with all the possible allowed values. One workaround to this really ugly situation would be to define a host specific header file that's included by a host independent math.h and float.h to control its behaviour on a per-host basis, and then expect the host OS vendor to provide it, or the compiler to dig it out itself. It's better for the vendor to provide it, if the vendor wants any say in the matter at all (i.e. if the crt0 is going to call fpsetprec() to force the initial state, then why would the OS define an initial state that wasn't what the compiler wanted, so it could skip the set call?, etc.). -- Terry To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support (was Re: libstdc++ does notcontain fabsl symbol)
Claiming 53 bits but supporting 64, and then not raising an exception and/or giving a NaN or INF result on overflow to the 54th bit is broken. If you do this, you will fail runtime validation suites. Huh? The 53-bit quantity refers to the mantissa not the exponent. Unless I'm sorely confused, the only IEEE exceptions you could be speaking about is inexact; Inf and NaN don't come into play. In any event: As I outlined, in this case (where we advertised 53-bit precision but the user forced 64-bit precision - it was not precise for you to use the word supporting since that does not characterize the situation I was speaking about properly), the user will have explicitly made a call to change the default precision as conveyed in the system header. At that point, I don't know why the user should be able to expect that the published values in float.h are still valid. Do these validation suites typically run with a call to override the precision setting in the IEEE FP control word? Doubtful (or if they do, they know what they are doing; just as application code that monkeys with the control register would have to). I.e. the test suite would be running against the published limits.h which at the moment should be: #define LDBL_MANT_DIG53 #define LDBL_MIN_EXP (-16381) #define LDBL_MAX_EXP 16384 (All other published LDBL_ constants are derivable from these.) since they match the default FP control word setting on FreeBSD/i386. I don't think that any amount of hand-waving will turn it into a compiler-only issue. I am not trying to handwave anything. The currently published float.h (both before and after recent patch) is what is attempting to handwave something. It doesn't match the hardware settings. That patch it just received fixed one thing (exponent range) but broke another (precision/epsilon). More than anything, I am attempting to have that file written exactly to match the default hardware setup. Since there is exactly one default hardware setup for any particular booted system, it seems possible to do. If I were doing what is claimed, I would have fixed the issue in gcc mainline without consulting FreeBSD-side experts. Perhaps we should just leave it broken in the FSF tree and let an expert sort it out when they import gcc 3.3 into FreeBSD. However, it seemed reasonable to me to fix the issues exposed by the gcc infrastructure change ASAP... I'd like to see Bruce's issues with the 64 bit support taken care of with long double (and the implicit cast that occurs in the one case that Bruce complained about in his email, where there is *too much* precision on the rvalue, which is a computation of dobule operands done in long double form, with a double result). I think I now understand Bruce's point. There are two issues: (a) incorrect double-rounding (once to the precision of extended double in register and another to double when moved to memory allocated for double); (b) non-exact comparisons where might otherwise be expected by programmers even if not absolutely guaranteed by IEEE 754. To anyone that wishes to understand it, start reading page 249 of this version of _What Every Computer Scientist Should Know About Floating-Point Arithmetic_ http://www.validlab.com/goldberg/paper.ps FYI, by default, FreeBSD/i386 uses technique 4 on page 260 to circumvent these issues. (There is a proof earlier that fully explains why double-rounding doesn't affect double-float conversions on i386.) Now, in case anyone cares, gcc 3.3 will expose the C99 FLT_EVAL_METHOD macro (set to 2 for FreeBSD/i386) and related float_t and double_t types (which will both map to long double to represent the destination of intermediate results otherwise beyond the user's control). Given the extended range of the exponent of a double or float in an i386 HW FP register; I believe that is correct. Regards, Loren To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
In article [EMAIL PROTECTED] imp writes: This works. I'm not sure why this isn't the default. It looks like we have hacks in the local tree to do this, which is why I thought that it worked great by default This is true too. See the fpsetprec() call that I had to add to make things work above. Yes, I know about that call. I conditionally added it to at least one gcc i386 FP test case that assumed 64-bit precision. However, the system header float.h is suppose to reveal the FP hardware as it is configured not as some user could litter their code to make it so, no? Yes. The standard didn't anticipate the fp hardware that intel made. C89, perhaps (although given the timing, I'm skeptical). C99, no way. One could do something like: #define LDBL_EPSILON (fpgetprec() == FP_PE ? _LDBL_EPSILON : DBL_EPSILON) But as you said, this isn't a compile time constant. I'm not sure that it would matter in any real context. I don't think that you can do floating point in the preprocessor... This proposal isn't bad IMHO. It would clearly explain to the gcc team what type of FP support we'd want even if not in full compliance with the standard text. And, to avoid all compliance problems, perhaps: #if !defined(_ANSI_SOURCE) !defined(_POSIX_SOURCE) !defined(__STRICT_ANSI__) // for i386, match default as expressed in __INITIAL_NPXCW__ #define LDBL_MANT_DIG 53 #define LDBL_EPSILON 2.2204460492503131E-16 [...] // changing LDBL_MANT_DIG subtly changes every value not just LDBL_EPSILON) #else // Assume something would have to be done to avoid including ieeefp.h #define LDBL_MANT_DIG (fpgetprec() == FP_PE ? _LDBL_MANT_DIG : DBL_MANT_DIG) #define LDBL_EPSILON (fpgetprec() == FP_PE ? _LDBL_EPSILON : DBL_EPSILON) [...] #endif To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
On Mon, 28 Oct 2002, M. Warner Losh wrote: In message: [EMAIL PROTECTED] Loren James Rittle [EMAIL PROTECTED] writes: This works. I'm not sure why this isn't the default. It looks like we have hacks in the local tree to do this, which is why I thought that it worked great by default Better change FreeBSD to match the unhacked version :-). : gcc 3.3 will support a framework in which such changes would be easy : to convey at compile-time but, to my knowledge, there is no support : yet to obtain e.g. the precision setting at run-time. I.e. float.h FreeBSD (on i386's) has fpgetprec() to get it and fpsetprec() to set it, but these are nonstandard and won't become standard. They don't exist on most or all non-i386's now, unlike fpget/setround() which will become the standard feget/setround(). : is now completely dynamically created at compile-time based on the : exact knowledge within gcc of the FP hardware; but it is static : w.r.t. eventual run-time. It does not know how to effectively export : a function ala FreeBSD/alpha's float.h: : : #define FLT_ROUNDS __flt_rounds() I hope an alpha person will explain the details of this. Where is the default configured? : One issue, the standard says that various macros related to float : limits are constant expressions (as may be used to influence the : preprocessor?). The above construct doesn't conform but I understand : the intent. The standard has a special exception for FLT_ROUNDS. Yes. The standard didn't anticipate the fp hardware that intel made. Actually, it didn't support the hardware. The hardware was implemented long before the (C) standard. One could do something like: #define LDBL_EPSILON (fpgetprec() == FP_PE ? _LDBL_EPSILON : DBL_EPSILON) But as you said, this isn't a compile time constant. I'm not sure The standard doesn't have a special exception for anything in float.h except FLT_ROUNDS :-. that it would matter in any real context. I don't think that you can do floating point in the preprocessor... Not in non-broken preprocessors. Bruce To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support (was Re: libstdc++ does notcontain fabsl symbol)
In article [EMAIL PROTECTED], Bruce Evans[EMAIL PROTECTED] writes: If you really want, I can tell RTH that FreeBSD/i386 absolutely wants `long double' to be: 53 mantissa bits 1024 max exponent No need. I prefer to keep the 53-bit precision for now, but fix the exponents. OK. This was the resolution that made sense to us on the gcc side (RTH, quickly; myself, some time to get up to speed). FYI, the system header patch that was actually checked in claims 64-bit precision. Oh well, at least the exponents are now correct. ;-) FYI, here is the exact test case which shows the new value for LDBL_EPSILON (derived directly from LDBL_MANT_DIG) is wrong verses the hardware default: #include float.h // Force run-time computation of math (beware, inlining oneld will defeat this). long double oneld() { return 1.0L; } main () { long double a = oneld(); long double b = oneld() + LDBL_EPSILON; if (a == b) abort (); } On ref5 against gcc 3.2.X (as installed as system compiler), with the latest float.h, it crashes. By specification, this is one FP test involving exact equality that is guaranteed to work (and report false, in this case). Hopefully the precision won't be hard-coded into gcc in such a way as to completely break changing the precision at runtime. I think it should affect (only) constant folding. The issues are very similar to the ones with changing the rounding mode at runtime (C99 compilers shouldn't do constant folding in #pragma STDC FENV_ACCESS ON sections if the correct result might depend on the FP environment). This exchange has been quite useful. I see that issue. Unfortunately, changing precision of the FP hardware would seem to change the value of epsilon that is exported, both in classic C headers and C++ limits (the latter being how I originally took any interest in this matter since a C++ test case started failing after the new real.c code was installed). gcc 3.3 will support a framework in which such changes would be easy to convey at compile-time but, to my knowledge, there is no support yet to obtain e.g. the precision setting at run-time. I.e. float.h is now completely dynamically created at compile-time based on the exact knowledge within gcc of the FP hardware; but it is static w.r.t. eventual run-time. It does not know how to effectively export a function ala FreeBSD/alpha's float.h: #define FLT_ROUNDS __flt_rounds() One issue, the standard says that various macros related to float limits are constant expressions (as may be used to influence the preprocessor?). The above construct doesn't conform but I understand the intent. I will advise RTH about that type of issue. Fortunately, in this case, I think advertising 53-bit precision but really using 64-bit precision (i.e. application code overrode system default) doesn't invalidate the advertised epsilon, in terms of how it is used by the application. More generally, I will ask if gcc can support these details as gained from the run-time environment instead of hard-coded defaults. This would be useful for all free OSes not just FreeBSD running on hardware with such flexible FP hardware. Any more comments, before I start work on the gcc mainline side of things? Thanks, Loren To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support (was Re: libstdc++ does notcontain fabsl symbol)
Loren James Rittle wrote: I will advise RTH about that type of issue. Fortunately, in this case, I think advertising 53-bit precision but really using 64-bit precision (i.e. application code overrode system default) doesn't invalidate the advertised epsilon, in terms of how it is used by the application. More generally, I will ask if gcc can support these details as gained from the run-time environment instead of hard-coded defaults. This would be useful for all free OSes not just FreeBSD running on hardware with such flexible FP hardware. Any more comments, before I start work on the gcc mainline side of things? Claiming 53 bits but supporting 64, and then not raising an exception and/or giving a NaN or INF result on overflow to the 54th bit is broken. If you do this, you will fail runtime validation suites. The C99 standard intentionall gets its information from float.h ... rather than it's float.h from the information, as you are doing ... because this is a combination host OS *and* compiler issue. I don't think that any amount of hand-waving will turn it into a compiler-only issue. I'd like to see Bruce's issues with the 64 bit support taken care of with long double (and the implicit cast that occurs in the one case that Bruce complained about in his email, where there is *too much* precision on the rvalue, which is a computation of dobule operands done in long double form, with a double result). -- Terry To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
In message: [EMAIL PROTECTED] Terry Lambert [EMAIL PROTECTED] writes: : I'd like to see Bruce's issues with the 64 bit support taken care : of with long double (and the implicit cast that occurs in the one : case that Bruce complained about in his email, where there is *too : much* precision on the rvalue, which is a computation of dobule : operands done in long double form, with a double result). I'd like to see these fixed too. Now that I understand why I was deluded into thinking that he was mistaken, I'd like to get these issues resolved. Warner To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
Thus spake M. Warner Losh [EMAIL PROTECTED]: : No. You should assume that for i386, at least, that long double will : have the right LDBL_ constants. I've had them in my local tree for : about 3 months now and just haven't found the time to commit to : -current. I'll find the time right now. I've committed the fix to the tree. NetBSD uses these numbers, and I've been using these numbers on a large number of systems that we maintain at timing solutions (they were added to our local tree prior to the 4.5 release, and we've built hundreds of ports since then w/o any issues). I've had them in my own personal p4 tree for 3 months with similar results. I submitted patches for this back in May. Could you please close i386/38288? While you're at it, you should probably patch IA64 as well. Other supported platforms should be okay, I think. TIA. (Every time this happens, someone comes along a month later and tells me that _I'm_wrong_ about there ever being a bug.) To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
In message: [EMAIL PROTECTED] David Schultz [EMAIL PROTECTED] writes: : Thus spake M. Warner Losh [EMAIL PROTECTED]: : : No. You should assume that for i386, at least, that long double will : : have the right LDBL_ constants. I've had them in my local tree for : : about 3 months now and just haven't found the time to commit to : : -current. I'll find the time right now. : : I've committed the fix to the tree. NetBSD uses these numbers, and : I've been using these numbers on a large number of systems that we : maintain at timing solutions (they were added to our local tree prior : to the 4.5 release, and we've built hundreds of ports since then w/o : any issues). I've had them in my own personal p4 tree for 3 months : with similar results. : : I submitted patches for this back in May. Could you please close : i386/38288? While you're at it, you should probably patch IA64 as : well. Other supported platforms should be okay, I think. TIA. : : (Every time this happens, someone comes along a month later and : tells me that _I'm_wrong_ about there ever being a bug.) If I hadn't been using long doubles, day in and day our, for the past two years, I'd likely have agreed with you. However, I've had to look into why weird things happen with long doubles a lot, and have found in general they work pretty good. I'll ask Peter Wemm about IA64. Warner To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
In message: [EMAIL PROTECTED] Loren James Rittle [EMAIL PROTECTED] writes: : Yet, the FP hardware is actually configured by default to provide : `long double' as: : : #define LDBL_MANT_DIG 53 : #define LDBL_MIN_EXP(-16381) : #define LDBL_MAX_EXP16384 : : Indeed, FP code using long double generated by gcc 2.95.X, installed : as the FreeBSD 4 system compiler, uses the full exponent range of : -16381 to 16384. However, printf(), etc loses on that exponent range : and reports Inf. I suspect this is why the system header misreports : the FP hardware, thus the header describes the largest printable long : double value, not the largest that could be held in a calculation. I have patches to fix these constants, but not to fix printf, and co, to really support the full precision of long double. Even NetBSD doesn't do that. : Anyways, two questions for FreeBSD maintainers. How should gcc, as : provided from the FSF, describe the long double FP format for : FreeBSD/i386 4.x? Shall we assume that no changes for FreeBSD 5.x : will occur? No. You should assume that for i386, at least, that long double will have the right LDBL_ constants. I've had them in my local tree for about 3 months now and just haven't found the time to commit to -current. I'll find the time right now. Warner To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
In message: [EMAIL PROTECTED] M. Warner Losh [EMAIL PROTECTED] writes: : : Anyways, two questions for FreeBSD maintainers. How should gcc, as : : provided from the FSF, describe the long double FP format for : : FreeBSD/i386 4.x? Shall we assume that no changes for FreeBSD 5.x : : will occur? : : No. You should assume that for i386, at least, that long double will : have the right LDBL_ constants. I've had them in my local tree for : about 3 months now and just haven't found the time to commit to : -current. I'll find the time right now. I've committed the fix to the tree. NetBSD uses these numbers, and I've been using these numbers on a large number of systems that we maintain at timing solutions (they were added to our local tree prior to the 4.5 release, and we've built hundreds of ports since then w/o any issues). I've had them in my own personal p4 tree for 3 months with similar results. Warner To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support (was Re: libstdc++ does notcontain fabsl symbol)
On Thu, 24 Oct 2002, Loren James Rittle wrote: ... Anyways, that work exposed some issues. ... It is easy to generate, with arithmetic, a long double value outside the *exponent* range above no matter how the precision is set; it is not truncated to Inf until it is actually cast to a double (as is currently done just before a long double is printed with stdio). See below for a program that demonstrates this behavior. Yet, the FP hardware is actually configured by default to provide `long double' as: #define LDBL_MANT_DIG 53 I think you mean 64 (the hardware default). No sir, I did mean as configured in the system startup code, it is forced to 53-bits (that choice affects long double as well as double). But there are no IEEE control bits to limit the size of the exponent field, are there? Thus, the following describes the exact size of the HW's exponent field of a long double as configured by default: #define LDBL_MIN_EXP(-16381) #define LDBL_MAX_EXP16384 gcc can't actually support the full range, since it doesn't control the runtime environement (it could issue a fninit before main() to change the default, but it shouldn't and doesn't). The exponent range is lost long before printf() is reached. E.g., long double x= DBL_MAX; long double y = 2 * x; gives +Inf for y since the result is doesn't fit in 53-bit precision. As you know, the selection of maximum precision is orthogonal to the number of bits used for the exponent. I do wish you were correct. Have you looked at the raw memory of y? It is *not* the bit pattern for +Inf. If y were +Inf, then based on the properties of IEEE math, the following would report Inf not DBL_MAX/2: Oops. I did look at the bits, but I looked more closely at gdb's display of the value which is broken (it says +inf). Apparently gdb uses the host's FP too much. #include float.h int main (void) { long double x= LDBL_MAX; // Same as DBL_MAX in current float.h long double y = 2e100 * x; // If LDBL_MAX was correct, we should latch Inf. long double z = y / 4e100; printf (%Lg\n, z); } It does, in fact, report DBL_MAX/2 with the system compiler on FreeBSD 4. FYI, I reviewed the generated code to ensure it was using run-time calculations not compile-time calculations. I'd call that a rather easy time getting a normalized long double much larger than LDBL_MAX/DBL_MAX. This test alone proves in my mind that the float.h system header for i386 is itself wrong. Yes, this example is as convincing as examining the (right :) bits. The system header correctly reports this default precision. Any header genrated by the gcc build should be no different, since the build should run in the target environment. I agree that the precision setting in the system header is fine. The size of the exponent field is buggy. I held the opinion you have but while trying to convince RTH (the guy that rewrote gcc FP support), I did enough research that also leads me to think that it is the header itself which is buggy. If you really want, I can tell RTH that FreeBSD/i386 absolutely wants `long double' to be: 53 mantissa bits 1024 max exponent No need. I prefer to keep the 53-bit precision for now, but fix the exponents. Hopefully the precision won't be hard-coded into gcc in such a way as to completely break changing the precision at runtime. I think it should affect (only) constant folding. The issues are very similar to the ones with changing the rounding mode at runtime (C99 compilers shouldn't do constant folding in #pragma STDC FENV_ACCESS ON sections if the correct result might depend on the FP environment). It should use whatever is the default format for the host environment, It still has enquire.c for doing this automatically. [...] I fear I didn't explain clearly enough. enquire.c is completely *gone* in gcc 3.3. This is why gcc needs to fully understand the exact FP default configuration. As you noted, enquire.c was buggy. Ah. I was a little surprised to find it still in 3.2. It is not so much buggy as dysfunctional in a cross compiler. It has to run on the target somehow to work. Bruce To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support
On Fri, 25 Oct 2002, M. Warner Losh wrote: In message: [EMAIL PROTECTED] Bruce Evans [EMAIL PROTECTED] writes: : On Thu, 24 Oct 2002, Loren James Rittle wrote: : : ... Anyways, that work exposed some issues. : : We have this in the system header: : : #define LDBL_MANT_DIG DBL_MANT_DIG : #define LDBL_MIN_EXPDBL_MIN_EXP : #define LDBL_MAX_EXPDBL_MAX_EXP : [...] : : This seems to be correct. Long double precision is not really supported : either at complie time or runtime. The default precision (on i386's) : is 53 bits, so (normalized) long doubles have a hard time getting any : larger than DBL_MAX or any smaller than DBL_MIN (you can create them : as bits or using a hardware transcendental function, but any arithmetic : on them will convert them to double precision). That is incorrect. long double are supported at runtime. We use them all the time and do get numbers outside the range of normal doubles. There are some minor rounding issues with them, but those issues result in a 1-2 bit rounding error in most of the cases I've looked at in extreme detail. Such rounding errors do limit the effective range to about 62 bits, but that's still a lot better than 53 bits you get with doubles. Um, you get the FreeBSD default of 53 bits on i386's unless you change the FP environment using fesetprec(3) or equivalent. This thread highlighted the point that you get a larger exponent range even with 53-bit precision. : gcc can't actually support the full range, since it doesn't control : the runtime environement (it could issue a fninit before main() to : change the default, but it shouldn't and doesn't). The exponent : range is lost long before printf() is reached. E.g., : : long double x= DBL_MAX; : long double y = 2 * x; : : gives +Inf for y since the result is doesn't fit in 53-bit precision. : The system header correctly reports this default precision. Any header : genrated by the gcc build should be no different, since the build should : run in the target environment. that's not true. y is not +Inf, but prints as +Inf because printf and friends do not support outside the range of a double. Oops (see another reply). : Not really. Assembly is still required to get full control over precision. : I'm still waiting for (C) language support to catch up. Been waiting for : about 14 years so far. C99 clarified the semantics of floating point : precision but is not supported by gcc (yet?). This is not true. No oops. gcc has no support for the C99 FENV_ACCESS stuff and still doesn't clip excess precision on assignment. These are easy to implement ... provided efficiency is not required. Bruce To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Lack of real long double support (was Re: libstdc++ does not contain fabsl symbol)
Note that while you're adding the C99 math stuff, you might want to fix up float.h, which is just wrong about long doubles (see PR i386/38288). Right, I should have said no one has started committing C99 math functions. (Reading this exchange reminded me that I promised fellow gcc developers to check on this issue with FreeBSD developers.) The gcc mainline (what will become 3.3) recently got a new implementation of ``software floating point emulation'' (contained in gcc/real.[hc] which is used to format all compile-time FP constants, etc). Along with that change, the compiler wants to provide a copy of float.h generated from its own knowledge of FP hardware instead of sucking information from /usr/include/float.h, as it had done in past gcc releases. I know that when we install gcc as the FreeBSD system compiler, we don't bother with such header files provided from gcc (but, for the moment please consider that people might build cross-compilers to FreeBSD and please consider that we test future releases of gcc as might be used as the FreeBSD system compiler from FSF sources). Anyways, that work exposed some issues. We have this in the system header: #define LDBL_MANT_DIG DBL_MANT_DIG #define LDBL_MIN_EXPDBL_MIN_EXP #define LDBL_MAX_EXPDBL_MAX_EXP [...] Yet, the FP hardware is actually configured by default to provide `long double' as: #define LDBL_MANT_DIG 53 #define LDBL_MIN_EXP(-16381) #define LDBL_MAX_EXP16384 Indeed, FP code using long double generated by gcc 2.95.X, installed as the FreeBSD 4 system compiler, uses the full exponent range of -16381 to 16384. However, printf(), etc loses on that exponent range and reports Inf. I suspect this is why the system header misreports the FP hardware, thus the header describes the largest printable long double value, not the largest that could be held in a calculation. Anyways, two questions for FreeBSD maintainers. How should gcc, as provided from the FSF, describe the long double FP format for FreeBSD/i386 4.x? Shall we assume that no changes for FreeBSD 5.x will occur? Unless someone strongly prefers otherwise, the I lean towards wanting to describe the default FP hardware setup exactly and assume that libc changes to properly support long double stdio, etc will follow at some point. However, that also brings to mind: Are we happy with the current default FP hardware setup especially if support for long double is to be improved? At the moment we support long double in name only. There is no extra dynamic range over a double; as might be implied (and allowed by the hardware). Also, as an aside, having just learned everything there is to know about IEEE FP from a witty 80-slide presentation on the WWW by one of the original designers of the spec@Berkeley, I'd say that he would be sad that we default to use 53-bit precision mode. I'd say that it is dumb to claim we even support long double unless we change that to 64-bit precision mode... Regarding the comment in sys/i386/include/npx.h: * 64-bit precision often gives bad results with high level languages * because it makes the results of calculations depend on whether * intermediate values are stored in memory or in FPU registers. This is pure bunk when considered in broad context. Using 53-bit precision mode with high level languages while making actual calculations yields more outright undetectable precision-related errors due to algorithm design by non-numerical analysts. I know which error I'd rather *not* find in my naively-written and compiled FP code. People that write their FP code to correctly use epsilon (the one appropriate for the type of the float they are using) should never see this problem, no? I don't see why FreeBSD should cater to people that don't know how to write FP code properly (i.e. anyone that expected exact results across compilation switches, etc) at the expense of being able to write code that fully utilizes the best mode available from the CPU. People that absolutely want to avoid the problem of spilling from register to memory truncation changing with optimization level may feel free to allocate long doubles instead of doubles. Problem solved. Anyways, that is my quick speech in favor of change. I will help commit bits to the FSF gcc tree that supports whatever people want to do. It is easy to support one FP model for FreeBSD 4 and another for FreeBSD 5. Regards, Loren To Unsubscribe: send mail to [EMAIL PROTECTED] with unsubscribe freebsd-current in the body of the message
Re: Lack of real long double support (was Re: libstdc++ does notcontain fabsl symbol)
On Thu, 24 Oct 2002, Loren James Rittle wrote: ... Anyways, that work exposed some issues. We have this in the system header: #define LDBL_MANT_DIG DBL_MANT_DIG #define LDBL_MIN_EXPDBL_MIN_EXP #define LDBL_MAX_EXPDBL_MAX_EXP [...] This seems to be correct. Long double precision is not really supported either at complie time or runtime. The default precision (on i386's) is 53 bits, so (normalized) long doubles have a hard time getting any larger than DBL_MAX or any smaller than DBL_MIN (you can create them as bits or using a hardware transcendental function, but any arithmetic on them will convert them to double precision). Yet, the FP hardware is actually configured by default to provide `long double' as: #define LDBL_MANT_DIG 53 I think you mean 64 (the hardware default). #define LDBL_MIN_EXP(-16381) #define LDBL_MAX_EXP16384 Indeed, FP code using long double generated by gcc 2.95.X, installed as the FreeBSD 4 system compiler, uses the full exponent range of -16381 to 16384. However, printf(), etc loses on that exponent range and reports Inf. I suspect this is why the system header misreports the FP hardware, thus the header describes the largest printable long double value, not the largest that could be held in a calculation. gcc can't actually support the full range, since it doesn't control the runtime environement (it could issue a fninit before main() to change the default, but it shouldn't and doesn't). The exponent range is lost long before printf() is reached. E.g., long double x= DBL_MAX; long double y = 2 * x; gives +Inf for y since the result is doesn't fit in 53-bit precision. The system header correctly reports this default precision. Any header genrated by the gcc build should be no different, since the build should run in the target environment. Anyways, two questions for FreeBSD maintainers. How should gcc, as provided from the FSF, describe the long double FP format for FreeBSD/i386 4.x? Shall we assume that no changes for FreeBSD 5.x will occur? It should use whatever is the default format for the host environment, It still has enquire.c for doing this automatically. I don't know when enquire.c actually gets used. The FreeBSD build just ignores it and uses src/sys/${MACHINE_ARCH}/float.h. My first encounter with this bug suite was near enquire.c 12-14 years ago. enquire gave different results for -msoft-float and hardware FP because my soft-float libraries only had 53-bit precision but hardware FP used 64-bit precision. ... However, that also brings to mind: Are we happy with the current default FP hardware setup especially if support for long double is to be improved? At the moment we support long double in name only. There is no extra dynamic range over a double; as might be implied (and allowed by the hardware). Not really. Assembly is still required to get full control over precision. I'm still waiting for (C) language support to catch up. Been waiting for about 14 years so far. C99 clarified the semantics of floating point precision but is not supported by gcc (yet?). Also, as an aside, having just learned everything there is to know about IEEE FP from a witty 80-slide presentation on the WWW by one of the original designers of the spec@Berkeley, I'd say that he would be sad that we default to use 53-bit precision mode. I'd say that it is dumb to claim we even support long double unless we change that to 64-bit precision mode... I think he would be even unhappier with gcc's support for it. We default to 53-bit precision partly because Kahan's (his?) paranioa(1) is unhappy with 64-bit precision. Regarding the comment in sys/i386/include/npx.h: * 64-bit precision often gives bad results with high level languages * because it makes the results of calculations depend on whether * intermediate values are stored in memory or in FPU registers. This is pure bunk when considered in broad context. Using 53-bit precision mode with high level languages while making actual calculations yields more outright undetectable precision-related errors due to algorithm design by non-numerical analysts. I know which error I'd rather *not* find in my naively-written and compiled FP code. I think it makes no provably significant difference for naively-written code. I'd rather get the same (perhaps wrong) results on all machines from naively-written code. People that write their FP code to correctly use epsilon (the one appropriate for the type of the float they are using) should never see this problem, no? No. They would see strange behaviour cause by compiler bugs. I don't see why FreeBSD should cater to people that don't know how to write FP code properly (i.e. anyone that expected exact results across compilation switches, etc) at the expense of being able to write code that fully utilizes the best mode available from the CPU. IEEE754 provides many guarantees about
Re: Lack of real long double support (was Re: libstdc++ does notcontain fabsl symbol)
Thanks for the quick answer Bruce. Based on the statement: ``It should use whatever is the default format for the host environment'' and the statements that make it clear gcc isn't changing its default precision setting anytime soon, I think I now know how to make a correct patch for the FSF gcc mainline. More details in line below. Regards, Loren ... Anyways, that work exposed some issues. We have this in the system header: #define LDBL_MANT_DIG DBL_MANT_DIG #define LDBL_MIN_EXPDBL_MIN_EXP #define LDBL_MAX_EXPDBL_MAX_EXP [...] This seems to be correct. Long double precision is not really supported either at complie time or runtime. The default precision (on i386's) is 53 bits, so (normalized) long doubles have a hard time getting any larger than DBL_MAX or any smaller than DBL_MIN (you can create them as bits or using a hardware transcendental function, but any arithmetic on them will convert them to double precision). It is easy to generate, with arithmetic, a long double value outside the *exponent* range above no matter how the precision is set; it is not truncated to Inf until it is actually cast to a double (as is currently done just before a long double is printed with stdio). See below for a program that demonstrates this behavior. Yet, the FP hardware is actually configured by default to provide `long double' as: #define LDBL_MANT_DIG 53 I think you mean 64 (the hardware default). No sir, I did mean as configured in the system startup code, it is forced to 53-bits (that choice affects long double as well as double). But there are no IEEE control bits to limit the size of the exponent field, are there? Thus, the following describes the exact size of the HW's exponent field of a long double as configured by default: #define LDBL_MIN_EXP(-16381) #define LDBL_MAX_EXP16384 gcc can't actually support the full range, since it doesn't control the runtime environement (it could issue a fninit before main() to change the default, but it shouldn't and doesn't). The exponent range is lost long before printf() is reached. E.g., long double x= DBL_MAX; long double y = 2 * x; gives +Inf for y since the result is doesn't fit in 53-bit precision. As you know, the selection of maximum precision is orthogonal to the number of bits used for the exponent. I do wish you were correct. Have you looked at the raw memory of y? It is *not* the bit pattern for +Inf. If y were +Inf, then based on the properties of IEEE math, the following would report Inf not DBL_MAX/2: #include float.h int main (void) { long double x= LDBL_MAX; // Same as DBL_MAX in current float.h long double y = 2e100 * x; // If LDBL_MAX was correct, we should latch Inf. long double z = y / 4e100; printf (%Lg\n, z); } It does, in fact, report DBL_MAX/2 with the system compiler on FreeBSD 4. FYI, I reviewed the generated code to ensure it was using run-time calculations not compile-time calculations. I'd call that a rather easy time getting a normalized long double much larger than LDBL_MAX/DBL_MAX. This test alone proves in my mind that the float.h system header for i386 is itself wrong. The system header correctly reports this default precision. Any header genrated by the gcc build should be no different, since the build should run in the target environment. I agree that the precision setting in the system header is fine. The size of the exponent field is buggy. I held the opinion you have but while trying to convince RTH (the guy that rewrote gcc FP support), I did enough research that also leads me to think that it is the header itself which is buggy. If you really want, I can tell RTH that FreeBSD/i386 absolutely wants `long double' to be: 53 mantissa bits 1024 max exponent And we can let the chips fall where they may but that is lie verses the hardware setup just to match a buggy system header. Attempting to get that patch in was what triggered my research and first post. Anyways, two questions for FreeBSD maintainers. How should gcc, as provided from the FSF, describe the long double FP format for FreeBSD/i386 4.x? Shall we assume that no changes for FreeBSD 5.x will occur? It should use whatever is the default format for the host environment, It still has enquire.c for doing this automatically. [...] I fear I didn't explain clearly enough. enquire.c is completely *gone* in gcc 3.3. This is why gcc needs to fully understand the exact FP default configuration. As you noted, enquire.c was buggy. I think he would be even unhappier with gcc's support for it. We default to 53-bit precision partly because Kahan's (his?) paranioa(1) is unhappy with 64-bit precision. I can't disagree with the first statement. However, support for FP in gcc has just been rewritten and the paranioa test was pulled into gcc. Perhaps it is time to revisit some past assumptions related to FP when gcc 3.3 is imported as the system compiler. And of