Skip to content

Commit 7711a3b

Browse files
committed
[libc][math][c23] Fix some test failures.
1 parent 18e165b commit 7711a3b

File tree

2 files changed

+45
-25
lines changed

2 files changed

+45
-25
lines changed

libc/src/math/generic/acoshf16.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,18 @@ namespace LIBC_NAMESPACE_DECL {
2323
LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
2424
using FPBits = fputil::FPBits<float16>;
2525
FPBits xbits(x);
26-
2726
uint16_t x_u = xbits.uintval();
2827
uint16_t x_abs = x_u & 0x7fff;
2928

29+
// if (LIBC_UNLIKELY(x <= 1.0f)) {
30+
// if (x == 1.0f)
31+
// return 0.0f;
32+
// // x < 1.
33+
// fputil::set_errno_if_required(EDOM);
34+
// fputil::raise_except_if_required(FE_INVALID);
35+
// return FPBits::quiet_nan().get_val();
36+
// }
37+
3038
// Check for NaN input first.
3139
if (LIBC_UNLIKELY(xbits.is_nan())) {
3240
if (xbits.is_signaling_nan()) {
@@ -62,11 +70,18 @@ LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
6270
// High precision for inputs very close to 1.0
6371
if (LIBC_UNLIKELY(xf32 < 1.25f)) {
6472
float delta = xf32 - 1.0f;
65-
float sqrt_2_delta = fputil::sqrt<float>(2.0f * delta);
66-
double correction = (double)delta / 12.0 - (3.0 * (double)delta * delta) / 160.0;
67-
double precise_result = (double)sqrt_2_delta * (1.0 - correction);
68-
return fputil::cast<float16>(static_cast<float>(precise_result));
73+
float sqrt_2 = fputil::sqrt<float>(2.0f * delta);
74+
float sqrt_2d = fputil::sqrt<float>(2.0f * delta);
75+
float d32 = delta * fputil::sqrt<float>(delta);
76+
float term2 = d32 / (6.0f * fputil::sqrt<float>(2.0f));
77+
float d52 = d32 * delta;
78+
float term3 = 3.0f * d52 / (80.0f * sqrt_2);
79+
float d72 = d52 * delta;
80+
float term4 = 5.0f * d72 / (1792.0f * sqrt_2);
81+
float result = sqrt_2d - term2 + term3 - term4;
82+
return fputil::cast<float16>(result);
6983
}
84+
7085
// Special optimization for large input values.
7186
if (LIBC_UNLIKELY(xf32 >= 32.0f)) {
7287
float result = static_cast<float>(log_eval(2.0f * xf32));

libc/test/src/math/acoshf16_test.cpp

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include "src/__support/FPUtil/cast.h"
910
#include "src/errno/libc_errno.h"
1011
#include "src/math/acoshf16.h"
1112
#include "src/__support/FPUtil/FPBits.h"
@@ -40,34 +41,38 @@ TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
4041
}
4142

4243
TEST_F(LlvmLibcAcoshf16Test, InFloat16Range) {
43-
constexpr uint16_t START = 0x3C00U; // 1.0
44-
constexpr uint16_t STOP = 0x7BFFU; // Largest finite float16 value
44+
constexpr uint32_t COUNT = 100'000;
45+
constexpr uint32_t STEP = UINT32_MAX / COUNT;
4546

46-
for (uint16_t bits = START; bits <= STOP; ++bits) {
47-
float16 x = FPBits(bits).get_val();
48-
if (FPBits(bits).is_nan() || FPBits(bits).is_inf())
47+
for (uint32_t i = 0, v = 0; i <= COUNT; ++i, v += STEP) {
48+
LIBC_NAMESPACE::fputil::FPBits<float> bits(v);
49+
float xf32 = bits.get_val();
50+
if (bits.is_nan() || bits.is_inf())
4951
continue;
50-
ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, float(x),
51-
float(LIBC_NAMESPACE::acoshf16(x)),
52-
5.0);
52+
if (xf32 < 1.0f)
53+
continue;
54+
float16 xh = LIBC_NAMESPACE::fputil::cast<float16>(xf32);
55+
56+
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, xh,
57+
LIBC_NAMESPACE::acoshf16(xh), 3.0);
5358
}
5459
}
5560

5661
TEST_F(LlvmLibcAcoshf16Test, SpecificBitPatterns) {
5762
constexpr int N = 12;
5863
constexpr uint16_t INPUTS[N] = {
59-
0x3C00, // 1.0
60-
0x3C01, // just above 1.0 (minimally larger than 1)
61-
0x3E00, // 1.5
62-
0x4200, // 3.0
63-
0x4500, // 5.0
64-
0x4900, // 10.0
65-
0x51FF, // ~47.94 (random mid-range value)
66-
0x5CB0, // ~300.0 (random mid-range value)
67-
0x643F, // ~1087.6 (random large value)
68-
0x77FF, // just below next exponent interval (max for exponent 0x1D)
69-
0x7801, // just above previous value (min for exponent 0x1E)
70-
0x7BFF // 65504.0 (max finite half)
64+
0x3C00, // x = 1.0
65+
0x3C01, // x = just above 1.0 (minimally larger than 1)
66+
0x3E00, // x = 1.5
67+
0x4200, // x = 3.0
68+
0x4500, // x = 5.0
69+
0x4900, // x = 10.0
70+
0x51FF, // x = ~47.94
71+
0x5CB0, // x = ~300.0
72+
0x643F, // x = ~1087.6
73+
0x77FF, // x = just below next exponent interval (max for exponent 0x1D)
74+
0x7801, // x = just above previous value (min for exponent 0x1E)
75+
0x7BFF // x = 65504.0 (max finite half)
7176
};
7277
for (int i = 0; i < N; ++i) {
7378
float16 x = FPBits(INPUTS[i]).get_val();

0 commit comments

Comments
 (0)