Skip to content

Commit 33c2efa

Browse files
committed
[libc][math][c23] Do some change.
1 parent 573e9d0 commit 33c2efa

File tree

4 files changed

+26
-41
lines changed

4 files changed

+26
-41
lines changed

libc/src/math/generic/acoshf16.cpp

Lines changed: 18 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===-- Half-precision acoshf16 function ----------------------------------===//
1+
//===-- Half-precision acosh(x) function ----------------------------------===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "src/math/acoshf16.h"
10+
#include "explogxf.h"
1011
#include "hdr/errno_macros.h"
1112
#include "hdr/fenv_macros.h"
1213
#include "src/__support/FPUtil/FEnvImpl.h"
@@ -16,16 +17,15 @@
1617
#include "src/__support/FPUtil/multiply_add.h"
1718
#include "src/__support/FPUtil/sqrt.h"
1819
#include "src/__support/macros/optimization.h"
19-
#include "src/math/generic/explogxf.h"
2020

2121
namespace LIBC_NAMESPACE_DECL {
2222

2323
static constexpr size_t N_EXCEPTS = 2;
2424
static constexpr fputil::ExceptValues<float16, N_EXCEPTS> ACOSHF16_EXCEPTS{{
2525
// (input, RZ output, RU offset, RD offset, RN offset)
26-
// x = 0x1.6ep+1, acoshf16(x) = 0x1.dbp+0 (RZ)
26+
// x = 0x1.6dcp+1, acoshf16(x) = 0x1.b6p+0 (RZ)
2727
{0x41B7, 0x3ED8, 1, 0, 0},
28-
// x = 0x1.c8p+0, acoshf16(x) = 0x1.27cp-1 (RZ)
28+
// x = 0x1.39p+0, acoshf16(x) = 0x1.4f8p-1 (RZ)
2929
{0x3CE4, 0x393E, 1, 0, 1},
3030
}};
3131

@@ -70,42 +70,24 @@ LLVM_LIBC_FUNCTION(float16, acoshf16, (float16 x)) {
7070
return r.value();
7171

7272
float xf = x;
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:
73+
// High-precision polynomial approximation for inputs close to 1.0
74+
// ([1, 1.25)).
7775
//
78-
// Step-by-step derivation:
79-
// 1. Define y = acosh(x), thus by definition x = cosh(y).
80-
//
81-
// 2. Expand cosh(y) using exponential identities:
82-
// cosh(y) = (e^y + e^{-y}) / 2
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.
86-
//
87-
// 3. Express y explicitly in terms of delta (for small delta):
88-
// y = acosh(1 + delta) ≈ sqrt(2 * delta) for very small delta.
89-
//
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].
96-
//
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.
76+
// Brief derivation:
77+
// 1. Start from the definition: acosh(x) = y means x = cosh(y).
78+
// 2. Set x = 1 + delta. For small delta, y ≈ sqrt(2 * delta).
79+
// 3. Expand acosh(1 + delta) using Taylor series around delta=0:
80+
// acosh(1 + delta) ≈ sqrt(2 * delta) * [1 - delta/12 + 3*delta^2/160
81+
// - 5*delta^3/896 + 35*delta^4/18432 + ...]
82+
// 4. Truncate the series to fit accurately for delta in [0, 0.25].
83+
// 5. Polynomial coefficients (from sollya) used here are:
84+
// P(delta) ≈ 1 - 0x1.555556p-4 * delta + 0x1.333334p-6 * delta^2
85+
// - 0x1.6db6dcp-8 * delta^3 + 0x1.f1c71cp-10 * delta^4
10486
if (LIBC_UNLIKELY(xf < 1.25f)) {
10587
float delta = xf - 1.0f;
10688
float sqrt_2_delta = fputil::sqrt<float>(2.0 * delta);
107-
float pe = fputil::polyeval(delta, 0x1p+0f, -0x1.55551ap-4f, 0x1.33160cp-6f,
108-
-0x1.6890f4p-8f, 0x1.8f3a62p-10f);
89+
float pe = fputil::polyeval(delta, 0x1p+0f, -0x1.555556p-4f, 0x1.333334p-6f,
90+
-0x1.6db6dcp-8f, 0x1.f1c71cp-10f);
10991
float approx = sqrt_2_delta * pe;
11092
return fputil::cast<float16>(approx);
11193
}

libc/test/src/math/acoshf16_test.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "src/__support/FPUtil/FPBits.h"
10-
#include "src/__support/FPUtil/cast.h"
119
#include "src/errno/libc_errno.h"
1210
#include "src/math/acoshf16.h"
1311
#include "test/UnitTest/FPMatcher.h"
12+
#include "test/UnitTest/Test.h"
1413
#include "utils/MPFRWrapper/MPFRUtils.h"
1514
#include <stdint.h>
1615

libc/test/src/math/smoke/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3953,7 +3953,8 @@ add_fp_unittest(
39533953
acoshf16_test.cpp
39543954
DEPENDS
39553955
libc.src.errno.errno
3956-
libc.src.math.acoshf16
3956+
libc.src.math.acoshf16
3957+
libc.src.__support.FPUtil.cast
39573958
)
39583959

39593960
add_fp_unittest(

libc/test/src/math/smoke/acoshf16_test.cpp

Lines changed: 5 additions & 2 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 "test/UnitTest/FPMatcher.h"
@@ -33,9 +34,11 @@ TEST_F(LlvmLibcAcoshf16Test, SpecialNumbers) {
3334
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(neg_inf));
3435
EXPECT_MATH_ERRNO(EDOM);
3536

36-
EXPECT_FP_EQ(float16(0.0f), LIBC_NAMESPACE::acoshf16(float16(1.0f)));
37+
EXPECT_FP_EQ(zero, LIBC_NAMESPACE::acoshf16(
38+
LIBC_NAMESPACE::fputil::cast<float16>(1.0)));
3739
EXPECT_MATH_ERRNO(0);
3840

39-
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(float16(0.5f)));
41+
EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::acoshf16(
42+
LIBC_NAMESPACE::fputil::cast<float16>(0.5)));
4043
EXPECT_MATH_ERRNO(EDOM);
4144
}

0 commit comments

Comments
 (0)