Date: Mon, 28 Oct 2002 21:40:57 -0700 (MST) From: "M. Warner Losh" <imp@bsdimp.com> To: rittle@labs.mot.com, rittle@latour.rsch.comm.mot.com Cc: current@freebsd.org, bde@zeta.org.au, dschultz@uclink.Berkeley.EDU Subject: Re: Lack of real long double support Message-ID: <20021028.214057.108404482.imp@bsdimp.com> In-Reply-To: <200210290211.g9T2BBcP010112@latour.rsch.comm.mot.com> References: <20021025182223.D3076-100000@gamplex.bde.org> <200210290211.g9T2BBcP010112@latour.rsch.comm.mot.com>
next in thread | previous in thread | raw e-mail | index | archive | help
In message: <200210290211.g9T2BBcP010112@latour.rsch.comm.mot.com>
Loren James Rittle <rittle@latour.rsch.comm.mot.com> writes:
: #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 ();
: }
#include <sys/types.h>
#include <float.h>
#include <ieeefp.h>
long double oneld() { return 1.0L; }
print(char *msg, long double ld)
{
uint8_t *c;
int i;
c = (uint8_t *) &ld;
printf("%s = ", msg);
for (i = 0; i < sizeof(ld); i++)
printf("%02x ", *c++ & 0xff);
printf("\n");
}
main ()
{
long double a;
long double b;
fpsetprec(FP_PE);
a = oneld();
b = oneld() + LDBL_EPSILON;
print("a ", a);
a += LDBL_EPSILON;
print("a++", a);
print("b ", b);
}
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....
: 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).
Yup.
: > 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).
This is true too. See the fpsetprec() call that I had to add to make
things work above.
: 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.
Yes. The standard didn't anticipate the fp hardware that intel made.
: 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?
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...
Warner
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20021028.214057.108404482.imp>
