Skip to content

Commit 4bf657f

Browse files
committed
Fix when m_lo is underflowed.
1 parent ab057bd commit 4bf657f

File tree

1 file changed

+9
-8
lines changed

1 file changed

+9
-8
lines changed

libc/src/math/generic/log1p.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,6 @@ LLVM_LIBC_FUNCTION(double, log1p, (double x)) {
882882

883883
constexpr int EXP_BIAS = FPBits_t::EXP_BIAS;
884884
constexpr int FRACTION_LEN = FPBits_t::FRACTION_LEN;
885-
constexpr uint64_t FRACTION_MASK = FPBits_t::FRACTION_MASK;
886885
FPBits_t xbits(x);
887886
uint64_t x_u = xbits.uintval();
888887

@@ -954,12 +953,12 @@ LLVM_LIBC_FUNCTION(double, log1p, (double x)) {
954953
// |x_dd.lo| < ulp(x_dd.hi)
955954

956955
FPBits_t xhi_bits(x_dd.hi);
956+
uint64_t xhi_frac = xhi_bits.get_mantissa();
957957
x_u = xhi_bits.uintval();
958958
// Range reduction:
959959
// Find k such that |x_hi - k * 2^-7| <= 2^-8.
960-
int idx =
961-
static_cast<int>(((x_u & FRACTION_MASK) + (1ULL << (FRACTION_LEN - 8))) >>
962-
(FRACTION_LEN - 7));
960+
int idx = static_cast<int>((xhi_frac + (1ULL << (FRACTION_LEN - 8))) >>
961+
(FRACTION_LEN - 7));
963962
int x_e = xhi_bits.get_exponent() + (idx >> 7);
964963
double e_x = static_cast<double>(x_e);
965964

@@ -981,11 +980,13 @@ LLVM_LIBC_FUNCTION(double, log1p, (double x)) {
981980
// 1 <= m_dd.hi < 2
982981
// |m_dd.lo| < 2^-52.
983982
// This is exact.
984-
uint64_t m_hi = static_cast<uint64_t>(static_cast<int64_t>(x_u) - s_u);
983+
uint64_t m_hi = FPBits_t::one().uintval() | xhi_frac;
984+
985985
uint64_t m_lo =
986-
(x_dd.lo != 0.0)
987-
? FPBits_t(x_dd.lo).uintval()
988-
: static_cast<uint64_t>(cpp::bit_cast<int64_t>(x_dd.lo) - s_u);
986+
FPBits_t(x_dd.lo).abs().get_val() > x_dd.hi * 0x1.0p-127
987+
? static_cast<uint64_t>(cpp::bit_cast<int64_t>(x_dd.lo) - s_u)
988+
: 0;
989+
989990
fputil::DoubleDouble m_dd{FPBits_t(m_lo).get_val(), FPBits_t(m_hi).get_val()};
990991

991992
// Perform range reduction:

0 commit comments

Comments
 (0)