Skip to content

Commit 174129e

Browse files
ViralBShahclaude
andcommitted
add regression test for #285 coshl tiny inputs
Covers ld128 coshl(2^-k) for k in [57,128]; the pre-fix code returned 1+tiny instead of exactly 1.0 for k>71. Skipped where long double is not 128-bit (LDBL_MANT_DIG < 100). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 100ab2d commit 174129e

1 file changed

Lines changed: 52 additions & 0 deletions

File tree

test/regression/test-285.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Regression test for issue #285: ld128 coshl returned 1+x instead of 1 for
3+
* tiny |x|.
4+
* https://github.com/JuliaMath/openlibm/issues/285
5+
*
6+
* The early-exit branch in ld128/e_coshl.c returned `1 + expm1l(x)` (~= 1+x)
7+
* for tiny representable x instead of exactly 1.0. cosh(x) = 1 + x^2/2 + O(x^4);
8+
* for these inputs the x^2/2 term is below half an ulp at 1.0 (2^-113 in
9+
* 113-bit precision), so the correctly rounded result is exactly 1.0.
10+
*
11+
* This only manifests where long double is 128-bit (LDBL_MANT_DIG == 113),
12+
* e.g. aarch64/riscv64 Linux. Elsewhere (80-bit x87, 64-bit double) the test
13+
* is skipped.
14+
*/
15+
#include <float.h>
16+
17+
#include "regress-util.h"
18+
19+
/*
20+
* The fix is in ld128/e_coshl.c, which openlibm compiles only on (linux)
21+
* aarch64. Restrict the test to that target at compile time so that on every
22+
* other arch it becomes a bare skip with no reference to coshl (which may be
23+
* absent from the library and would otherwise break the link).
24+
*/
25+
#if defined(__aarch64__) && LDBL_MANT_DIG == 113
26+
27+
#include <math.h>
28+
29+
int
30+
main(void)
31+
{
32+
int k;
33+
34+
/*
35+
* For k in [57,128], coshl(2^-k) rounds to exactly 1.0L in 113-bit
36+
* precision. The pre-fix code returned 1+tiny for k > 71.
37+
*/
38+
for (k = 57; k <= 128; k++)
39+
CHECK(coshl(ldexpl(1.0L, -k)) == 1.0L);
40+
41+
return 0;
42+
}
43+
44+
#else
45+
46+
int
47+
main(void)
48+
{
49+
return REGRESS_SKIP;
50+
}
51+
52+
#endif

0 commit comments

Comments
 (0)