You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The following test program computes cosh of 1, 1/2, 1/4, ..., 1/2^-128.
#include<stdio.h>#include<math.h>intmain(intargc, char**argv) {
long doubled=1.0;
for (inti=0; i<128; i++) {
printf("coshl(%La) = %La\n", d, coshl(d));
d /= 2;
}
}
For small ε, cosh(ε) ≈ 1+ε^2/2. So if we run on AArch64, which has 128-bit long doubles with a 112-bit mantissa, we expect that by the time the input is about 2^-56, the output will be indistinguishable from 1. And indeed this looks sensible to start off with:
Naive question: could this branch be amended to return one instead of w?
Also, I checked the OpenBSD source (where openlibm's 128-bit long double definition for coshl came from) and the code hasn't changed since the version imported here, so it has the same issue. When the issue is fixed here it could be worthwhile for someone to contribute the fix back upstream as well.
The following test program computes cosh of 1, 1/2, 1/4, ..., 1/2^-128.
For small ε, cosh(ε) ≈ 1+ε^2/2. So if we run on AArch64, which has 128-bit long doubles with a 112-bit mantissa, we expect that by the time the input is about 2^-56, the output will be indistinguishable from 1. And indeed this looks sensible to start off with:
but a little bit later, the outputs unexpectedly become wrong:
It looks as if the early exit code path from this special case in
ld128/e_coshl.c
is absent-mindedly returning the wrong variable:But
w
is not 1: it's 1 + expm1(input), i.e. about exp(input), i.e. about 1+input (for small inputs).The text was updated successfully, but these errors were encountered: