Skip site navigation (1)Skip section navigation (2)
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>