@@ -134,6 +134,12 @@ class MPFRNumber {
134
134
mpfr_set (value, other.value , mpfr_rounding);
135
135
}
136
136
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
+
137
143
~MPFRNumber () { mpfr_clear (value); }
138
144
139
145
MPFRNumber &operator =(const MPFRNumber &rhs) {
@@ -229,10 +235,28 @@ class MPFRNumber {
229
235
return result;
230
236
}
231
237
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 )
233
243
MPFRNumber result (*this );
234
244
mpfr_exp2m1 (result.value , value, mpfr_rounding);
235
245
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
236
260
}
237
261
238
262
MPFRNumber exp10 () const {
@@ -576,8 +600,15 @@ unary_operation(Operation op, InputType input, unsigned int precision,
576
600
return mpfrInput.exp ();
577
601
case Operation::Exp2:
578
602
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
+ }
581
612
case Operation::Exp10:
582
613
return mpfrInput.exp10 ();
583
614
case Operation::Expm1:
0 commit comments