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