Use of C99 extra long double math functions after r236148

Stephen Montgomery-Smith stephen at
Tue May 29 03:03:50 UTC 2012

On 05/28/2012 07:07 PM, Steve Kargl wrote:
> On Mon, May 28, 2012 at 06:44:42PM -0500, Stephen Montgomery-Smith wrote:
>> On 05/28/2012 06:30 PM, Steve Kargl wrote:
>>> > From clog.c in
>>> double complex
>>> ccosh (z)
>>>       double complex z;
>>> {
>>>    double complex w;
>>>    double x, y;
>>>    x = creal(z);
>>>    y = cimag(z);
>>>    w = cosh (x) * cos (y)  +  (sinh (x) * sin (y)) * I;
>>>    return (w);
>>> }
>>> See math_private.h about the above.
>> I looked in math_private.h - I presume you meant
>> lib/msun/src/math_private.h.  I wasn't able to find anything about ccosh
>> there.
>> I think that for a rough and ready ccosh, this is high enough quality
>> for a math/cephes port.
> That's the problem.  It is not acceptable (imo).  The comment in
> math_private.h that is relevant is
> /*
>   * Inline functions that can be used to construct complex values.
>   *
>   * The C99 standard intends x+I*y to be used for this, but x+I*y is
>   * currently unusable in general since gcc introduces many overflow,
>   * underflow, sign and efficiency bugs by rewriting I*y as
>   * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product.
>   * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted
>   * to -0.0+I*0.0.
>   */
> Those wrong +-0 mean you may up end up on the worng riemann sheet,
> and that NaN propagates.

OK, I agree with you that gcc fails to be C99 compliant.  But I disagree 
with you that this is a big deal.

1.  By being so picky about being so precise, FreeBSD is behind the time 
line in rolling out a usable set of C99 functions.  The compilers and 
operating systems have many bugs, and if we waited until we were totally 
sure that all the bugs were gone, we wouldn't have any operating system 
to work with at all.  Why be more picky with floating point arithmetic 
than the other aspects of FreeBSD?

2.  If I was really worried about being on the correct Riemann sheet, I 
would code very, very carefully, and not rely on numerical accuracy of 
any kind of floating point calculation.  There is a certain mathematical 
inconsistency in introducing 0, -0 and Inf+I*Inf, and the number of 
times programmers really want a very specific kind of behavior for 
exceptions is so rare that they are better off writing their own wrapper 
code than relying on any library functions.  (For example, is there a 
difference between 0 and +0?  If not, does -(0) compute to 0 or -0?  I 
can see circumstances where I sometimes want one, and sometimes the other.)

3.  But to counter my own argument, it highly bothers me that in C that 
"(-5)%3" evaluates to "-2" and not to "1".  That bug^H^H^H feature has 
truly bitten me.  And I have had lengthy arguments online with some C 
experts as to why "1" should be the correct answer, without being able 
to convince them.  If it were up to me, the whole of the C standard 
would be scrapped, and rewritten with everything exactly the same except 
for this one thing.  But to those I argued with, I seem just as picky as 
you seem when you insist that 0 and -0 are different.  So what do I do? 
  I live with it, just like we all live in an imperfect world.

If I had a choice between correcting the C standard for "%" or solving 
world hunger, I would definitely settle for the second.  And maybe the C 
programming language, for all its imperfections, has helped push 
frontiers of technology sufficiently that someone is less hungry than 
they would have otherwise been.  And if those resources used to feed 
people had been redirected to fix the C standard, then maybe a few more 
people would be hungry.

In the end, I do think it is good to ultimately settle on good C99 
compliant code.  But having something intermediate that mostly works is 
better than nothing.  Especially if it exists only in the ports, and not 
in the base code.

More information about the freebsd-current mailing list