Skip to content

Commit 573e9d0

Browse files
committed
[libc][math][c23] Update for comments again.
1 parent 9420e19 commit 573e9d0

File tree

2 files changed

+24
-63
lines changed

2 files changed

+24
-63
lines changed

libc/src/math/generic/acoshf16.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -70,29 +70,37 @@ LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
7070
return r.value();
7171

7272
float xf = x;
73-
// High precision for inputs very close to 1.0
74-
// For inputs close to 1 (1 <= x < 1.25), use polynomial approximation:
73+
// High precision polynomial approximation for inputs very close to 1.0
74+
// Specifically, for inputs within the range [1, 1.25), we employ the
75+
// following step-by-step Taylor expansion derivation to maintain numerical
76+
// accuracy:
7577
//
7678
// Step-by-step derivation:
77-
// 1. Let y = acosh(x), thus x = cosh(y).
79+
// 1. Define y = acosh(x), thus by definition x = cosh(y).
7880
//
79-
// 2. Rewrite cosh identity using exponential form:
81+
// 2. Expand cosh(y) using exponential identities:
8082
// cosh(y) = (e^y + e^{-y}) / 2
81-
// For y close to 0, let y = sqrt(2 * delta), thus:
82-
// x = cosh(y) ≈ 1 + delta (since cosh(0) = 1, and delta is small)
83-
// thus delta = x - 1.
83+
// For small y, let us set y ≈ sqrt(2 * delta), thus:
84+
// x cosh(y) ≈ 1 + delta, for small delta
85+
// hence delta = x - 1.
8486
//
85-
// 3: Express y in terms of delta (for small delta):
86-
// y ≈ sqrt(2 * delta)
87+
// 3. Express y explicitly in terms of delta (for small delta):
88+
// y = acosh(1 + delta) ≈ sqrt(2 * delta) for very small delta.
8789
//
88-
// 4: Expand acosh(1 + delta) using a Taylor expansion around delta = 0:
89-
// acosh(1 + delta) ≈ sqrt(2 * delta) * P(delta), where P(delta)
90-
// is a polynomial approximation obtained by fitting the function
91-
// precisely in the interval [0, 0.25].
90+
// 4. Use Taylor expansion around delta = 0 to obtain a more accurate
91+
// polynomial:
92+
// acosh(1 + delta) ≈ sqrt(2 * delta) * [1 - delta/12 + 3*delta^2/160 -
93+
// 5*delta^3/896 + 35*delta^4/18432 + ...] For practical computation and
94+
// precision, truncate and fit the polynomial precisely in the range [0,
95+
// 0.25].
9296
//
93-
// Because delta = x - 1 and 0 <= delta < 0.25, the polynomial approximation
94-
// remains numerically stable and accurate in this domain, ensuring high
95-
// precision.
97+
// 5. The implemented polynomial approximation (coefficients obtained from
98+
// careful numerical fitting) is:
99+
// P(delta) ≈ 1 - 0x1.55551ap-4 * delta + 0x1.33160cp-6 * delta^2 -
100+
// 0x1.6890f4p-8 * delta^3 + 0x1.8f3a62p-10 * delta^4
101+
//
102+
// Since delta = x - 1, and 0 <= delta < 0.25, this approximation achieves
103+
// high precision and numerical stability.
96104
if (LIBC_UNLIKELY(xf < 1.25f)) {
97105
float delta = xf - 1.0f;
98106
float sqrt_2_delta = fputil::sqrt<float>(2.0 * delta);

libc/test/src/math/acoshf16_test.cpp

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -20,56 +20,9 @@ namespace mpfr = LIBC_NAMESPACE::testing::mpfr;
2020
static constexpr uint16_t START = 0x3c00U;
2121
static constexpr uint16_t STOP = 0x7bffU;
2222

23-
TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
24-
LIBC_NAMESPACE::libc_errno = 0;
25-
26-
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(aNaN));
27-
EXPECT_MATH_ERRNO(0);
28-
29-
EXPECT_FP_EQ_WITH_EXCEPTION(aNaN, LIBC_NAMESPACE::acoshf16(sNaN), FE_INVALID);
30-
EXPECT_MATH_ERRNO(0);
31-
32-
EXPECT_FP_EQ_ALL_ROUNDING(float16(0.0f),
33-
LIBC_NAMESPACE::acoshf16(float16(1.0f)));
34-
EXPECT_MATH_ERRNO(0);
35-
36-
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
37-
EXPECT_MATH_ERRNO(EDOM);
38-
39-
EXPECT_FP_EQ_ALL_ROUNDING(inf, LIBC_NAMESPACE::acoshf16(inf));
40-
EXPECT_MATH_ERRNO(0);
41-
42-
EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
43-
EXPECT_MATH_ERRNO(EDOM);
44-
}
45-
4623
TEST_F(LlvmLibcAcoshf16Test, PositiveRange) {
4724
for (uint16_t v = START; v <= STOP; ++v) {
4825
float16 x = FPBits(v).get_val();
49-
50-
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, x,
51-
LIBC_NAMESPACE::acoshf16(x), 0.5);
52-
}
53-
}
54-
55-
TEST_F(LlvmLibcAcoshf16Test, SpecificBitPatterns) {
56-
constexpr int N = 12;
57-
constexpr uint16_t INPUTS[N] = {
58-
0x3C00, // x = 1.0
59-
0x3C01, // x = just above 1.0 (minimally larger than 1)
60-
0x3E00, // x = 1.5
61-
0x4200, // x = 3.0
62-
0x4500, // x = 5.0
63-
0x4900, // x = 10.0
64-
0x51FF, // x = ~47.94
65-
0x5CB0, // x = ~300.0
66-
0x643F, // x = ~1087.6
67-
0x77FF, // x = just below next exponent interval (max for exponent 0x1D)
68-
0x7801, // x = just above previous value (min for exponent 0x1E)
69-
0x7BFF // x = 65504.0 (max finite half)
70-
};
71-
for (int i = 0; i < N; ++i) {
72-
float16 x = FPBits(INPUTS[i]).get_val();
7326
EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Acosh, x,
7427
LIBC_NAMESPACE::acoshf16(x), 0.5);
7528
}

0 commit comments

Comments
 (0)