[libc-commits] [libc] [libc][math][c23] Add exp2m1f C23 math function (PR #86996)

via libc-commits libc-commits at lists.llvm.org
Tue Apr 2 03:50:00 PDT 2024


================
@@ -223,6 +229,30 @@ class MPFRNumber {
     return result;
   }
 
+  MPFRNumber
+  exp2m1([[maybe_unused]] const MPFRNumber &underflow_rndz_fallback) const {
+    // TODO: Only use mpfr_exp2m1 once CI and buildbots get MPFR >= 4.2.0.
+#if MPFR_VERSION_MAJOR > 4 ||                                                  \
+    (MPFR_VERSION_MAJOR == 4 && MPFR_VERSION_MINOR >= 2)
+    MPFRNumber result(*this);
+    mpfr_exp2m1(result.value, value, mpfr_rounding);
+    return result;
+#else
+    MPFRNumber result(*this, mpfr_precision * 8);
----------------
overmighty wrote:

There are 4 values for which it fails:

```
[ RUN      ] LlvmLibcExp2m1fExhaustiveTest.PostiveRange
/home/overmighty/projects/llvm-project/libc/test/src/math/exhaustive/exhaustive_test.h:64: FAILURE
Failed to match FUNC(x) against LIBC_NAMESPACE::testing::mpfr::get_mpfr_matcher<Op>( x, FUNC(x), 0.5, rounding).
Match value not within tolerance value of MPFR result:
  Input decimal: 24.00000000000000000000000000000000000000000000000000
     Input bits: 0x41C00000 = (S: 0, E: 0x0083, M: 0x00400000)

  Match decimal: 16777215.00000000000000000000000000000000000000000000000000
     Match bits: 0x4B7FFFFF = (S: 0, E: 0x0096, M: 0x007FFFFF)

    MPFR result: 16777215.00000000000006750155989720951765775680541992187500
   MPFR rounded: 0x4B800000 = (S: 0, E: 0x0097, M: 0x00000000)

      ULP error: 1.00000000000000000000000000000000000000000000000000
/home/overmighty/projects/llvm-project/libc/test/src/math/exhaustive/exhaustive_test.h:64: FAILURE
Failed to match FUNC(x) against LIBC_NAMESPACE::testing::mpfr::get_mpfr_matcher<Op>( x, FUNC(x), 0.5, rounding).
Match value not within tolerance value of MPFR result:
  Input decimal: 24.00000000000000000000000000000000000000000000000000
     Input bits: 0x41C00000 = (S: 0, E: 0x0083, M: 0x00400000)

  Match decimal: 16777215.00000000000000000000000000000000000000000000000000
     Match bits: 0x4B7FFFFF = (S: 0, E: 0x0096, M: 0x007FFFFF)

    MPFR result: 16777215.00000000000006750155989720951765775680541992187500
   MPFR rounded: 0x4B800000 = (S: 0, E: 0x0097, M: 0x00000000)

      ULP error: 1.00000000000000000000000000000000000000000000000000
Test failed for 1 inputs in range: 1102053376 to 1103101952 [0x41b00000, 0x41c00000), [0x1.6p+4, 0x1.8p+4)
Test failed for 1 inputs in range: 1103101952 to 1104150528 [0x41c00000, 0x41d00000), [0x1.8p+4, 0x1.ap+4)

Test FAILED
/home/overmighty/projects/llvm-project/libc/test/src/math/exhaustive/exhaustive_test.h:148: FAILURE
      Expected: failed.load()
      Which is: 2
To be equal to: uint64_t(0)
      Which is: 0
[  FAILED  ] LlvmLibcExp2m1fExhaustiveTest.PostiveRange
[ RUN      ] LlvmLibcExp2m1fExhaustiveTest.NegativeRange
-- Testing for FE_TONEAREST in range [0xbf700000, 0xbf900000) --
100% is in process
Test PASSED
-- Testing for FE_UPWARD in range [0xbf700000, 0xbf900000) --
50% is in process
Test PASSED
-- Testing for FE_DOWNWARD in range [0xbf700000, 0xbf900000) --
100% is in process
Test PASSED
-- Testing for FE_TOWARDZERO in range [0xbf700000, 0xbf900000) --
/home/overmighty/projects/llvm-project/libc/test/src/math/exhaustive/exhaustive_test.h:64: FAILURE
Failed to match FUNC(x) against LIBC_NAMESPACE::testing::mpfr::get_mpfr_matcher<Op>( x, FUNC(x), 0.5, rounding).
Match value not within tolerance value of MPFR result:
  Input decimal: -1.00000000000000000000000000000000000000000000000000
     Input bits: 0xBF800000 = (S: 1, E: 0x007F, M: 0x00000000)

  Match decimal: -0.50000000000000000000000000000000000000000000000000
     Match bits: 0xBF000000 = (S: 1, E: 0x007E, M: 0x00000000)

    MPFR result: -0.49999999999999999999989412088159321245761645968742
   MPFR rounded: 0xBEFFFFFF = (S: 1, E: 0x007D, M: 0x007FFFFF)

      ULP error: 1.00000000000000000000000000000000000000000000000000
/home/overmighty/projects/llvm-project/libc/test/src/math/exhaustive/exhaustive_test.h:64: FAILURE
Failed to match FUNC(x) against LIBC_NAMESPACE::testing::mpfr::get_mpfr_matcher<Op>( x, FUNC(x), 0.5, rounding).
Match value not within tolerance value of MPFR result:
  Input decimal: -1.00000000000000000000000000000000000000000000000000
     Input bits: 0xBF800000 = (S: 1, E: 0x007F, M: 0x00000000)

  Match decimal: -0.50000000000000000000000000000000000000000000000000
     Match bits: 0xBF000000 = (S: 1, E: 0x007E, M: 0x00000000)

    MPFR result: -0.49999999999999999999989412088159321245761645968742
   MPFR rounded: 0xBEFFFFFF = (S: 1, E: 0x007D, M: 0x007FFFFF)

      ULP error: 1.00000000000000000000000000000000000000000000000000
Test failed for 1 inputs in range: 3211788288 to 3212836864 [0xbf700000, 0xbf800000), [-0x1.ep-1, -0x1p+0)
Test failed for 1 inputs in range: 3212836864 to 3213885440 [0xbf800000, 0xbf900000), [-0x1p+0, -0x1.2p+0)

Test FAILED
/home/overmighty/projects/llvm-project/libc/test/src/math/exhaustive/exhaustive_test.h:148: FAILURE
      Expected: failed.load()
      Which is: 2
To be equal to: uint64_t(0)
      Which is: 0
[  FAILED  ] LlvmLibcExp2m1fExhaustiveTest.NegativeRange
```

Code:

```cpp
    auto prec = mpfr_precision * 3;
    MPFRNumber result(*this, prec);
    MPFRNumber ln2(2.0f, prec);
    mpfr_log(ln2.value, ln2.value, mpfr_rounding); // log(2)
    mpfr_mul(result.value, value, ln2.value, mpfr_rounding); // x * log(2)
    mpfr_expm1(result.value, result.value, mpfr_rounding); // e^(x * log(2)) - 1
    return result;
```

https://github.com/llvm/llvm-project/pull/86996


More information about the libc-commits mailing list