svn commit: r216142 - head/share/man/man3

David Schultz das at
Fri Dec 3 16:19:10 UTC 2010

On Sat, Dec 04, 2010, Bruce Evans wrote:
> On Fri, 3 Dec 2010, David Schultz wrote:
> >Log:
> > Explain some of the reasons that fpsetprec() is unlikely to work as
> > one might expect.  (These functions have already been deprecated for
> > many years.)
> Um, only the functions other than fpsetprec() are deprecated (since it
> is a bug in the fenv family of functions that it has no replacement).

I think "unsupported" is a better term. It may be useful for
people who know what they're doing, but there are numerous rough
edges that nobody plans to fix any time soon.  With gcc now
assuming that all constant-folding is to be done in double
precision, it is virtually unusable.

I'm not picky about the wording; I just want to make sure we're
not claiming that something works when that's far from the case.

> Special:
>     exp2l()
> This falls back to using exp() if the precision is not already extended,
> and is the only libm function with such a fallback.  It, and all other
> functions that need extended precision, should do the same test as
> this one to see if the precision is already, and if not then switch to
> it, and back later.  This would be slower, but only slightly slower in
> what should be the usual case of the caller already having switched
> unconditionally.

I'd forgotten I added that.  IIRC, that was to work around really
egregious errors -- probably the reduction using long double
arithmetic and double constants.  For consistency, maybe we should
just declare defeat on the issue, like most other places in libm.

> exp2l() has been more tested than the other long double transcendenta
> functions, and is known to have some inaccuracies, probably due to
> a buggy polynomial.  According to saved data, the worst case that I
> could find was:
> x = 0.003906249999999999805394000000
>   = 0.003906249999999999805394180368  when rounded to 64 bits
> exp2l(x) = 1.002711275050202485151000000 (according to libm)
>          = 1.002711275050202485150871445 when rounded to 64 bits
>          = 0x8058d7d2d5e5f6ae.0p-63
> exp2l(x rounded) =
>            1.002711275050202485295489388 (according to pari; 28 decimal 
>            digs)
>          = 1.002711275050202485259291663 when rounded to 64 bits
>          = 0x8058d7d2d5e5f6af55.0p-71"
> The error is about 1 + 0x55/0x100 ulps (this is the difference in the 0xp
> values after the 64th mantissa bit), but the claimed accuracy is < 0.511 
> ulps.
> The value of 0.003906... is related to the endpoints of the intervals
> used by exp2l().  There are large errors for many values close to the
> endpoint x = 1/256.0.  This value less 333 ulps is another.

Hmm, that wouldn't be surprising.  I forget which program I used
to compute the polynomial, but it may have neglected to check for
extrema at the endpoints.  Perhaps you can find a better one?

More information about the svn-src-all mailing list