Skip to main content

malachite_float/float/arithmetic/
power_of_2_x_minus_1.rs

1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MPFR Library.
4//
5//      Copyright 2001-2025 Free Software Foundation, Inc.
6//
7//      Contributed by the Pascaline and Caramba projects, INRIA.
8//
9// This file is part of Malachite.
10//
11// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
12// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
13// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
14
15use crate::InnerFloat::{Infinity, NaN, Zero};
16use crate::float::arithmetic::exp::{exp_overflow, one_neighbor};
17use crate::float::arithmetic::exp_x_minus_1::exp_x_minus_1_rational_near_zero;
18use crate::float::arithmetic::round_near_x::float_round_near_x;
19use crate::{
20    Float, emulate_float_to_float_fn, emulate_rational_to_float_fn, float_infinity, float_nan,
21    float_zero, floor_and_ceiling,
22};
23use core::cmp::Ordering::{self, *};
24use core::cmp::max;
25use malachite_base::num::arithmetic::traits::{
26    CeilingLogBase2, PowerOf2, PowerOf2XMinus1, PowerOf2XMinus1Assign,
27};
28use malachite_base::num::basic::floats::PrimitiveFloat;
29use malachite_base::num::basic::integers::PrimitiveInt;
30use malachite_base::num::basic::traits::{NegativeOne, NegativeZero, One, Zero as ZeroTrait};
31use malachite_base::num::comparison::traits::PartialOrdAbs;
32use malachite_base::num::conversion::traits::{ExactFrom, IsInteger, RoundingFrom, SaturatingFrom};
33use malachite_base::num::logic::traits::SignificantBits;
34use malachite_base::rounding_modes::RoundingMode::{self, *};
35use malachite_nz::integer::Integer;
36use malachite_nz::natural::arithmetic::float_extras::float_can_round;
37use malachite_nz::platform::Limb;
38use malachite_q::Rational;
39
40// The outcome of the "small |x|" branch of `mpfr_exp2m1`.
41enum Small {
42    // x * ln(2) enables correct rounding; the contained `Float` is the approximation to round.
43    Round(Float),
44    // The small approximation did not enable correct rounding.
45    NotSmall,
46}
47
48// In case x is small in absolute value, 2^x - 1 ~ x * ln(2). If this is enough to deduce correct
49// rounding, return the approximation that will be rounded to get the result; otherwise signal that
50// the small case does not apply. (The underflow case, where x * ln(2) is smaller than the minimum
51// positive `Float`, is handled up front in `power_of_2_x_minus_1_prec_round_normal`, so here x *
52// ln(2) is always representable.)
53//
54// This is mpfr_exp2m1_small from exp2m1.c, MPFR 4.2.2.
55fn power_of_2_x_minus_1_small(x: &Float, prec: u64, working_prec: u64, rm: RoundingMode) -> Small {
56    let ex = i64::from(x.get_exponent().unwrap());
57    // For |x| < 0.125, we have |2^x - 1 - x * ln(2)| < x^2 / 4. Otherwise the approximation is not
58    // accurate enough.
59    if ex > -3 {
60        return Small::NotSmall;
61    }
62    // t = ln(2) * x * (1 + theta)^2 with |theta| <= 2^(-working_prec).
63    let t = Float::ln_2_prec(working_prec)
64        .0
65        .mul_prec_val_ref(x, working_prec)
66        .0;
67    let exp_t = i64::from(t.get_exponent().unwrap());
68    // |t - x * ln(2)| < 3 * 2^(EXP(t) - working_prec), and |x^2 / 4| < 2^e * 2^(EXP(t) -
69    // working_prec), so |t - (2^x - 1)| < 2^e * 2^(EXP(t) - working_prec).
70    let e = (ex << 1) - 2 + i64::exact_from(working_prec) - exp_t;
71    let e = if e <= 1 { 2 + i64::from(e == 1) } else { e + 1 };
72    if float_can_round(
73        t.significand_ref().unwrap(),
74        working_prec - u64::exact_from(e),
75        prec,
76        rm,
77    ) {
78        Small::Round(t)
79    } else {
80        Small::NotSmall
81    }
82}
83
84// This is mpfr_exp2m1 from exp2m1.c, MPFR 4.2.2, where the input is finite and nonzero.
85fn power_of_2_x_minus_1_prec_round_normal(
86    x: &Float,
87    prec: u64,
88    rm: RoundingMode,
89) -> (Float, Ordering) {
90    // Huge negative x: if |x| > prec + 1 then 2^x < (1/4) ulp(-1), so 2^x - 1 rounds to -1 (for
91    // Floor, Up, and Nearest) or to nextabove(-1) (for Ceiling and Down).
92    if x.is_sign_negative() && x.gt_abs(&(prec + 1)) {
93        return match rm {
94            Ceiling | Down => (-one_neighbor(prec, false), Greater),
95            Floor | Up | Nearest => (-Float::one_prec(prec), Less),
96            Exact => panic!("Inexact power_of_2_x_minus_1"),
97        };
98    }
99    // Tiny x: 2^x - 1 ~ x * ln(2). Because ln(2) < 1, this can be smaller than the minimum positive
100    // `Float` even when x is not (an underflow that e^x - 1 ~ x never produces). Malachite's
101    // bounded-exponent arithmetic cannot represent such a sub-minimal intermediate, so the Ziv loop
102    // below would never converge; detect and round the underflow here. This is only possible in the
103    // smallest binade (|x| >= min_positive), where |2^x - 1| ~ |x| ln(2) lies in (min_positive / 2,
104    // min_positive): the lower bound is min_positive * ln(2) > min_positive / 2, so a `Nearest`
105    // result always rounds away from zero. Rounding ln(2) to `x`'s precision (rather than the
106    // output precision, which may be enormous) is enough to resolve which side of min_positive the
107    // result lies on.
108    let ex = i64::from(x.get_exponent().unwrap());
109    if ex <= i64::from(Float::MIN_EXPONENT) {
110        // Scale x to exponent 1 before converting to a `Rational`: x itself sits in the smallest
111        // binade, so an exact `Rational` for it would carry a ~2^30-bit power-of-2 denominator
112        // (~128 MB). With x' = x * 2^(1 - EXP(x)), a small number, the test |x ln(2)| <
113        // 2^(MIN_EXPONENT - 1) becomes |x' ln(2)| < 2^(MIN_EXPONENT - ex), which is a comparison of
114        // floor(log_2 |x' ln(2)|) against the exponent -- no power-of-2 `Rational` needed. ln(2) is
115        // bracketed and the brackets widened until both ends decide the comparison the same way; a
116        // one-shot approximation would leave the decision to the table-maker's dilemma. (x ln(2) is
117        // irrational, so the widening always terminates.)
118        let x_scaled = x >> (ex - 1);
119        let xs_r = Rational::exact_from(&x_scaled);
120        let bound = i64::from(Float::MIN_EXPONENT) - ex;
121        let mut p = x.significant_bits() + Limb::WIDTH;
122        let below = loop {
123            let (ln_2_lo, ln_2_hi) = floor_and_ceiling(Float::ln_2_prec_round(p, Floor));
124            let f_lo = (&xs_r * Rational::exact_from(&ln_2_lo)).floor_log_base_2_abs() < bound;
125            let f_hi = (&xs_r * Rational::exact_from(&ln_2_hi)).floor_log_base_2_abs() < bound;
126            if f_lo == f_hi {
127                break f_lo;
128            }
129            p <<= 1;
130        };
131        if below {
132            let neg = x.is_sign_negative();
133            // A magnitude in (min_positive / 2, min_positive) rounds either away from zero (to
134            // +/-min_positive) or toward zero (to +/-0), depending on the rounding mode.
135            let away = match rm {
136                Up | Nearest => true,
137                Ceiling => !neg,
138                Floor => neg,
139                Down => false,
140                Exact => panic!("Inexact power_of_2_x_minus_1"),
141            };
142            return if away {
143                let m = Float::min_positive_value_prec(prec);
144                if neg { (-m, Less) } else { (m, Greater) }
145            } else if neg {
146                (Float::NEGATIVE_ZERO, Greater)
147            } else {
148                (Float::ZERO, Less)
149            };
150        }
151    }
152    // Deeply negative x: 2^x lies below the smallest positive Float, so the loop's
153    // `power_of_2_of_float` would return 0 or the minimum positive value with unbounded relative
154    // error, and the result could never be certified. Since the huge-negative shortcut above did
155    // not fire, |x| <= prec + 1, so the bits of 2^x land within the output's prec-bit window and
156    // must be computed for real.
157    if *x < const { Float::MIN_EXPONENT as i64 - 1 } {
158        return power_of_2_x_minus_1_deep_negative(x, prec, rm);
159    }
160    // Compute the precision of the intermediary variable: the optimal number of bits, see
161    // algorithms.tex.
162    let mut working_prec = prec + prec.ceiling_log_base_2() + 6;
163    let mut increment = Limb::WIDTH;
164    loop {
165        // 2^x may overflow.
166        let (mut t, o1) = Float::power_of_2_of_float_prec_ref(x, working_prec);
167        if t.is_infinite() {
168            // 2^x overflowed at the working precision. For prec < MAX_EXPONENT this decides the
169            // result: 2^x >= (1 - 2^-working_prec) * 2^MAX_EXPONENT, so 2^x - 1 exceeds the largest
170            // prec-bit value and rounds exactly as an overflow does. At prec >= MAX_EXPONENT the
171            // values just below 2^MAX_EXPONENT are representable, and the intermediate overflow no
172            // longer implies one in the result:
173            // - x = MAX_EXPONENT exactly (the only integer reaching this branch without a true
174            //   overflow): 2^x - 1 has exponent MAX_EXPONENT and is exactly representable;
175            //   materialize it, like the Rational path does.
176            // - x > MAX_EXPONENT: a true overflow. Even for x barely above (x = MAX_EXPONENT +
177            //   2^-k), the result exceeds max_finite and lies at least 2^(MAX_EXPONENT - k) ln(2)
178            //   above 2^MAX_EXPONENT - 1, which clears the `Nearest` overflow threshold for any k
179            //   below MAX_EXPONENT -- and reaching k >= MAX_EXPONENT would take an x of more than
180            //   2^31 bits.
181            // - x < MAX_EXPONENT (necessarily a non-integer here): 2^x < 2^MAX_EXPONENT strictly,
182            //   so the overflow is an artifact of rounding 2^x up at the working precision; growing
183            //   it far enough (past the distance from x to MAX_EXPONENT) makes 2^x finite, and the
184            //   loop proceeds normally.
185            if prec < Float::MAX_EXPONENT_U64 || *x > Float::MAX_EXPONENT_I64 {
186                return exp_overflow(prec, rm);
187            }
188            if *x == Float::MAX_EXPONENT_I64 {
189                return Float::from_rational_prec_round(
190                    Rational::power_of_2(Float::MAX_EXPONENT_I64) - Rational::ONE,
191                    prec,
192                    rm,
193                );
194            }
195            working_prec += increment;
196            increment = working_prec >> 1;
197            continue;
198        }
199        // 2^x cannot underflow here: that would require x < MIN_EXPONENT - 1, but then the deep-
200        // negative case above would already have returned. Integer x: 2^x is exact, so the result
201        // is simply round(2^x - 1).
202        if o1 == Equal {
203            return t.sub_prec_round(Float::ONE, prec, rm);
204        }
205        // 2^x is inexact, so x is not an integer and 2^x - 1 is transcendental: never exact.
206        assert_ne!(rm, Exact, "Inexact power_of_2_x_minus_1");
207        let exp_te = i64::from(t.get_exponent().unwrap());
208        t.sub_prec_assign(Float::ONE, working_prec); // 2^x - 1
209        if t != 0u32 {
210            let exp_t = i64::from(t.get_exponent().unwrap());
211            // The error estimate (cf. exp2m1.c): err = max(EXP(2^x) - EXP(2^x - 1), 0) + 1.
212            let err = u64::exact_from(max(exp_te - exp_t, 0) + 1);
213            if float_can_round(t.significand_ref().unwrap(), working_prec - err, prec, rm) {
214                return Float::from_float_prec_round(t, prec, rm);
215            }
216        }
217        // For small |x|, 2^x - 1 ~ x * ln(2); this may enable correct rounding when the
218        // cancellation in 2^x - 1 above does not. We must retry it at each Ziv step, since the
219        // multiplication x * ln(2) might not give correct rounding at the first loop.
220        match power_of_2_x_minus_1_small(x, prec, working_prec, rm) {
221            Small::Round(t) => return Float::from_float_prec_round(t, prec, rm),
222            Small::NotSmall => {}
223        }
224        // Increase the precision.
225        working_prec += increment;
226        increment = working_prec >> 1;
227    }
228}
229
230// Computes 2^x - 1 for a Float x < MIN_EXPONENT - 1 (so that 2^x is smaller than the smallest
231// positive Float) with |x| <= prec + 1 (larger |x| is handled by the caller's -1-rounding
232// shortcut). The result is -1 + 2^x, and since |x| <= prec + 1 the bits of 2^x land within the
233// output's prec-bit window, even though 2^x itself is not representable. Split x = -s + f with
234// integer s and f in [0, 1): 2^x = 2^f * 2^-s, where 2^f is a normal Float in [1, 2); the scaling
235// by 2^-s and the subtraction of 1 are exact over `Rational`s, whose size stays O(prec) because s
236// <= prec + 2. For integer x the result is an exact dyadic rational; otherwise 2^f is bracketed and
237// the bracket is tightened Ziv-style. The initial working precision is small: the leading s - 1
238// bits of the result are a run of ones, so only about prec - s bits of 2^f are needed.
239fn power_of_2_x_minus_1_deep_negative(x: &Float, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
240    let xr = Rational::exact_from(x);
241    let neg_n = -Integer::rounding_from(&xr, Floor).0; // = |floor(x)|, since x < 0
242    // The conversion fails only for |x| >= 2^63; but |x| <= prec + 1, and a result of such a
243    // precision could never be materialized at all.
244    let shift = u64::exact_from(&neg_n);
245    let frac = xr + Rational::from(neg_n); // x - floor(x), in [0, 1)
246    if frac == 0u32 {
247        // x is an integer, so -1 + 2^x is an exact dyadic rational needing |x| + 1 bits.
248        return Float::from_rational_prec_round(
249            Rational::power_of_2(-i64::exact_from(shift)) - Rational::ONE,
250            prec,
251            rm,
252        );
253    }
254    // x is not an integer, so 2^x - 1 is irrational: never exact.
255    assert_ne!(rm, Exact, "Inexact power_of_2_x_minus_1");
256    // The fractional part of the Float x is a dyadic rational, exactly representable with as many
257    // bits as its numerator has.
258    let frac_prec = frac.numerator_ref().significant_bits();
259    let frac = Float::from_rational_prec_round(frac, frac_prec, Exact).0;
260    let mut working_prec = prec.saturating_sub(shift) + Limb::WIDTH;
261    let mut increment = Limb::WIDTH;
262    loop {
263        // 2^frac is in (1, 2) and irrational, so the Floor rounding is strict: the true value lies
264        // strictly between u_lo and u_hi.
265        let u = Float::power_of_2_of_float_prec_round_ref(&frac, working_prec, Floor);
266        let (u_lo, u_hi) = floor_and_ceiling(u);
267        let (f_lo, mut o_lo) = Float::from_rational_prec_round(
268            (Rational::exact_from(&u_lo) >> shift) - Rational::ONE,
269            prec,
270            rm,
271        );
272        let (f_hi, mut o_hi) = Float::from_rational_prec_round(
273            (Rational::exact_from(&u_hi) >> shift) - Rational::ONE,
274            prec,
275            rm,
276        );
277        // A bound that is exactly representable at `prec` rounds with `Equal`, but the true value
278        // lies strictly between the bounds, so the other bound's ordering is the true one; treat
279        // the exact bound as agreeing with it. (Both cannot be `Equal` with equal values, since the
280        // bounds are distinct.)
281        if o_lo == Equal {
282            o_lo = o_hi;
283        }
284        if o_hi == Equal {
285            o_hi = o_lo;
286        }
287        if o_lo == o_hi && f_lo == f_hi {
288            return (f_lo, o_lo);
289        }
290        working_prec += increment;
291        increment = working_prec >> 1;
292    }
293}
294
295// Computes 2^x - 1 for a nonzero `Rational` `x` with `|x| < 2^MIN_EXPONENT`, too small to bracket
296// between `Float`s. Since 2^x - 1 = expm1(x ln(2)), bracketing ln(2) between two `Rational`s (from
297// a single directed ln(2) computation) and applying `exp_x_minus_1_rational_near_zero` to each
298// product brackets the result; that helper's `from_rational_prec_round` calls perform the underflow
299// rounding, which matters here because |2^x - 1| ~ |x| ln(2) can fall below the smallest positive
300// `Float` (ln(2) < 1). expm1 is increasing, and x ln(2) is increasing in ln(2) for x > 0 and
301// decreasing for x < 0, so the bracket ends order accordingly. The bracket width is about |x| 2^-w
302// for a working ln(2) precision w, while the result's ulp is about 2^(EXP(x) - prec), so w ~ prec +
303// slack suffices regardless of how tiny x is; the Ziv loop widens w if not.
304fn power_of_2_x_minus_1_rational_near_zero(
305    x: &Rational,
306    prec: u64,
307    rm: RoundingMode,
308) -> (Float, Ordering) {
309    let positive = *x > 0u32;
310    let mut working_prec = prec + Limb::WIDTH;
311    let mut increment = Limb::WIDTH;
312    loop {
313        // ln_2_lo <= ln(2) <= ln_2_hi, as exact Rationals, from a single ln(2) computation.
314        let (ln_2_lo, ln_2_hi) = floor_and_ceiling(Float::ln_2_prec_round(working_prec, Floor));
315        let ln_2_lo = Rational::exact_from(&ln_2_lo);
316        let ln_2_hi = Rational::exact_from(&ln_2_hi);
317        let (a_lo, a_hi) = if positive {
318            (x * ln_2_lo, x * ln_2_hi)
319        } else {
320            (x * ln_2_hi, x * ln_2_lo)
321        };
322        let (f_lo, o_lo) = exp_x_minus_1_rational_near_zero(&a_lo, prec, rm);
323        let (f_hi, o_hi) = exp_x_minus_1_rational_near_zero(&a_hi, prec, rm);
324        if o_lo == o_hi && f_lo == f_hi {
325            return (f_lo, o_lo);
326        }
327        working_prec += increment;
328        increment = working_prec >> 1;
329    }
330}
331
332// Computes 2^x - 1 for a nonzero `Rational` `x`, rounded to precision `prec` with rounding mode
333// `rm`. (2^0 - 1 = 0 is handled by the caller.) Unlike expm1, the result is exactly representable
334// for some inputs: an integer x makes 2^x - 1 an exact dyadic rational, so those are computed
335// directly (the Ziv squeeze below could never certify one); every other rational x gives an
336// irrational result.
337fn power_of_2_x_minus_1_rational_helper(
338    x: &Rational,
339    prec: u64,
340    rm: RoundingMode,
341) -> (Float, Ordering) {
342    if x.is_integer() {
343        let n = Integer::exact_from(x);
344        return if n > Float::MAX_EXPONENT_I64 {
345            // 2^n - 1 has exponent n, beyond the maximum.
346            exp_overflow(prec, rm)
347        } else if n == Float::MAX_EXPONENT_I64 {
348            // 2^n is not representable, but 2^n - 1 (with exponent n) is -- though only with at
349            // least n bits of precision. At smaller precisions it rounds exactly like an overflow:
350            // down to the largest finite value, or up (and to nearest) past it.
351            if prec >= Float::MAX_EXPONENT_U64 {
352                Float::from_rational_prec_round(
353                    Rational::power_of_2(i64::exact_from(&n)) - Rational::ONE,
354                    prec,
355                    rm,
356                )
357            } else {
358                exp_overflow(prec, rm)
359            }
360        } else if n >= i64::from(Float::MIN_EXPONENT) - 1 {
361            // 2^n is representable, so round the exact difference 2^n - 1 directly.
362            Float::power_of_2(i64::exact_from(&n)).sub_prec_round(Float::ONE, prec, rm)
363        } else {
364            // n <= MIN_EXPONENT - 2: the result is -1 + 2^n with 2^n below the smallest positive
365            // Float. It is exactly representable with -n bits; at prec = -n - 1 it sits exactly on
366            // the `Nearest` midpoint between -1 and its toward-zero neighbor. Both cases
367            // materialize the exact rational (proportional to prec). (The i64 conversion would fail
368            // only for |n| >= 2^63, where prec >= |n| - 1 means the result could not be
369            // materialized at all.)
370            if n >= -i64::exact_from(prec) - 1 {
371                Float::from_rational_prec_round(
372                    Rational::power_of_2(i64::exact_from(&n)) - Rational::ONE,
373                    prec,
374                    rm,
375                )
376            } else {
377                // The result is within 2^n <= (1/8) ulp(-1) of -1, and err = -n >= prec + 2 exceeds
378                // prec + 1 while strictly bounding the error (|result + 1| = 2^n < 2^(1 - err)), as
379                // `float_round_near_x`'s contract requires; rounding from -1 always resolves.
380                assert_ne!(rm, Exact, "Inexact power_of_2_x_minus_1");
381                let err = u64::saturating_from(&-&n);
382                float_round_near_x(&Float::NEGATIVE_ONE, err, false, prec, rm).unwrap()
383            }
384        };
385    }
386    // The result for a non-integer rational is irrational, hence never exactly representable.
387    assert_ne!(rm, Exact, "Inexact power_of_2_x_minus_1");
388    let positive = *x > 0u32;
389    let exp_x = x.floor_log_base_2_abs() + 1; // the MPFR-style exponent of x
390    // x is too small to be represented as a normal Float (|x| < 2^MIN_EXPONENT). The squeeze below
391    // cannot bracket it (its Float bounds would be 0), so use the ln(2)-bracketing helper, which
392    // also performs the underflow rounding that |x| ln(2) may need.
393    if exp_x <= Float::MIN_EXPONENT_I64 {
394        return power_of_2_x_minus_1_rational_near_zero(x, prec, rm);
395    }
396    // |x| is too large to be a finite Float. For x > 0, 2^x - 1 overflows; for x < 0 it tends to
397    // -1. Smaller x that still overflow or round to -1 are handled by the Float function inside the
398    // squeeze below.
399    if exp_x >= Float::MAX_EXPONENT_I64 {
400        if positive {
401            return exp_overflow(prec, rm);
402        }
403        // 2^x is far below ulp(-1) at any precision, so 2^x - 1 rounds to -1 or its toward-zero
404        // neighbor.
405        let err = Float::MAX_EXPONENT_U64;
406        if let Some(result) = float_round_near_x(&Float::NEGATIVE_ONE, err, false, prec, rm) {
407            return result;
408        }
409        // `prec` is enormous (>= MAX_EXPONENT), so `float_round_near_x` cannot resolve the
410        // rounding; but 2^x is still far below ulp(-1), so -1 rounds the same way.
411        return match rm {
412            Ceiling | Down => (-one_neighbor(prec, false), Greater), // -1 + ulp (toward zero)
413            _ => (-Float::one_prec(prec), Less),                     // -1
414        };
415    }
416    // General case: bracket x between the Floats x_lo <= x <= x_hi, apply 2^x - 1 to both, and
417    // increase the working precision until the two bounds round to the same result. 2^x - 1 is
418    // monotonic, so once the bounds agree the exact result (which lies between them) rounds the
419    // same way. A bound that lands on an integer produces an `Equal` ordering, which cannot match
420    // the other (irrational) bound's; the loop then simply tightens the bracket until neither bound
421    // is an integer.
422    let mut working_prec = prec + 10;
423    let mut increment = Limb::WIDTH;
424    loop {
425        let (x_lo, x_o) = Float::from_rational_prec_round_ref(x, working_prec, Floor);
426        if x_o == Equal {
427            // x is exactly representable at `working_prec`, so the result is simply that of the
428            // Float function.
429            return x_lo.power_of_2_x_minus_1_prec_round(prec, rm);
430        }
431        let (x_lo, x_hi) = floor_and_ceiling((x_lo, x_o));
432        let (e_lo, o_lo) = x_lo.power_of_2_x_minus_1_prec_round_ref(prec, rm);
433        let (e_hi, o_hi) = x_hi.power_of_2_x_minus_1_prec_round_ref(prec, rm);
434        if o_lo == o_hi && e_lo == e_hi {
435            return (e_lo, o_lo);
436        }
437        working_prec += increment;
438        increment = working_prec >> 1;
439    }
440}
441
442impl Float {
443    /// Computes $2^x-1$, rounding the result to the specified precision and with the specified
444    /// rounding mode. The [`Float`] is taken by value.
445    #[inline]
446    pub fn power_of_2_x_minus_1_prec_round(self, prec: u64, rm: RoundingMode) -> (Self, Ordering) {
447        self.power_of_2_x_minus_1_prec_round_ref(prec, rm)
448    }
449
450    /// Computes $2^x-1$, rounding the result to the specified precision and with the specified
451    /// rounding mode. The [`Float`] is taken by reference.
452    #[inline]
453    pub fn power_of_2_x_minus_1_prec_round_ref(
454        &self,
455        prec: u64,
456        rm: RoundingMode,
457    ) -> (Self, Ordering) {
458        assert_ne!(prec, 0);
459        match self {
460            Self(NaN) => (float_nan!(), Equal),
461            float_infinity!() => (float_infinity!(), Equal),
462            // 2^(-inf) - 1 = -1
463            Self(Infinity { sign: false }) => (Self::from_signed_prec(-1i32, prec).0, Equal),
464            // 2^(±0) - 1 = ±0
465            Self(Zero { sign }) => (Self(Zero { sign: *sign }), Equal),
466            _ => power_of_2_x_minus_1_prec_round_normal(self, prec, rm),
467        }
468    }
469
470    /// Computes $2^x-1$, rounding the result to the nearest value of the specified precision. The
471    /// [`Float`] is taken by value.
472    #[inline]
473    pub fn power_of_2_x_minus_1_prec(self, prec: u64) -> (Self, Ordering) {
474        self.power_of_2_x_minus_1_prec_round(prec, Nearest)
475    }
476
477    /// Computes $2^x-1$, rounding the result to the nearest value of the specified precision. The
478    /// [`Float`] is taken by reference.
479    #[inline]
480    pub fn power_of_2_x_minus_1_prec_ref(&self, prec: u64) -> (Self, Ordering) {
481        self.power_of_2_x_minus_1_prec_round_ref(prec, Nearest)
482    }
483
484    /// Computes $2^x-1$, rounding the result with the specified rounding mode. The precision of the
485    /// output is the precision of the input. The [`Float`] is taken by value.
486    #[inline]
487    pub fn power_of_2_x_minus_1_round(self, rm: RoundingMode) -> (Self, Ordering) {
488        let prec = self.significant_bits();
489        self.power_of_2_x_minus_1_prec_round(prec, rm)
490    }
491
492    /// Computes $2^x-1$, rounding the result with the specified rounding mode. The precision of the
493    /// output is the precision of the input. The [`Float`] is taken by reference.
494    #[inline]
495    pub fn power_of_2_x_minus_1_round_ref(&self, rm: RoundingMode) -> (Self, Ordering) {
496        self.power_of_2_x_minus_1_prec_round_ref(self.significant_bits(), rm)
497    }
498
499    /// Computes $2^x-1$ in place, rounding the result to the specified precision and with the
500    /// specified rounding mode.
501    #[inline]
502    pub fn power_of_2_x_minus_1_prec_round_assign(
503        &mut self,
504        prec: u64,
505        rm: RoundingMode,
506    ) -> Ordering {
507        let (result, o) = core::mem::take(self).power_of_2_x_minus_1_prec_round(prec, rm);
508        *self = result;
509        o
510    }
511
512    /// Computes $2^x-1$ in place, rounding the result to the nearest value of the specified
513    /// precision.
514    #[inline]
515    pub fn power_of_2_x_minus_1_prec_assign(&mut self, prec: u64) -> Ordering {
516        self.power_of_2_x_minus_1_prec_round_assign(prec, Nearest)
517    }
518
519    /// Computes $2^x-1$ in place, rounding the result with the specified rounding mode. The
520    /// precision of the output is the precision of the input.
521    #[inline]
522    pub fn power_of_2_x_minus_1_round_assign(&mut self, rm: RoundingMode) -> Ordering {
523        let prec = self.significant_bits();
524        self.power_of_2_x_minus_1_prec_round_assign(prec, rm)
525    }
526
527    #[allow(clippy::needless_pass_by_value)]
528    /// Computes $2^x-1$, where $x$ is a [`Rational`], rounding the result to the specified
529    /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
530    /// [`Rational`] is taken by value.
531    #[inline]
532    pub fn power_of_2_x_minus_1_rational_prec_round(
533        x: Rational,
534        prec: u64,
535        rm: RoundingMode,
536    ) -> (Self, Ordering) {
537        Self::power_of_2_x_minus_1_rational_prec_round_ref(&x, prec, rm)
538    }
539
540    /// Computes $2^x-1$, where $x$ is a [`Rational`], rounding the result to the specified
541    /// precision and with the specified rounding mode and returning the result as a [`Float`]. The
542    /// [`Rational`] is taken by reference.
543    #[inline]
544    pub fn power_of_2_x_minus_1_rational_prec_round_ref(
545        x: &Rational,
546        prec: u64,
547        rm: RoundingMode,
548    ) -> (Self, Ordering) {
549        assert_ne!(prec, 0);
550        if *x == 0u32 {
551            // 2^0 - 1 = 0, exactly.
552            return (float_zero!(), Equal);
553        }
554        power_of_2_x_minus_1_rational_helper(x, prec, rm)
555    }
556
557    /// Computes $2^x-1$, where $x$ is a [`Rational`], rounding the result to the nearest value of
558    /// the specified precision and returning the result as a [`Float`]. The [`Rational`] is taken
559    /// by value.
560    #[inline]
561    pub fn power_of_2_x_minus_1_rational_prec(x: Rational, prec: u64) -> (Self, Ordering) {
562        Self::power_of_2_x_minus_1_rational_prec_round(x, prec, Nearest)
563    }
564
565    /// Computes $2^x-1$, where $x$ is a [`Rational`], rounding the result to the nearest value of
566    /// the specified precision and returning the result as a [`Float`]. The [`Rational`] is taken
567    /// by reference.
568    #[inline]
569    pub fn power_of_2_x_minus_1_rational_prec_ref(x: &Rational, prec: u64) -> (Self, Ordering) {
570        Self::power_of_2_x_minus_1_rational_prec_round_ref(x, prec, Nearest)
571    }
572}
573
574impl PowerOf2XMinus1 for Float {
575    type Output = Self;
576
577    /// Computes $2^x-1$, where $x$ is a [`Float`], taking the [`Float`] by value.
578    #[inline]
579    fn power_of_2_x_minus_1(self) -> Self {
580        let prec = self.significant_bits();
581        self.power_of_2_x_minus_1_prec(prec).0
582    }
583}
584
585impl PowerOf2XMinus1 for &Float {
586    type Output = Float;
587
588    /// Computes $2^x-1$, where $x$ is a [`Float`], taking the [`Float`] by reference.
589    #[inline]
590    fn power_of_2_x_minus_1(self) -> Float {
591        self.power_of_2_x_minus_1_prec_round_ref(self.significant_bits(), Nearest)
592            .0
593    }
594}
595
596impl PowerOf2XMinus1Assign for Float {
597    /// Computes $2^x-1$, where $x$ is a [`Float`], in place.
598    #[inline]
599    fn power_of_2_x_minus_1_assign(&mut self) {
600        let prec = self.significant_bits();
601        self.power_of_2_x_minus_1_prec_round_assign(prec, Nearest);
602    }
603}
604
605/// Computes $2^x-1$ for a primitive float. The result is correctly rounded. Using this function is
606/// more accurate than computing `x.exp2() - 1.0` with the primitive float functions: that
607/// subtraction loses all precision when $x$ is small (where $2^x-1\approx x\ln 2$ but $2^x$ rounds
608/// to 1), and the standard library's `exp2` is not correctly rounded to begin with.
609///
610/// $$
611/// f(x) = 2^x-1+\varepsilon.
612/// $$
613/// - If $2^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
614/// - If $2^x-1$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |2^x-1|\rfloor-p}$,
615///   where $p$ is the precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
616///   [`f64`], but less if the output is subnormal).
617///
618/// Special cases:
619/// - $f(\text{NaN})=\text{NaN}$
620/// - $f(\infty)=\infty$
621/// - $f(-\infty)=-1$
622/// - $f(\pm0.0)=\pm0.0$
623///
624/// # Worst-case complexity
625/// Constant time and additional memory.
626///
627/// # Examples
628/// ```
629/// use malachite_base::num::basic::traits::NegativeInfinity;
630/// use malachite_base::num::float::NiceFloat;
631/// use malachite_float::float::arithmetic::power_of_2_x_minus_1::*;
632///
633/// assert!(primitive_float_power_of_2_x_minus_1(f32::NAN).is_nan());
634/// assert_eq!(
635///     NiceFloat(primitive_float_power_of_2_x_minus_1(f32::INFINITY)),
636///     NiceFloat(f32::INFINITY)
637/// );
638/// assert_eq!(
639///     NiceFloat(primitive_float_power_of_2_x_minus_1(f32::NEGATIVE_INFINITY)),
640///     NiceFloat(-1.0)
641/// );
642/// assert_eq!(
643///     NiceFloat(primitive_float_power_of_2_x_minus_1(3.0f32)),
644///     NiceFloat(7.0)
645/// );
646/// ```
647#[inline]
648#[allow(clippy::type_repetition_in_bounds)]
649pub fn primitive_float_power_of_2_x_minus_1<T: PrimitiveFloat>(x: T) -> T
650where
651    Float: From<T> + PartialOrd<T>,
652    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
653{
654    emulate_float_to_float_fn(Float::power_of_2_x_minus_1_prec, x)
655}
656
657/// Computes $2^x-1$, where $x$ is a [`Rational`], returning the result as a primitive float. The
658/// result is correctly rounded.
659///
660/// $$
661/// f(x) = 2^x-1+\varepsilon.
662/// $$
663/// - If $2^x-1$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
664/// - If $2^x-1$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |2^x-1|\rfloor-p}$,
665///   where $p$ is the precision of the output (typically 24 if `T` is a [`f32`] and 53 if `T` is a
666///   [`f64`], but less if the output is subnormal).
667///
668/// Special cases:
669/// - $f(0)=0$
670///
671/// # Worst-case complexity
672/// Constant time and additional memory.
673///
674/// # Examples
675/// ```
676/// use malachite_base::num::float::NiceFloat;
677/// use malachite_float::float::arithmetic::power_of_2_x_minus_1::*;
678/// use malachite_q::Rational;
679///
680/// assert_eq!(
681///     NiceFloat(primitive_float_power_of_2_x_minus_1_rational::<f32>(
682///         &Rational::from(3u32)
683///     )),
684///     NiceFloat(7.0)
685/// );
686/// assert_eq!(
687///     NiceFloat(primitive_float_power_of_2_x_minus_1_rational::<f32>(
688///         &Rational::from_signeds(-1i32, 2)
689///     )),
690///     NiceFloat(-0.29289323)
691/// );
692/// ```
693#[inline]
694#[allow(clippy::type_repetition_in_bounds)]
695pub fn primitive_float_power_of_2_x_minus_1_rational<T: PrimitiveFloat>(x: &Rational) -> T
696where
697    Float: PartialOrd<T>,
698    for<'a> T: ExactFrom<&'a Float> + RoundingFrom<&'a Float>,
699{
700    emulate_rational_to_float_fn(Float::power_of_2_x_minus_1_rational_prec_ref, x)
701}