From owner-freebsd-current Thu Oct 24 16:48:42 2002 Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9050D37B401 for ; Thu, 24 Oct 2002 16:48:38 -0700 (PDT) Received: from motgate.mot.com (motgate.mot.com [129.188.136.100]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6FCDB43E3B for ; Thu, 24 Oct 2002 16:48:37 -0700 (PDT) (envelope-from rittle@latour.rsch.comm.mot.com) Received: [from pobox4.mot.com (pobox4.mot.com [10.64.251.243]) by motgate.mot.com (motgate 2.1) with ESMTP id QAA06262; Thu, 24 Oct 2002 16:48:35 -0700 (MST)] Received: [from latour.rsch.comm.mot.com (latour.rsch.comm.mot.com [145.1.80.116]) by pobox4.mot.com (MOT-pobox4 2.0) with ESMTP id QAA07898; Thu, 24 Oct 2002 16:48:34 -0700 (MST)] Received: from latour.rsch.comm.mot.com (localhost.rsch.comm.mot.com [127.0.0.1]) by latour.rsch.comm.mot.com (8.12.6/8.12.6) with ESMTP id g9ONlJpZ036024; Thu, 24 Oct 2002 18:47:19 -0500 (CDT) (envelope-from rittle@latour.rsch.comm.mot.com) Received: (from rittle@localhost) by latour.rsch.comm.mot.com (8.12.6/8.12.6/Submit) id g9ONlJqk036023; Thu, 24 Oct 2002 18:47:19 -0500 (CDT) Date: Thu, 24 Oct 2002 18:47:19 -0500 (CDT) From: Loren James Rittle Message-Id: <200210242347.g9ONlJqk036023@latour.rsch.comm.mot.com> To: current@freebsd.org Subject: Re: Lack of real long double support (was Re: libstdc++ does not contain fabsl symbol) In-Reply-To: <20021024205944.R1451-100000@gamplex.bde.org> References: <200210240833.g9O8XB1W033884@latour.rsch.comm.mot.com> Organization: Networks and Infrastructure Lab (IL02/2240), Motorola Labs Cc: bde@zeta.org.au Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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_EXP DBL_MIN_EXP >> #define LDBL_MAX_EXP DBL_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_EXP 16384 > 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 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 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 course, I assumed it was better to give a headups now and fix the FSF-side now while we have the attention of the person that reworked FP support. > 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. OK, my main point was to learn exactly what FreeBSD was going to do with FP so we could capture it over in gcc. To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message