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}