[libc-commits] [libc] a879073 - [libc][math] Fix a bug in cbrt when the result is rounded to the next exponent. (#113749)

via libc-commits libc-commits at lists.llvm.org
Fri Oct 25 19:11:11 PDT 2024


Author: lntue
Date: 2024-10-25T22:11:07-04:00
New Revision: a879073494e7989f670ab0432dd0047ffbf5d1cd

URL: https://github.com/llvm/llvm-project/commit/a879073494e7989f670ab0432dd0047ffbf5d1cd
DIFF: https://github.com/llvm/llvm-project/commit/a879073494e7989f670ab0432dd0047ffbf5d1cd.diff

LOG: [libc][math] Fix a bug in cbrt when the result is rounded to the next exponent. (#113749)

Added: 
    

Modified: 
    libc/src/math/generic/cbrt.cpp
    libc/test/src/math/cbrt_test.cpp
    libc/test/src/math/smoke/cbrt_test.cpp

Removed: 
    


################################################################################
diff  --git a/libc/src/math/generic/cbrt.cpp b/libc/src/math/generic/cbrt.cpp
index 036664c2aafaf4..4fa24c54fdeecf 100644
--- a/libc/src/math/generic/cbrt.cpp
+++ b/libc/src/math/generic/cbrt.cpp
@@ -235,10 +235,10 @@ LLVM_LIBC_FUNCTION(double, cbrt, (double x)) {
 
   // Lambda function to update the exponent of the result.
   auto update_exponent = [=](double r) -> double {
-    uint64_t r_m = FPBits(r).uintval() & 0x800F'FFFF'FFFF'FFFF;
+    uint64_t r_m = FPBits(r).uintval() - 0x3FF0'0000'0000'0000;
     // Adjust exponent and sign.
     uint64_t r_bits =
-        r_m | (static_cast<uint64_t>(out_e) << FPBits::FRACTION_LEN);
+        r_m + (static_cast<uint64_t>(out_e) << FPBits::FRACTION_LEN);
     return FPBits(r_bits).get_val();
   };
 

diff  --git a/libc/test/src/math/cbrt_test.cpp b/libc/test/src/math/cbrt_test.cpp
index 2ef2140966f52c..2e2de16fc859d1 100644
--- a/libc/test/src/math/cbrt_test.cpp
+++ b/libc/test/src/math/cbrt_test.cpp
@@ -87,12 +87,13 @@ TEST_F(LlvmLibcCbrtTest, InDoubleRange) {
 
 TEST_F(LlvmLibcCbrtTest, SpecialValues) {
   constexpr double INPUTS[] = {
-      0x1.4f61672324c8p-1028, 0x1.00152f57068b7p-1, 0x1.006509cda9886p-1,
-      0x1.018369b92e523p-1,   0x1.10af932ef2bf9p-1, 0x1.1a41117939fdbp-1,
-      0x1.2ae8076520d9ap-1,   0x1.a202bfc89ddffp-1, 0x1.a6bb8c803147bp-1,
-      0x1.000197b499b1bp+0,   0x1.00065ed266c6cp+0, 0x1.d4306c202c4c2p+0,
-      0x1.8fd409efe4851p+1,   0x1.95fd0eb31cc4p+1,  0x1.7cef1d276e335p+2,
-      0x1.94910c4fc98p+2,     0x1.a0cc1327bb4c4p+2, 0x1.e7d6ebed549c4p+2,
+      0x1.4f61672324c8p-1028, -0x1.fffffffffffffp-1021, 0x1.00152f57068b7p-1,
+      0x1.006509cda9886p-1,   0x1.018369b92e523p-1,     0x1.10af932ef2bf9p-1,
+      0x1.1a41117939fdbp-1,   0x1.2ae8076520d9ap-1,     0x1.a202bfc89ddffp-1,
+      0x1.a6bb8c803147bp-1,   0x1.000197b499b1bp+0,     0x1.00065ed266c6cp+0,
+      0x1.d4306c202c4c2p+0,   0x1.8fd409efe4851p+1,     0x1.95fd0eb31cc4p+1,
+      0x1.7cef1d276e335p+2,   0x1.94910c4fc98p+2,       0x1.a0cc1327bb4c4p+2,
+      0x1.e7d6ebed549c4p+2,
   };
   for (double v : INPUTS) {
     double x = FPBits(v).get_val();

diff  --git a/libc/test/src/math/smoke/cbrt_test.cpp b/libc/test/src/math/smoke/cbrt_test.cpp
index 724e0e979decc1..d57cdb20de2746 100644
--- a/libc/test/src/math/smoke/cbrt_test.cpp
+++ b/libc/test/src/math/smoke/cbrt_test.cpp
@@ -32,4 +32,6 @@ TEST_F(LlvmLibcCbrtTest, SpecialNumbers) {
   EXPECT_FP_EQ_ALL_ROUNDING(-0x1.0p42, LIBC_NAMESPACE::cbrt(-0x1.0p126));
   EXPECT_FP_EQ_ALL_ROUNDING(0x1.0p341, LIBC_NAMESPACE::cbrt(0x1.0p1023));
   EXPECT_FP_EQ_ALL_ROUNDING(-0x1.0p341, LIBC_NAMESPACE::cbrt(-0x1.0p1023));
+  EXPECT_FP_EQ(-0x1.0p-340, LIBC_NAMESPACE::cbrt(-0x1.fffffffffffffp-1021));
+  EXPECT_FP_EQ(2.0, LIBC_NAMESPACE::cbrt(0x1.fffffffffffffp2));
 }


        


More information about the libc-commits mailing list