Skip to content

Commit a813c1f

Browse files
committed
fixup! [libc][math][c23] Add exp2m1f C23 math function
1 parent dfcb548 commit a813c1f

File tree

1 file changed

+34
-3
lines changed

1 file changed

+34
-3
lines changed

libc/utils/MPFRWrapper/MPFRUtils.cpp

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@ class MPFRNumber {
134134
mpfr_set(value, other.value, mpfr_rounding);
135135
}
136136

137+
MPFRNumber(const MPFRNumber &other, unsigned int precision)
138+
: mpfr_precision(precision), mpfr_rounding(other.mpfr_rounding) {
139+
mpfr_init2(value, mpfr_precision);
140+
mpfr_set(value, other.value, mpfr_rounding);
141+
}
142+
137143
~MPFRNumber() { mpfr_clear(value); }
138144

139145
MPFRNumber &operator=(const MPFRNumber &rhs) {
@@ -229,10 +235,28 @@ class MPFRNumber {
229235
return result;
230236
}
231237

232-
MPFRNumber exp2m1() const {
238+
MPFRNumber
239+
exp2m1([[maybe_unused]] const MPFRNumber &underflow_rndz_fallback) const {
240+
// TODO: Only use mpfr_exp2m1 once CI and buildbots get MPFR >= 4.2.0.
241+
#if MPFR_VERSION_MAJOR > 4 || \
242+
(MPFR_VERSION_MAJOR == 4 && MPFR_VERSION_MINOR >= 2)
233243
MPFRNumber result(*this);
234244
mpfr_exp2m1(result.value, value, mpfr_rounding);
235245
return result;
246+
#else
247+
MPFRNumber result(*this, mpfr_precision * 8);
248+
mpfr_exp2(result.value, value, mpfr_rounding);
249+
250+
if (mpfr_underflow_p()) {
251+
mpfr_clear_underflow();
252+
253+
if (mpfr_rounding == MPFR_RNDZ)
254+
return underflow_rndz_fallback;
255+
}
256+
257+
mpfr_sub_ui(result.value, result.value, 1, mpfr_rounding);
258+
return result;
259+
#endif
236260
}
237261

238262
MPFRNumber exp10() const {
@@ -576,8 +600,15 @@ unary_operation(Operation op, InputType input, unsigned int precision,
576600
return mpfrInput.exp();
577601
case Operation::Exp2:
578602
return mpfrInput.exp2();
579-
case Operation::Exp2m1:
580-
return mpfrInput.exp2m1();
603+
case Operation::Exp2m1: {
604+
constexpr InputType UNDERFLOW_RNDZ_FALLBACK =
605+
FPBits<InputType>::create_value(Sign::NEG,
606+
-1 + FPBits<InputType>::EXP_BIAS,
607+
FPBits<InputType>::SIG_MASK)
608+
.get_val();
609+
MPFRNumber underflow_rndz_fallback(UNDERFLOW_RNDZ_FALLBACK);
610+
return mpfrInput.exp2m1(underflow_rndz_fallback);
611+
}
581612
case Operation::Exp10:
582613
return mpfrInput.exp10();
583614
case Operation::Expm1:

0 commit comments

Comments
 (0)