Underflow in ctanh()

Damian McGuckin damianm@esi.com.au
Wed Jul 2 09:39:46 GMT 2025


I am curious as to the complexity

         /* Avoid intermediate overflow when the imaginary part of
            the result may be subnormal.  Ignoring negligible terms,
            the real part is +/- 1, the imaginary part is
            sin(y)*cos(y)/sinh(x)^2 = 4*sin(y)*cos(y)/exp(2x).  */
         FLOAT exp_2t = M_EXP (2 * t);

         __real__ res = M_COPYSIGN (1, __real__ x);
         __imag__ res = 4 * sinix * cosix;
         __real__ x = M_FABS (__real__ x);
         __real__ x -= t;
         __imag__ res /= exp_2t;
         if (__real__ x > t)
           {
             /* Underflow (original real part of x has absolute value
              > 2t).  */
             __imag__ res /= exp_2t;
           }
         else
           __imag__ res /= M_EXP (2 * __real__ x);

Rather than compensating for overflow, why not just compute

 	FLOAT exp_neg_x = M_EXP(-M_FABS(__real__ x))

This is either normal with no exception, or subnormal or zero with an 
underflow exception.  If exp(-|x|) was so small as to raise an exception,
this is desired.

Subsequently, then compute

 	__imag__ res = ((4 * sinix * cosix) * exp_neg_x) * exp_neg_x;

If s is normal but tiny, that last expression might correctly underflow
which is what is desired.

Thanks - Damian


More information about the Libc-alpha mailing list