malachite_float/float/arithmetic/add_mul.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// This file is part of Malachite.
8//
9// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
10// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
11// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
12
13use crate::InnerFloat::{Finite, Infinity, NaN, Zero};
14use crate::{
15 Float, emulate_float_float_float_to_float_fn, emulate_float_float_to_float_fn,
16 float_either_infinity, float_either_zero, float_infinity, float_nan, float_negative_infinity,
17 significand_bits,
18};
19use core::cmp::Ordering::{self, *};
20use core::cmp::{max, min};
21use malachite_base::max;
22use malachite_base::num::arithmetic::traits::{
23 AddMul, AddMulAssign, DivMod, ShlRoundAssign, UnsignedAbs,
24};
25use malachite_base::num::basic::floats::PrimitiveFloat;
26use malachite_base::num::basic::traits::{NegativeZero, One, Zero as ZeroTrait};
27use malachite_base::num::conversion::traits::ExactFrom;
28use malachite_base::num::logic::traits::SignificantBits;
29use malachite_base::rounding_modes::RoundingMode::{self, *};
30use malachite_nz::integer::Integer;
31use malachite_nz::natural::Natural;
32use malachite_q::Rational;
33
34// If the product's exponent reaches this bound, the sum overflows regardless of the addend, whose
35// magnitude is less than 2^MAX_EXPONENT.
36const SURE_OVERFLOW_EXPONENT: i64 = Float::MAX_EXPONENT_I64 + 3;
37
38// The sign of a `Float` that is not NaN. `true` means positive.
39pub(crate) fn float_sign(x: &Float) -> bool {
40 match x {
41 Float(Infinity { sign } | Zero { sign } | Finite { sign, .. }) => *sign,
42 _ => panic!(),
43 }
44}
45
46// Rounds (A + P) / den to `prec` bits with rounding mode `rm`, where A = ±ma * 2^ea and P = ±mp *
47// 2^ep are exact scaled integers: ma and mp are positive, and ea and ep are the exponents of their
48// least significant bits. In the Float-Float case den is 1, and this stands in for the UBF
49// (unbounded-float) machinery that mpfr_fma uses when the product x * y lies outside the
50// representable exponent range: the product is kept in exact integer form instead of as an
51// unbounded float, and a single rounding produces the result. The mixed Float-Rational functions
52// pass the identity x + y(n/d) = (xd + yn)/d through the same core: both numerators share the
53// denominator, so the magnitude comparisons below are unaffected by it.
54//
55// The operands' bit ranges may be separated by an exponent gap of up to about 2^31, and aligning
56// them in full would materialize gap-sized integers. Instead the alignment is clamped: the smaller
57// operand is never placed more than prec + den.significant_bits() + 8 bits below the larger one's
58// least significant bit. Bits truncated by the clamp are dropped toward the dominant operand (the
59// truncated numerator underestimates the true magnitude: the smaller operand is rounded down when
60// it reinforces the sum and up when it opposes it), and their existence is recorded in a sticky
61// flag that joins the final division's remainder, placing the computed value and the true value
62// strictly between the same rounding boundaries.
63#[allow(clippy::too_many_arguments)]
64pub(crate) fn add_scaled_round(
65 sa: bool,
66 ma: &Natural,
67 ea: i64,
68 sp: bool,
69 mp: &Natural,
70 ep: i64,
71 den: &Natural,
72 prec: u64,
73 rm: RoundingMode,
74) -> (Float, Ordering) {
75 let am = ea + i64::exact_from(ma.significant_bits());
76 let pm = ep + i64::exact_from(mp.significant_bits());
77 // the operand with the greater most-significant-bit exponent dominates: its magnitude is at
78 // least 2^(dm - 1), and the other's is less than 2^tm <= 2^dm
79 let ((sd, _, _, dm), (st, _, _, tm)) = if pm > am {
80 ((sp, mp, ep, pm), (sa, ma, ea, am))
81 } else {
82 ((sa, ma, ea, am), (sp, mp, ep, pm))
83 };
84 // Deep cancellation is only possible when the operands' signs oppose and their magnitudes are
85 // within a factor of 2 of each other; the least-significant-bit gap is then at most the smaller
86 // operand's bit length, so full alignment is input-sized and the clamp is skipped. In every
87 // other case the sum's most significant bit is within 2 of the dominant operand's, and bits
88 // more than prec + den.significant_bits() + 8 below it cannot affect the rounding beyond a
89 // sticky. The clamp is also capped at the higher of the two least-significant-bit exponents, so
90 // that at most one operand is ever truncated and the sum underestimates the true magnitude by
91 // less than one unit in the last place kept.
92 let e_lo = min(ea, ep);
93 let e_hi = max(ea, ep);
94 let m = if st != sd && tm >= dm - 1 {
95 e_lo
96 } else {
97 max(
98 e_lo,
99 min(
100 e_hi,
101 dm.saturating_sub(i64::exact_from(prec + den.significant_bits() + 8)),
102 ),
103 )
104 };
105 // Truncating an operand at the clamp drops its low bits in the direction that makes the sum
106 // underestimate the true magnitude: toward zero for the operand that reinforces the dominant
107 // sign, and away from zero for the operand that opposes it.
108 let mut sticky_extra = false;
109 let mut part = |sign: bool, mag: &Natural, e_lsb: i64| {
110 if e_lsb >= m {
111 Integer::from_sign_and_abs(sign, mag << u64::exact_from(e_lsb - m))
112 } else {
113 let d = u64::exact_from(m - e_lsb);
114 let mut t = mag >> d;
115 if mag.trailing_zeros().unwrap() < d {
116 sticky_extra = true;
117 if sign != sd {
118 t += Natural::ONE;
119 }
120 }
121 Integer::from_sign_and_abs(sign, t)
122 }
123 };
124 let vd = part(sa, ma, ea);
125 let vt = part(sp, mp, ep);
126 let v = vd + vt;
127 if v == 0u32 {
128 // Exact cancellation: unreachable from the fma callers, which only come here when the
129 // product's magnitude range and the addend's are disjoint, but reachable from the mixed
130 // Float-Rational callers, as in 2 + 1 * (-2), and from the fmma callers, whose two products
131 // can cancel exactly even when both are out of range. The clamp cannot produce a zero,
132 // since it only fires when the dominant operand towers over the other, so the sum is exact
133 // here. The zero's sign follows the addition rule.
134 return (
135 if rm == Floor {
136 Float::NEGATIVE_ZERO
137 } else {
138 Float::ZERO
139 },
140 Equal,
141 );
142 }
143 // As in rem1_core: when the value is exact, the denominator is 1, and the result's exponent is
144 // strictly inside the representable range, round the integer once and shift exactly.
145 let e = i64::exact_from(v.significant_bits()) + m;
146 if !sticky_extra && *den == 1u32 && e > Float::MIN_EXPONENT_I64 && e < Float::MAX_EXPONENT_I64 {
147 let (f, o) = Float::from_integer_prec_round(v, prec, rm);
148 (f << m, o)
149 } else {
150 // Divide before shifting: materializing v / den * 2^m as a Rational would build a
151 // 2^|m|-sized shift factor whenever the result is far outside the exponent range. Instead
152 // the quotient is taken with enough guard bits for correct rounding, a sticky bit records a
153 // nonzero remainder or clamped-away bits, and the exact power-of-2 shift is applied
154 // afterwards with a saturating shl_round -- the same round-then-check-range order as MPFR.
155 let (sv, va) = (v >= 0u32, v.unsigned_abs());
156 let k = (prec + 4 + den.significant_bits()).saturating_sub(va.significant_bits());
157 let (w, r) = (va << k).div_mod(den);
158 let w2 = if r == 0u32 && !sticky_extra {
159 w << 1u32
160 } else {
161 // the sticky bit makes the padded quotient odd, placing it strictly between the same
162 // rounding boundaries as the true quotient
163 (w << 1u32) + Natural::ONE
164 };
165 let (mut f, o) =
166 Float::from_integer_prec_round(Integer::from_sign_and_abs(sv, w2), prec, rm);
167 let o_shift = f.shl_round_assign(m - i64::exact_from(k) - 1, rm);
168 (f, if o_shift == Equal { o } else { o_shift })
169 }
170}
171
172// As in mpfr_overflow: toward-zero modes give the largest finite value with the overflow's sign,
173// and the other modes give an infinity. `Exact` panics, since an overflow is always inexact.
174fn overflow_result(sp: bool, prec: u64, rm: RoundingMode) -> (Float, Ordering) {
175 match (sp, rm) {
176 (_, Exact) => panic!("Inexact Float addition"),
177 (true, Floor | Down) => (Float::max_finite_value_with_prec(prec), Less),
178 (true, _) => (float_infinity!(), Greater),
179 (false, Ceiling | Down) => (-Float::max_finite_value_with_prec(prec), Greater),
180 (false, _) => (float_negative_infinity!(), Less),
181 }
182}
183
184// The exact integer-level fallback for a product whose exponent left the representable range:
185// decomposes the finite nonzero operands and forms the sum in `add_scaled_round`.
186fn scaled_path(
187 a: &Float,
188 b: &Float,
189 c: &Float,
190 sp: bool,
191 prec: u64,
192 rm: RoundingMode,
193) -> (Float, Ordering) {
194 let (
195 Float(Finite {
196 sign: a_sign,
197 exponent: a_exponent,
198 significand: a_significand,
199 ..
200 }),
201 Float(Finite {
202 exponent: b_exponent,
203 significand: b_significand,
204 ..
205 }),
206 Float(Finite {
207 exponent: c_exponent,
208 significand: c_significand,
209 ..
210 }),
211 ) = (a, b, c)
212 else {
213 unreachable!()
214 };
215 add_scaled_round(
216 *a_sign,
217 a_significand,
218 i64::from(*a_exponent) - i64::exact_from(significand_bits(a_significand)),
219 sp,
220 &(b_significand * c_significand),
221 i64::from(*b_exponent) - i64::exact_from(significand_bits(b_significand))
222 + i64::from(*c_exponent)
223 - i64::exact_from(significand_bits(c_significand)),
224 &Natural::ONE,
225 prec,
226 rm,
227 )
228}
229
230// This is the mixed Float-Rational counterpart of `add_mul_helper`: the result is x + y * z (or x -
231// y * z if `neg_p` is true) with the `Rational` z entering exactly, rounded to `prec` bits with
232// rounding mode `rm`. Pre-rounding z to a `Float` would perturb the result by y times the
233// conversion error; here the identity x + y(n/d) = (xd + yn)/d keeps the whole computation exact
234// until the single rounding at the end, in `add_scaled_round`. Since a nonzero `Rational` is
235// generally not a dyadic, there is no exact-product fast path to take first.
236//
237// A `Rational` zero has no sign and is treated as a positive zero in the product's sign rules.
238pub(crate) fn add_mul_rational_helper(
239 x: &Float,
240 y: &Float,
241 z: &Rational,
242 neg_p: bool,
243 prec: u64,
244 rm: RoundingMode,
245) -> (Float, Ordering) {
246 assert_ne!(prec, 0);
247 match (x, y) {
248 (Float(NaN), _) | (_, Float(NaN)) => (float_nan!(), Equal),
249 (_, float_either_infinity!()) => {
250 // an infinite y times a zero z is NaN; otherwise the product is an infinity
251 if *z == 0u32 {
252 return (float_nan!(), Equal);
253 }
254 let sp = (float_sign(y) == (*z > 0u32)) != neg_p;
255 match x {
256 float_either_infinity!() if float_sign(x) != sp => (float_nan!(), Equal),
257 _ => (
258 if sp {
259 float_infinity!()
260 } else {
261 float_negative_infinity!()
262 },
263 Equal,
264 ),
265 }
266 }
267 // now y is finite
268 (float_either_infinity!(), _) => (
269 if float_sign(x) {
270 float_infinity!()
271 } else {
272 float_negative_infinity!()
273 },
274 Equal,
275 ),
276 _ if matches!(y, float_either_zero!()) || *z == 0u32 => {
277 // The product is a signed zero, and the sign rules for combining it with the addend are
278 // the addition rules.
279 let sp = (float_sign(y) == (*z >= 0u32)) != neg_p;
280 x.add_prec_round_ref_val(
281 if sp {
282 Float::ZERO
283 } else {
284 Float::NEGATIVE_ZERO
285 },
286 prec,
287 rm,
288 )
289 }
290 (float_either_zero!(), _) => {
291 // the result is the rounded product; a negated product is computed via the negation
292 // identity
293 if neg_p {
294 let (p, o) = y.mul_rational_prec_round_ref_ref(z, prec, -rm);
295 (-p, o.reverse())
296 } else {
297 y.mul_rational_prec_round_ref_ref(z, prec, rm)
298 }
299 }
300 _ => {
301 let (
302 Float(Finite {
303 sign: x_sign,
304 exponent: x_exponent,
305 significand: x_significand,
306 ..
307 }),
308 Float(Finite {
309 sign: y_sign,
310 exponent: y_exponent,
311 significand: y_significand,
312 ..
313 }),
314 ) = (x, y)
315 else {
316 unreachable!()
317 };
318 let d = z.denominator_ref();
319 add_scaled_round(
320 *x_sign,
321 &(x_significand * d),
322 i64::from(*x_exponent) - i64::exact_from(significand_bits(x_significand)),
323 (*y_sign == (*z > 0u32)) != neg_p,
324 &(y_significand * z.numerator_ref()),
325 i64::from(*y_exponent) - i64::exact_from(significand_bits(y_significand)),
326 d,
327 prec,
328 rm,
329 )
330 }
331 }
332}
333
334// This is mpfr_fma from fma.c, MPFR 4.2.2, with the result's precision passed explicitly and the
335// singular cases from mpfr_fma_singular inlined. `neg_p` negates the product, which also covers
336// mpfr_fms from fms.c: fms.c negates its addend to compute x * y - z, while Malachite's sub_mul
337// computes self - y * z, which is the same fused operation with the product negated instead.
338//
339// The result is a + b * c (or a - b * c if `neg_p` is true), rounded to `prec` bits with rounding
340// mode `rm`. If we take the product's precision to be prec(b) + prec(c), the product b * c is
341// exact, except in case of overflow or underflow, so the fused operation is a single rounded
342// addition. MPFR's same-precision limb-level fast paths are omitted: they are performance shortcuts
343// for the same exact-product-then-add computation, which Malachite's mul already optimizes. The
344// pointer-equality x == y square shortcut is omitted for the same reason.
345//
346// Where MPFR resolves an overflowed or underflowed product with UBF arithmetic, here the two easy
347// cases are handled as in the C code (a definite overflow, and a product so far below the addend
348// that a minimal-value sentinel with the product's sign rounds identically), and the remaining
349// cases form the sum exactly at the integer level in `add_scaled_round`.
350pub(crate) fn add_mul_helper(
351 a: &Float,
352 b: &Float,
353 c: &Float,
354 neg_p: bool,
355 prec: u64,
356 rm: RoundingMode,
357) -> (Float, Ordering) {
358 assert_ne!(prec, 0);
359 match (a, b, c) {
360 (Float(NaN), _, _) | (_, Float(NaN), _) | (_, _, Float(NaN)) => (float_nan!(), Equal),
361 (_, float_either_infinity!(), _) | (_, _, float_either_infinity!()) => {
362 // cases Inf*0 + a, 0*Inf + a, Inf - Inf
363 if matches!(b, float_either_zero!()) || matches!(c, float_either_zero!()) {
364 return (float_nan!(), Equal);
365 }
366 let sp = (float_sign(b) == float_sign(c)) != neg_p;
367 match a {
368 float_either_infinity!() if float_sign(a) != sp => (float_nan!(), Equal),
369 _ => (
370 // an infinite addend with the same sign as the infinite product, or a finite
371 // addend: the result is an infinity with the product's sign
372 if sp {
373 float_infinity!()
374 } else {
375 float_negative_infinity!()
376 },
377 Equal,
378 ),
379 }
380 }
381 // now b and c are finite
382 (float_either_infinity!(), _, _) => (
383 if float_sign(a) {
384 float_infinity!()
385 } else {
386 float_negative_infinity!()
387 },
388 Equal,
389 ),
390 (_, float_either_zero!(), _) | (_, _, float_either_zero!()) => {
391 // The product is a signed zero, and mpfr_fma_singular's rules for combining it with the
392 // addend (including the zero-plus-zero sign rules) are exactly the addition rules, so
393 // the addition does the work.
394 let sp = (float_sign(b) == float_sign(c)) != neg_p;
395 a.add_prec_round_ref_val(
396 if sp {
397 Float::ZERO
398 } else {
399 Float::NEGATIVE_ZERO
400 },
401 prec,
402 rm,
403 )
404 }
405 (float_either_zero!(), _, _) => {
406 // the result is the rounded product; a negated product is computed via the negation
407 // identity
408 if neg_p {
409 let (p, o) = b.mul_prec_round_ref_ref(c, prec, -rm);
410 (-p, o.reverse())
411 } else {
412 b.mul_prec_round_ref_ref(c, prec, rm)
413 }
414 }
415 (
416 Float(Finite {
417 sign: a_sign,
418 exponent: a_exponent,
419 precision: a_precision,
420 ..
421 }),
422 Float(Finite {
423 sign: b_sign,
424 exponent: b_exponent,
425 precision: b_precision,
426 ..
427 }),
428 Float(Finite {
429 sign: c_sign,
430 exponent: c_exponent,
431 precision: c_precision,
432 ..
433 }),
434 ) => {
435 // At precision prec(b) + prec(c) the product is exact unless its exponent leaves the
436 // representable range, and Nearest overflows to an infinity, so an inexact product
437 // means overflow if infinite and underflow otherwise.
438 let (u, o) = b.mul_prec_ref_ref(c, b_precision + c_precision);
439 if o == Equal {
440 let u = if neg_p { -u } else { u };
441 return a.add_prec_round_ref_val(u, prec, rm);
442 }
443 let sp = (*b_sign == *c_sign) != neg_p;
444 let sa = *a_sign;
445 if u.is_infinite() {
446 // The product overflows. If it has the addend's sign, no cancellation is possible.
447 // Also, |a| < 2^MAX_EXPONENT, so if the product's exponent is at least MAX_EXPONENT
448 // + 3, |b * c| >= 2^(MAX_EXPONENT + 1) and the sum still overflows.
449 let e = i64::from(*b_exponent) + i64::from(*c_exponent);
450 if sp == sa || e >= SURE_OVERFLOW_EXPONENT {
451 return overflow_result(sp, prec, rm);
452 }
453 } else {
454 // The product underflows: |b * c| < 2^(MIN_EXPONENT - 1). When that is at most half
455 // an ulp of both the addend and the result, the product can be replaced by a
456 // minimal-value sentinel with its sign; this is even true in case of equality for
457 // Nearest thanks to the even-rounding rule. The + 1 on prec is necessary because
458 // the exponent of the result can be one less than the addend's.
459 if u64::exact_from(i64::from(*a_exponent) - Float::MIN_EXPONENT_I64)
460 >= max(*a_precision, prec.saturating_add(1))
461 {
462 let sent = if sp {
463 Float::MIN_POSITIVE
464 } else {
465 -Float::MIN_POSITIVE
466 };
467 return a.add_prec_round_ref_val(sent, prec, rm);
468 }
469 }
470 // the remaining overflow and underflow cases: form the sum exactly
471 scaled_path(a, b, c, sp, prec, rm)
472 }
473 }
474}
475
476// Like `add_mul_helper`, but taking the addend by value, so that the additions in the main path can
477// reuse its storage. The singular cases don't benefit from ownership and are delegated to the
478// by-reference helper.
479pub(crate) fn add_mul_val_helper(
480 a: Float,
481 b: &Float,
482 c: &Float,
483 neg_p: bool,
484 prec: u64,
485 rm: RoundingMode,
486) -> (Float, Ordering) {
487 assert_ne!(prec, 0);
488 let (
489 Float(Finite {
490 sign: a_sign,
491 exponent: a_exponent,
492 precision: a_precision,
493 ..
494 }),
495 Float(Finite {
496 sign: b_sign,
497 exponent: b_exponent,
498 precision: b_precision,
499 ..
500 }),
501 Float(Finite {
502 sign: c_sign,
503 exponent: c_exponent,
504 precision: c_precision,
505 ..
506 }),
507 ) = (&a, b, c)
508 else {
509 return add_mul_helper(&a, b, c, neg_p, prec, rm);
510 };
511 let (sa, ae, ap) = (*a_sign, i64::from(*a_exponent), *a_precision);
512 let sp = (*b_sign == *c_sign) != neg_p;
513 let e = i64::from(*b_exponent) + i64::from(*c_exponent);
514 let (u, o) = b.mul_prec_ref_ref(c, b_precision + c_precision);
515 if o == Equal {
516 let u = if neg_p { -u } else { u };
517 return a.add_prec_round(u, prec, rm);
518 }
519 if u.is_infinite() {
520 // as in the by-reference helper
521 if sp == sa || e >= SURE_OVERFLOW_EXPONENT {
522 return overflow_result(sp, prec, rm);
523 }
524 } else if u64::exact_from(ae - Float::MIN_EXPONENT_I64) >= max(ap, prec.saturating_add(1)) {
525 let sent = if sp {
526 Float::MIN_POSITIVE
527 } else {
528 -Float::MIN_POSITIVE
529 };
530 return a.add_prec_round(sent, prec, rm);
531 }
532 scaled_path(&a, b, c, sp, prec, rm)
533}
534
535impl Float {
536 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the
537 /// specified precision and with the specified rounding mode. All three [`Float`]s are taken by
538 /// value. An [`Ordering`] is also returned, indicating whether the rounded sum is less than,
539 /// equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
540 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
541 ///
542 /// See [`RoundingMode`] for a description of the possible rounding modes.
543 ///
544 /// $$
545 /// f(x,y,z,p,m) = x+yz+\varepsilon.
546 /// $$
547 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
548 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
549 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
550 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
551 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
552 ///
553 /// If the output has a precision, it is `prec`.
554 ///
555 /// Special cases:
556 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
557 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
558 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
559 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
560 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
561 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
562 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
563 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
564 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=0.0$
565 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=-0.0$
566 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$
567 /// is not `Floor`
568 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$
569 /// is `Floor`
570 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
571 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
572 ///
573 /// Overflow and underflow:
574 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
575 /// returned instead.
576 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
577 /// is returned instead, where `p` is the precision of the output.
578 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
579 /// returned instead.
580 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
581 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
582 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
583 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
584 /// instead.
585 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
586 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
587 /// returned instead.
588 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
589 /// instead.
590 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
591 /// instead.
592 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
593 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
594 /// returned instead.
595 ///
596 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_prec`] instead. If
597 /// you know that your target precision is the maximum of the precisions of the inputs, consider
598 /// using [`Float::add_mul_round`] instead. If both of these things are true, consider using
599 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
600 ///
601 /// # Worst-case complexity
602 /// $T(n, m) = O(n \log n \log\log n + m)$
603 ///
604 /// $M(n, m) = O(n \log n + m)$
605 ///
606 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
607 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
608 ///
609 /// # Panics
610 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
611 /// representable with `prec` bits.
612 ///
613 /// # Examples
614 /// ```
615 /// use core::f64::consts::{E, PI, SQRT_2};
616 /// use malachite_base::rounding_modes::RoundingMode::*;
617 /// use malachite_float::Float;
618 /// use std::cmp::Ordering::*;
619 ///
620 /// let x = Float::from(PI);
621 /// let y = Float::from(E);
622 /// let z = Float::from(SQRT_2);
623 ///
624 /// let (sum, o) = x.clone().add_mul_prec_round(y.clone(), z.clone(), 5, Floor);
625 /// assert_eq!(sum.to_string(), "6.75");
626 /// assert_eq!(o, Less);
627 ///
628 /// let (sum, o) = x
629 /// .clone()
630 /// .add_mul_prec_round(y.clone(), z.clone(), 5, Ceiling);
631 /// assert_eq!(sum.to_string(), "7.00");
632 /// assert_eq!(o, Greater);
633 ///
634 /// let (sum, o) = x
635 /// .clone()
636 /// .add_mul_prec_round(y.clone(), z.clone(), 5, Nearest);
637 /// assert_eq!(sum.to_string(), "7.00");
638 /// assert_eq!(o, Greater);
639 ///
640 /// let (sum, o) = x
641 /// .clone()
642 /// .add_mul_prec_round(y.clone(), z.clone(), 20, Floor);
643 /// assert_eq!(sum.to_string(), "6.9858170");
644 /// assert_eq!(o, Less);
645 ///
646 /// let (sum, o) = x
647 /// .clone()
648 /// .add_mul_prec_round(y.clone(), z.clone(), 20, Ceiling);
649 /// assert_eq!(sum.to_string(), "6.9858246");
650 /// assert_eq!(o, Greater);
651 ///
652 /// let (sum, o) = x
653 /// .clone()
654 /// .add_mul_prec_round(y.clone(), z.clone(), 20, Nearest);
655 /// assert_eq!(sum.to_string(), "6.9858246");
656 /// assert_eq!(o, Greater);
657 /// ```
658 #[allow(clippy::needless_pass_by_value)]
659 #[inline]
660 pub fn add_mul_prec_round(
661 self,
662 y: Self,
663 z: Self,
664 prec: u64,
665 rm: RoundingMode,
666 ) -> (Self, Ordering) {
667 add_mul_val_helper(self, &y, &z, false, prec, rm)
668 }
669
670 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the
671 /// specified precision and with the specified rounding mode. The first two [`Float`]s are taken
672 /// by value and the third by reference. An [`Ordering`] is also returned, indicating whether
673 /// the rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are
674 /// not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
675 /// `Equal`.
676 ///
677 /// See [`RoundingMode`] for a description of the possible rounding modes.
678 ///
679 /// $$
680 /// f(x,y,z,p,m) = x+yz+\varepsilon.
681 /// $$
682 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
683 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
684 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
685 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
686 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
687 ///
688 /// If the output has a precision, it is `prec`.
689 ///
690 /// Special cases:
691 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
692 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
693 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
694 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
695 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
696 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
697 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
698 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
699 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=0.0$
700 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=-0.0$
701 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$
702 /// is not `Floor`
703 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$
704 /// is `Floor`
705 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
706 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
707 ///
708 /// Overflow and underflow:
709 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
710 /// returned instead.
711 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
712 /// is returned instead, where `p` is the precision of the output.
713 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
714 /// returned instead.
715 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
716 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
717 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
718 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
719 /// instead.
720 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
721 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
722 /// returned instead.
723 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
724 /// instead.
725 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
726 /// instead.
727 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
728 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
729 /// returned instead.
730 ///
731 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_prec`] instead. If
732 /// you know that your target precision is the maximum of the precisions of the inputs, consider
733 /// using [`Float::add_mul_round`] instead. If both of these things are true, consider using
734 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
735 ///
736 /// # Worst-case complexity
737 /// $T(n, m) = O(n \log n \log\log n + m)$
738 ///
739 /// $M(n, m) = O(n \log n + m)$
740 ///
741 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
742 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
743 ///
744 /// # Panics
745 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
746 /// representable with `prec` bits.
747 ///
748 /// # Examples
749 /// ```
750 /// use core::f64::consts::{E, PI, SQRT_2};
751 /// use malachite_base::rounding_modes::RoundingMode::*;
752 /// use malachite_float::Float;
753 /// use std::cmp::Ordering::*;
754 ///
755 /// let x = Float::from(PI);
756 /// let y = Float::from(E);
757 /// let z = Float::from(SQRT_2);
758 ///
759 /// let (sum, o) = x
760 /// .clone()
761 /// .add_mul_prec_round_val_val_ref(y.clone(), &z, 5, Floor);
762 /// assert_eq!(sum.to_string(), "6.75");
763 /// assert_eq!(o, Less);
764 ///
765 /// let (sum, o) = x
766 /// .clone()
767 /// .add_mul_prec_round_val_val_ref(y.clone(), &z, 5, Ceiling);
768 /// assert_eq!(sum.to_string(), "7.00");
769 /// assert_eq!(o, Greater);
770 ///
771 /// let (sum, o) = x
772 /// .clone()
773 /// .add_mul_prec_round_val_val_ref(y.clone(), &z, 5, Nearest);
774 /// assert_eq!(sum.to_string(), "7.00");
775 /// assert_eq!(o, Greater);
776 ///
777 /// let (sum, o) = x
778 /// .clone()
779 /// .add_mul_prec_round_val_val_ref(y.clone(), &z, 20, Floor);
780 /// assert_eq!(sum.to_string(), "6.9858170");
781 /// assert_eq!(o, Less);
782 ///
783 /// let (sum, o) = x
784 /// .clone()
785 /// .add_mul_prec_round_val_val_ref(y.clone(), &z, 20, Ceiling);
786 /// assert_eq!(sum.to_string(), "6.9858246");
787 /// assert_eq!(o, Greater);
788 ///
789 /// let (sum, o) = x
790 /// .clone()
791 /// .add_mul_prec_round_val_val_ref(y.clone(), &z, 20, Nearest);
792 /// assert_eq!(sum.to_string(), "6.9858246");
793 /// assert_eq!(o, Greater);
794 /// ```
795 #[allow(clippy::needless_pass_by_value)]
796 #[inline]
797 pub fn add_mul_prec_round_val_val_ref(
798 self,
799 y: Self,
800 z: &Self,
801 prec: u64,
802 rm: RoundingMode,
803 ) -> (Self, Ordering) {
804 add_mul_val_helper(self, &y, z, false, prec, rm)
805 }
806
807 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the
808 /// specified precision and with the specified rounding mode. The first and third [`Float`]s are
809 /// taken by value and the second by reference. An [`Ordering`] is also returned, indicating
810 /// whether the rounded sum is less than, equal to, or greater than the exact sum. Although
811 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
812 /// returns `Equal`.
813 ///
814 /// See [`RoundingMode`] for a description of the possible rounding modes.
815 ///
816 /// $$
817 /// f(x,y,z,p,m) = x+yz+\varepsilon.
818 /// $$
819 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
820 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
821 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
822 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
823 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
824 ///
825 /// If the output has a precision, it is `prec`.
826 ///
827 /// Special cases:
828 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
829 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
830 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
831 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
832 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
833 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
834 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
835 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
836 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=0.0$
837 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=-0.0$
838 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$
839 /// is not `Floor`
840 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$
841 /// is `Floor`
842 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
843 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
844 ///
845 /// Overflow and underflow:
846 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
847 /// returned instead.
848 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
849 /// is returned instead, where `p` is the precision of the output.
850 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
851 /// returned instead.
852 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
853 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
854 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
855 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
856 /// instead.
857 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
858 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
859 /// returned instead.
860 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
861 /// instead.
862 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
863 /// instead.
864 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
865 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
866 /// returned instead.
867 ///
868 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_prec`] instead. If
869 /// you know that your target precision is the maximum of the precisions of the inputs, consider
870 /// using [`Float::add_mul_round`] instead. If both of these things are true, consider using
871 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
872 ///
873 /// # Worst-case complexity
874 /// $T(n, m) = O(n \log n \log\log n + m)$
875 ///
876 /// $M(n, m) = O(n \log n + m)$
877 ///
878 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
879 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
880 ///
881 /// # Panics
882 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
883 /// representable with `prec` bits.
884 ///
885 /// # Examples
886 /// ```
887 /// use core::f64::consts::{E, PI, SQRT_2};
888 /// use malachite_base::rounding_modes::RoundingMode::*;
889 /// use malachite_float::Float;
890 /// use std::cmp::Ordering::*;
891 ///
892 /// let x = Float::from(PI);
893 /// let y = Float::from(E);
894 /// let z = Float::from(SQRT_2);
895 ///
896 /// let (sum, o) = x
897 /// .clone()
898 /// .add_mul_prec_round_val_ref_val(&y, z.clone(), 5, Floor);
899 /// assert_eq!(sum.to_string(), "6.75");
900 /// assert_eq!(o, Less);
901 ///
902 /// let (sum, o) = x
903 /// .clone()
904 /// .add_mul_prec_round_val_ref_val(&y, z.clone(), 5, Ceiling);
905 /// assert_eq!(sum.to_string(), "7.00");
906 /// assert_eq!(o, Greater);
907 ///
908 /// let (sum, o) = x
909 /// .clone()
910 /// .add_mul_prec_round_val_ref_val(&y, z.clone(), 5, Nearest);
911 /// assert_eq!(sum.to_string(), "7.00");
912 /// assert_eq!(o, Greater);
913 ///
914 /// let (sum, o) = x
915 /// .clone()
916 /// .add_mul_prec_round_val_ref_val(&y, z.clone(), 20, Floor);
917 /// assert_eq!(sum.to_string(), "6.9858170");
918 /// assert_eq!(o, Less);
919 ///
920 /// let (sum, o) = x
921 /// .clone()
922 /// .add_mul_prec_round_val_ref_val(&y, z.clone(), 20, Ceiling);
923 /// assert_eq!(sum.to_string(), "6.9858246");
924 /// assert_eq!(o, Greater);
925 ///
926 /// let (sum, o) = x
927 /// .clone()
928 /// .add_mul_prec_round_val_ref_val(&y, z.clone(), 20, Nearest);
929 /// assert_eq!(sum.to_string(), "6.9858246");
930 /// assert_eq!(o, Greater);
931 /// ```
932 #[allow(clippy::needless_pass_by_value)]
933 #[inline]
934 pub fn add_mul_prec_round_val_ref_val(
935 self,
936 y: &Self,
937 z: Self,
938 prec: u64,
939 rm: RoundingMode,
940 ) -> (Self, Ordering) {
941 add_mul_val_helper(self, y, &z, false, prec, rm)
942 }
943
944 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the
945 /// specified precision and with the specified rounding mode. The first [`Float`] is taken by
946 /// value and the second and third by reference. An [`Ordering`] is also returned, indicating
947 /// whether the rounded sum is less than, equal to, or greater than the exact sum. Although
948 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
949 /// returns `Equal`.
950 ///
951 /// See [`RoundingMode`] for a description of the possible rounding modes.
952 ///
953 /// $$
954 /// f(x,y,z,p,m) = x+yz+\varepsilon.
955 /// $$
956 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
957 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
958 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
959 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
960 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
961 ///
962 /// If the output has a precision, it is `prec`.
963 ///
964 /// Special cases:
965 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
966 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
967 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
968 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
969 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
970 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
971 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
972 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
973 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=0.0$
974 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=-0.0$
975 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$
976 /// is not `Floor`
977 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$
978 /// is `Floor`
979 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
980 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
981 ///
982 /// Overflow and underflow:
983 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
984 /// returned instead.
985 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
986 /// is returned instead, where `p` is the precision of the output.
987 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
988 /// returned instead.
989 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
990 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
991 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
992 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
993 /// instead.
994 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
995 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
996 /// returned instead.
997 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
998 /// instead.
999 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1000 /// instead.
1001 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1002 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1003 /// returned instead.
1004 ///
1005 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_prec`] instead. If
1006 /// you know that your target precision is the maximum of the precisions of the inputs, consider
1007 /// using [`Float::add_mul_round`] instead. If both of these things are true, consider using
1008 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
1009 ///
1010 /// # Worst-case complexity
1011 /// $T(n, m) = O(n \log n \log\log n + m)$
1012 ///
1013 /// $M(n, m) = O(n \log n + m)$
1014 ///
1015 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1016 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1017 ///
1018 /// # Panics
1019 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
1020 /// representable with `prec` bits.
1021 ///
1022 /// # Examples
1023 /// ```
1024 /// use core::f64::consts::{E, PI, SQRT_2};
1025 /// use malachite_base::rounding_modes::RoundingMode::*;
1026 /// use malachite_float::Float;
1027 /// use std::cmp::Ordering::*;
1028 ///
1029 /// let x = Float::from(PI);
1030 /// let y = Float::from(E);
1031 /// let z = Float::from(SQRT_2);
1032 ///
1033 /// let (sum, o) = x.clone().add_mul_prec_round_val_ref_ref(&y, &z, 5, Floor);
1034 /// assert_eq!(sum.to_string(), "6.75");
1035 /// assert_eq!(o, Less);
1036 ///
1037 /// let (sum, o) = x.clone().add_mul_prec_round_val_ref_ref(&y, &z, 5, Ceiling);
1038 /// assert_eq!(sum.to_string(), "7.00");
1039 /// assert_eq!(o, Greater);
1040 ///
1041 /// let (sum, o) = x.clone().add_mul_prec_round_val_ref_ref(&y, &z, 5, Nearest);
1042 /// assert_eq!(sum.to_string(), "7.00");
1043 /// assert_eq!(o, Greater);
1044 ///
1045 /// let (sum, o) = x.clone().add_mul_prec_round_val_ref_ref(&y, &z, 20, Floor);
1046 /// assert_eq!(sum.to_string(), "6.9858170");
1047 /// assert_eq!(o, Less);
1048 ///
1049 /// let (sum, o) = x
1050 /// .clone()
1051 /// .add_mul_prec_round_val_ref_ref(&y, &z, 20, Ceiling);
1052 /// assert_eq!(sum.to_string(), "6.9858246");
1053 /// assert_eq!(o, Greater);
1054 ///
1055 /// let (sum, o) = x
1056 /// .clone()
1057 /// .add_mul_prec_round_val_ref_ref(&y, &z, 20, Nearest);
1058 /// assert_eq!(sum.to_string(), "6.9858246");
1059 /// assert_eq!(o, Greater);
1060 /// ```
1061 #[inline]
1062 pub fn add_mul_prec_round_val_ref_ref(
1063 self,
1064 y: &Self,
1065 z: &Self,
1066 prec: u64,
1067 rm: RoundingMode,
1068 ) -> (Self, Ordering) {
1069 add_mul_val_helper(self, y, z, false, prec, rm)
1070 }
1071
1072 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the
1073 /// specified precision and with the specified rounding mode. The first [`Float`] is taken by
1074 /// reference and the second and third by value. An [`Ordering`] is also returned, indicating
1075 /// whether the rounded sum is less than, equal to, or greater than the exact sum. Although
1076 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
1077 /// returns `Equal`.
1078 ///
1079 /// See [`RoundingMode`] for a description of the possible rounding modes.
1080 ///
1081 /// $$
1082 /// f(x,y,z,p,m) = x+yz+\varepsilon.
1083 /// $$
1084 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1085 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1086 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
1087 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1088 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
1089 ///
1090 /// If the output has a precision, it is `prec`.
1091 ///
1092 /// Special cases:
1093 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
1094 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
1095 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
1096 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
1097 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
1098 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
1099 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
1100 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
1101 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=0.0$
1102 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=-0.0$
1103 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$
1104 /// is not `Floor`
1105 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$
1106 /// is `Floor`
1107 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
1108 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
1109 ///
1110 /// Overflow and underflow:
1111 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1112 /// returned instead.
1113 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
1114 /// is returned instead, where `p` is the precision of the output.
1115 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1116 /// returned instead.
1117 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
1118 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1119 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1120 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1121 /// instead.
1122 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1123 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
1124 /// returned instead.
1125 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
1126 /// instead.
1127 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1128 /// instead.
1129 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1130 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1131 /// returned instead.
1132 ///
1133 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_prec`] instead. If
1134 /// you know that your target precision is the maximum of the precisions of the inputs, consider
1135 /// using [`Float::add_mul_round`] instead. If both of these things are true, consider using
1136 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
1137 ///
1138 /// # Worst-case complexity
1139 /// $T(n, m) = O(n \log n \log\log n + m)$
1140 ///
1141 /// $M(n, m) = O(n \log n + m)$
1142 ///
1143 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1144 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1145 ///
1146 /// # Panics
1147 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
1148 /// representable with `prec` bits.
1149 ///
1150 /// # Examples
1151 /// ```
1152 /// use core::f64::consts::{E, PI, SQRT_2};
1153 /// use malachite_base::rounding_modes::RoundingMode::*;
1154 /// use malachite_float::Float;
1155 /// use std::cmp::Ordering::*;
1156 ///
1157 /// let x = Float::from(PI);
1158 /// let y = Float::from(E);
1159 /// let z = Float::from(SQRT_2);
1160 ///
1161 /// let (sum, o) = x.add_mul_prec_round_ref_val_val(y.clone(), z.clone(), 5, Floor);
1162 /// assert_eq!(sum.to_string(), "6.75");
1163 /// assert_eq!(o, Less);
1164 ///
1165 /// let (sum, o) = x.add_mul_prec_round_ref_val_val(y.clone(), z.clone(), 5, Ceiling);
1166 /// assert_eq!(sum.to_string(), "7.00");
1167 /// assert_eq!(o, Greater);
1168 ///
1169 /// let (sum, o) = x.add_mul_prec_round_ref_val_val(y.clone(), z.clone(), 5, Nearest);
1170 /// assert_eq!(sum.to_string(), "7.00");
1171 /// assert_eq!(o, Greater);
1172 ///
1173 /// let (sum, o) = x.add_mul_prec_round_ref_val_val(y.clone(), z.clone(), 20, Floor);
1174 /// assert_eq!(sum.to_string(), "6.9858170");
1175 /// assert_eq!(o, Less);
1176 ///
1177 /// let (sum, o) = x.add_mul_prec_round_ref_val_val(y.clone(), z.clone(), 20, Ceiling);
1178 /// assert_eq!(sum.to_string(), "6.9858246");
1179 /// assert_eq!(o, Greater);
1180 ///
1181 /// let (sum, o) = x.add_mul_prec_round_ref_val_val(y.clone(), z.clone(), 20, Nearest);
1182 /// assert_eq!(sum.to_string(), "6.9858246");
1183 /// assert_eq!(o, Greater);
1184 /// ```
1185 #[allow(clippy::needless_pass_by_value)]
1186 #[inline]
1187 pub fn add_mul_prec_round_ref_val_val(
1188 &self,
1189 y: Self,
1190 z: Self,
1191 prec: u64,
1192 rm: RoundingMode,
1193 ) -> (Self, Ordering) {
1194 add_mul_helper(self, &y, &z, false, prec, rm)
1195 }
1196
1197 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the
1198 /// specified precision and with the specified rounding mode. The first and third [`Float`]s are
1199 /// taken by reference and the second by value. An [`Ordering`] is also returned, indicating
1200 /// whether the rounded sum is less than, equal to, or greater than the exact sum. Although
1201 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
1202 /// returns `Equal`.
1203 ///
1204 /// See [`RoundingMode`] for a description of the possible rounding modes.
1205 ///
1206 /// $$
1207 /// f(x,y,z,p,m) = x+yz+\varepsilon.
1208 /// $$
1209 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1210 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1211 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
1212 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1213 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
1214 ///
1215 /// If the output has a precision, it is `prec`.
1216 ///
1217 /// Special cases:
1218 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
1219 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
1220 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
1221 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
1222 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
1223 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
1224 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
1225 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
1226 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=0.0$
1227 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=-0.0$
1228 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$
1229 /// is not `Floor`
1230 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$
1231 /// is `Floor`
1232 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
1233 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
1234 ///
1235 /// Overflow and underflow:
1236 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1237 /// returned instead.
1238 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
1239 /// is returned instead, where `p` is the precision of the output.
1240 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1241 /// returned instead.
1242 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
1243 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1244 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1245 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1246 /// instead.
1247 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1248 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
1249 /// returned instead.
1250 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
1251 /// instead.
1252 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1253 /// instead.
1254 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1255 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1256 /// returned instead.
1257 ///
1258 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_prec`] instead. If
1259 /// you know that your target precision is the maximum of the precisions of the inputs, consider
1260 /// using [`Float::add_mul_round`] instead. If both of these things are true, consider using
1261 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
1262 ///
1263 /// # Worst-case complexity
1264 /// $T(n, m) = O(n \log n \log\log n + m)$
1265 ///
1266 /// $M(n, m) = O(n \log n + m)$
1267 ///
1268 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1269 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1270 ///
1271 /// # Panics
1272 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
1273 /// representable with `prec` bits.
1274 ///
1275 /// # Examples
1276 /// ```
1277 /// use core::f64::consts::{E, PI, SQRT_2};
1278 /// use malachite_base::rounding_modes::RoundingMode::*;
1279 /// use malachite_float::Float;
1280 /// use std::cmp::Ordering::*;
1281 ///
1282 /// let x = Float::from(PI);
1283 /// let y = Float::from(E);
1284 /// let z = Float::from(SQRT_2);
1285 ///
1286 /// let (sum, o) = x.add_mul_prec_round_ref_val_ref(y.clone(), &z, 5, Floor);
1287 /// assert_eq!(sum.to_string(), "6.75");
1288 /// assert_eq!(o, Less);
1289 ///
1290 /// let (sum, o) = x.add_mul_prec_round_ref_val_ref(y.clone(), &z, 5, Ceiling);
1291 /// assert_eq!(sum.to_string(), "7.00");
1292 /// assert_eq!(o, Greater);
1293 ///
1294 /// let (sum, o) = x.add_mul_prec_round_ref_val_ref(y.clone(), &z, 5, Nearest);
1295 /// assert_eq!(sum.to_string(), "7.00");
1296 /// assert_eq!(o, Greater);
1297 ///
1298 /// let (sum, o) = x.add_mul_prec_round_ref_val_ref(y.clone(), &z, 20, Floor);
1299 /// assert_eq!(sum.to_string(), "6.9858170");
1300 /// assert_eq!(o, Less);
1301 ///
1302 /// let (sum, o) = x.add_mul_prec_round_ref_val_ref(y.clone(), &z, 20, Ceiling);
1303 /// assert_eq!(sum.to_string(), "6.9858246");
1304 /// assert_eq!(o, Greater);
1305 ///
1306 /// let (sum, o) = x.add_mul_prec_round_ref_val_ref(y.clone(), &z, 20, Nearest);
1307 /// assert_eq!(sum.to_string(), "6.9858246");
1308 /// assert_eq!(o, Greater);
1309 /// ```
1310 #[allow(clippy::needless_pass_by_value)]
1311 #[inline]
1312 pub fn add_mul_prec_round_ref_val_ref(
1313 &self,
1314 y: Self,
1315 z: &Self,
1316 prec: u64,
1317 rm: RoundingMode,
1318 ) -> (Self, Ordering) {
1319 add_mul_helper(self, &y, z, false, prec, rm)
1320 }
1321
1322 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the
1323 /// specified precision and with the specified rounding mode. The first two [`Float`]s are taken
1324 /// by reference and the third by value. An [`Ordering`] is also returned, indicating whether
1325 /// the rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are
1326 /// not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
1327 /// `Equal`.
1328 ///
1329 /// See [`RoundingMode`] for a description of the possible rounding modes.
1330 ///
1331 /// $$
1332 /// f(x,y,z,p,m) = x+yz+\varepsilon.
1333 /// $$
1334 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1335 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1336 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
1337 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1338 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
1339 ///
1340 /// If the output has a precision, it is `prec`.
1341 ///
1342 /// Special cases:
1343 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
1344 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
1345 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
1346 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
1347 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
1348 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
1349 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
1350 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
1351 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=0.0$
1352 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=-0.0$
1353 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$
1354 /// is not `Floor`
1355 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$
1356 /// is `Floor`
1357 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
1358 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
1359 ///
1360 /// Overflow and underflow:
1361 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1362 /// returned instead.
1363 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
1364 /// is returned instead, where `p` is the precision of the output.
1365 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1366 /// returned instead.
1367 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
1368 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1369 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1370 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1371 /// instead.
1372 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1373 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
1374 /// returned instead.
1375 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
1376 /// instead.
1377 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1378 /// instead.
1379 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1380 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1381 /// returned instead.
1382 ///
1383 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_prec`] instead. If
1384 /// you know that your target precision is the maximum of the precisions of the inputs, consider
1385 /// using [`Float::add_mul_round`] instead. If both of these things are true, consider using
1386 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
1387 ///
1388 /// # Worst-case complexity
1389 /// $T(n, m) = O(n \log n \log\log n + m)$
1390 ///
1391 /// $M(n, m) = O(n \log n + m)$
1392 ///
1393 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1394 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1395 ///
1396 /// # Panics
1397 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
1398 /// representable with `prec` bits.
1399 ///
1400 /// # Examples
1401 /// ```
1402 /// use core::f64::consts::{E, PI, SQRT_2};
1403 /// use malachite_base::rounding_modes::RoundingMode::*;
1404 /// use malachite_float::Float;
1405 /// use std::cmp::Ordering::*;
1406 ///
1407 /// let x = Float::from(PI);
1408 /// let y = Float::from(E);
1409 /// let z = Float::from(SQRT_2);
1410 ///
1411 /// let (sum, o) = x.add_mul_prec_round_ref_ref_val(&y, z.clone(), 5, Floor);
1412 /// assert_eq!(sum.to_string(), "6.75");
1413 /// assert_eq!(o, Less);
1414 ///
1415 /// let (sum, o) = x.add_mul_prec_round_ref_ref_val(&y, z.clone(), 5, Ceiling);
1416 /// assert_eq!(sum.to_string(), "7.00");
1417 /// assert_eq!(o, Greater);
1418 ///
1419 /// let (sum, o) = x.add_mul_prec_round_ref_ref_val(&y, z.clone(), 5, Nearest);
1420 /// assert_eq!(sum.to_string(), "7.00");
1421 /// assert_eq!(o, Greater);
1422 ///
1423 /// let (sum, o) = x.add_mul_prec_round_ref_ref_val(&y, z.clone(), 20, Floor);
1424 /// assert_eq!(sum.to_string(), "6.9858170");
1425 /// assert_eq!(o, Less);
1426 ///
1427 /// let (sum, o) = x.add_mul_prec_round_ref_ref_val(&y, z.clone(), 20, Ceiling);
1428 /// assert_eq!(sum.to_string(), "6.9858246");
1429 /// assert_eq!(o, Greater);
1430 ///
1431 /// let (sum, o) = x.add_mul_prec_round_ref_ref_val(&y, z.clone(), 20, Nearest);
1432 /// assert_eq!(sum.to_string(), "6.9858246");
1433 /// assert_eq!(o, Greater);
1434 /// ```
1435 #[allow(clippy::needless_pass_by_value)]
1436 #[inline]
1437 pub fn add_mul_prec_round_ref_ref_val(
1438 &self,
1439 y: &Self,
1440 z: Self,
1441 prec: u64,
1442 rm: RoundingMode,
1443 ) -> (Self, Ordering) {
1444 add_mul_helper(self, y, &z, false, prec, rm)
1445 }
1446
1447 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the
1448 /// specified precision and with the specified rounding mode. All three [`Float`]s are taken by
1449 /// reference. An [`Ordering`] is also returned, indicating whether the rounded sum is less
1450 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
1451 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1452 ///
1453 /// See [`RoundingMode`] for a description of the possible rounding modes.
1454 ///
1455 /// $$
1456 /// f(x,y,z,p,m) = x+yz+\varepsilon.
1457 /// $$
1458 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1459 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1460 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
1461 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1462 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
1463 ///
1464 /// If the output has a precision, it is `prec`.
1465 ///
1466 /// Special cases:
1467 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
1468 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
1469 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
1470 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
1471 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
1472 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
1473 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
1474 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
1475 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=0.0$
1476 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=-0.0$
1477 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$
1478 /// is not `Floor`
1479 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$
1480 /// is `Floor`
1481 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
1482 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
1483 ///
1484 /// Overflow and underflow:
1485 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1486 /// returned instead.
1487 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
1488 /// is returned instead, where `p` is the precision of the output.
1489 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1490 /// returned instead.
1491 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
1492 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1493 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
1494 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1495 /// instead.
1496 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1497 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
1498 /// returned instead.
1499 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
1500 /// instead.
1501 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1502 /// instead.
1503 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
1504 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1505 /// returned instead.
1506 ///
1507 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_prec`] instead. If
1508 /// you know that your target precision is the maximum of the precisions of the inputs, consider
1509 /// using [`Float::add_mul_round`] instead. If both of these things are true, consider using
1510 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
1511 ///
1512 /// # Worst-case complexity
1513 /// $T(n, m) = O(n \log n \log\log n + m)$
1514 ///
1515 /// $M(n, m) = O(n \log n + m)$
1516 ///
1517 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1518 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1519 ///
1520 /// # Panics
1521 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
1522 /// representable with `prec` bits.
1523 ///
1524 /// # Examples
1525 /// ```
1526 /// use core::f64::consts::{E, PI, SQRT_2};
1527 /// use malachite_base::rounding_modes::RoundingMode::*;
1528 /// use malachite_float::Float;
1529 /// use std::cmp::Ordering::*;
1530 ///
1531 /// let x = Float::from(PI);
1532 /// let y = Float::from(E);
1533 /// let z = Float::from(SQRT_2);
1534 ///
1535 /// let (sum, o) = x.add_mul_prec_round_ref_ref_ref(&y, &z, 5, Floor);
1536 /// assert_eq!(sum.to_string(), "6.75");
1537 /// assert_eq!(o, Less);
1538 ///
1539 /// let (sum, o) = x.add_mul_prec_round_ref_ref_ref(&y, &z, 5, Ceiling);
1540 /// assert_eq!(sum.to_string(), "7.00");
1541 /// assert_eq!(o, Greater);
1542 ///
1543 /// let (sum, o) = x.add_mul_prec_round_ref_ref_ref(&y, &z, 5, Nearest);
1544 /// assert_eq!(sum.to_string(), "7.00");
1545 /// assert_eq!(o, Greater);
1546 ///
1547 /// let (sum, o) = x.add_mul_prec_round_ref_ref_ref(&y, &z, 20, Floor);
1548 /// assert_eq!(sum.to_string(), "6.9858170");
1549 /// assert_eq!(o, Less);
1550 ///
1551 /// let (sum, o) = x.add_mul_prec_round_ref_ref_ref(&y, &z, 20, Ceiling);
1552 /// assert_eq!(sum.to_string(), "6.9858246");
1553 /// assert_eq!(o, Greater);
1554 ///
1555 /// let (sum, o) = x.add_mul_prec_round_ref_ref_ref(&y, &z, 20, Nearest);
1556 /// assert_eq!(sum.to_string(), "6.9858246");
1557 /// assert_eq!(o, Greater);
1558 /// ```
1559 #[inline]
1560 pub fn add_mul_prec_round_ref_ref_ref(
1561 &self,
1562 y: &Self,
1563 z: &Self,
1564 prec: u64,
1565 rm: RoundingMode,
1566 ) -> (Self, Ordering) {
1567 add_mul_helper(self, y, z, false, prec, rm)
1568 }
1569
1570 /// Adds the product of two [`Float`]s to a [`Float`] in place, rounding the result to the
1571 /// specified precision and with the specified rounding mode. Both [`Float`]s on the right-hand
1572 /// side are taken by value. An [`Ordering`] is returned, indicating whether the rounded sum is
1573 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
1574 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1575 ///
1576 /// See [`RoundingMode`] for a description of the possible rounding modes.
1577 ///
1578 /// $$
1579 /// x \gets x+yz+\varepsilon.
1580 /// $$
1581 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1582 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
1583 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1584 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
1585 ///
1586 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
1587 /// overflow, and underflow.
1588 ///
1589 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_prec_assign`]
1590 /// instead. If you know that your target precision is the maximum of the precisions of the
1591 /// inputs, consider using [`Float::add_mul_round_assign`] instead. If both of these things are
1592 /// true, consider using
1593 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
1594 /// instead.
1595 ///
1596 /// # Worst-case complexity
1597 /// $T(n, m) = O(n \log n \log\log n + m)$
1598 ///
1599 /// $M(n, m) = O(n \log n + m)$
1600 ///
1601 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1602 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1603 ///
1604 /// # Panics
1605 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
1606 /// representable with `prec` bits.
1607 ///
1608 /// # Examples
1609 /// ```
1610 /// use core::f64::consts::{E, PI, SQRT_2};
1611 /// use malachite_base::rounding_modes::RoundingMode::*;
1612 /// use malachite_float::Float;
1613 /// use std::cmp::Ordering::*;
1614 ///
1615 /// let y = Float::from(E);
1616 /// let z = Float::from(SQRT_2);
1617 ///
1618 /// let mut x = Float::from(PI);
1619 /// assert_eq!(
1620 /// x.add_mul_prec_round_assign(y.clone(), z.clone(), 5, Floor),
1621 /// Less
1622 /// );
1623 /// assert_eq!(x.to_string(), "6.75");
1624 ///
1625 /// let mut x = Float::from(PI);
1626 /// assert_eq!(
1627 /// x.add_mul_prec_round_assign(y.clone(), z.clone(), 5, Ceiling),
1628 /// Greater
1629 /// );
1630 /// assert_eq!(x.to_string(), "7.00");
1631 ///
1632 /// let mut x = Float::from(PI);
1633 /// assert_eq!(
1634 /// x.add_mul_prec_round_assign(y.clone(), z.clone(), 5, Nearest),
1635 /// Greater
1636 /// );
1637 /// assert_eq!(x.to_string(), "7.00");
1638 /// ```
1639 #[allow(clippy::needless_pass_by_value)]
1640 #[inline]
1641 pub fn add_mul_prec_round_assign(
1642 &mut self,
1643 y: Self,
1644 z: Self,
1645 prec: u64,
1646 rm: RoundingMode,
1647 ) -> Ordering {
1648 let (s, o) = add_mul_helper(self, &y, &z, false, prec, rm);
1649 *self = s;
1650 o
1651 }
1652
1653 /// Adds the product of two [`Float`]s to a [`Float`] in place, rounding the result to the
1654 /// specified precision and with the specified rounding mode. The first [`Float`] on the
1655 /// right-hand side is taken by value and the second by reference. An [`Ordering`] is returned,
1656 /// indicating whether the rounded sum is less than, equal to, or greater than the exact sum.
1657 /// Although `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN`
1658 /// it also returns `Equal`.
1659 ///
1660 /// See [`RoundingMode`] for a description of the possible rounding modes.
1661 ///
1662 /// $$
1663 /// x \gets x+yz+\varepsilon.
1664 /// $$
1665 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1666 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
1667 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1668 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
1669 ///
1670 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
1671 /// overflow, and underflow.
1672 ///
1673 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_prec_assign`]
1674 /// instead. If you know that your target precision is the maximum of the precisions of the
1675 /// inputs, consider using [`Float::add_mul_round_assign`] instead. If both of these things are
1676 /// true, consider using
1677 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
1678 /// instead.
1679 ///
1680 /// # Worst-case complexity
1681 /// $T(n, m) = O(n \log n \log\log n + m)$
1682 ///
1683 /// $M(n, m) = O(n \log n + m)$
1684 ///
1685 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1686 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1687 ///
1688 /// # Panics
1689 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
1690 /// representable with `prec` bits.
1691 ///
1692 /// # Examples
1693 /// ```
1694 /// use core::f64::consts::{E, PI, SQRT_2};
1695 /// use malachite_base::rounding_modes::RoundingMode::*;
1696 /// use malachite_float::Float;
1697 /// use std::cmp::Ordering::*;
1698 ///
1699 /// let y = Float::from(E);
1700 /// let z = Float::from(SQRT_2);
1701 ///
1702 /// let mut x = Float::from(PI);
1703 /// assert_eq!(
1704 /// x.add_mul_prec_round_assign_val_ref(y.clone(), &z, 5, Floor),
1705 /// Less
1706 /// );
1707 /// assert_eq!(x.to_string(), "6.75");
1708 ///
1709 /// let mut x = Float::from(PI);
1710 /// assert_eq!(
1711 /// x.add_mul_prec_round_assign_val_ref(y.clone(), &z, 5, Ceiling),
1712 /// Greater
1713 /// );
1714 /// assert_eq!(x.to_string(), "7.00");
1715 ///
1716 /// let mut x = Float::from(PI);
1717 /// assert_eq!(
1718 /// x.add_mul_prec_round_assign_val_ref(y.clone(), &z, 5, Nearest),
1719 /// Greater
1720 /// );
1721 /// assert_eq!(x.to_string(), "7.00");
1722 /// ```
1723 #[allow(clippy::needless_pass_by_value)]
1724 #[inline]
1725 pub fn add_mul_prec_round_assign_val_ref(
1726 &mut self,
1727 y: Self,
1728 z: &Self,
1729 prec: u64,
1730 rm: RoundingMode,
1731 ) -> Ordering {
1732 let (s, o) = add_mul_helper(self, &y, z, false, prec, rm);
1733 *self = s;
1734 o
1735 }
1736
1737 /// Adds the product of two [`Float`]s to a [`Float`] in place, rounding the result to the
1738 /// specified precision and with the specified rounding mode. The first [`Float`] on the
1739 /// right-hand side is taken by reference and the second by value. An [`Ordering`] is returned,
1740 /// indicating whether the rounded sum is less than, equal to, or greater than the exact sum.
1741 /// Although `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN`
1742 /// it also returns `Equal`.
1743 ///
1744 /// See [`RoundingMode`] for a description of the possible rounding modes.
1745 ///
1746 /// $$
1747 /// x \gets x+yz+\varepsilon.
1748 /// $$
1749 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1750 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
1751 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1752 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
1753 ///
1754 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
1755 /// overflow, and underflow.
1756 ///
1757 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_prec_assign`]
1758 /// instead. If you know that your target precision is the maximum of the precisions of the
1759 /// inputs, consider using [`Float::add_mul_round_assign`] instead. If both of these things are
1760 /// true, consider using
1761 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
1762 /// instead.
1763 ///
1764 /// # Worst-case complexity
1765 /// $T(n, m) = O(n \log n \log\log n + m)$
1766 ///
1767 /// $M(n, m) = O(n \log n + m)$
1768 ///
1769 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1770 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1771 ///
1772 /// # Panics
1773 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
1774 /// representable with `prec` bits.
1775 ///
1776 /// # Examples
1777 /// ```
1778 /// use core::f64::consts::{E, PI, SQRT_2};
1779 /// use malachite_base::rounding_modes::RoundingMode::*;
1780 /// use malachite_float::Float;
1781 /// use std::cmp::Ordering::*;
1782 ///
1783 /// let y = Float::from(E);
1784 /// let z = Float::from(SQRT_2);
1785 ///
1786 /// let mut x = Float::from(PI);
1787 /// assert_eq!(
1788 /// x.add_mul_prec_round_assign_ref_val(&y, z.clone(), 5, Floor),
1789 /// Less
1790 /// );
1791 /// assert_eq!(x.to_string(), "6.75");
1792 ///
1793 /// let mut x = Float::from(PI);
1794 /// assert_eq!(
1795 /// x.add_mul_prec_round_assign_ref_val(&y, z.clone(), 5, Ceiling),
1796 /// Greater
1797 /// );
1798 /// assert_eq!(x.to_string(), "7.00");
1799 ///
1800 /// let mut x = Float::from(PI);
1801 /// assert_eq!(
1802 /// x.add_mul_prec_round_assign_ref_val(&y, z.clone(), 5, Nearest),
1803 /// Greater
1804 /// );
1805 /// assert_eq!(x.to_string(), "7.00");
1806 /// ```
1807 #[allow(clippy::needless_pass_by_value)]
1808 #[inline]
1809 pub fn add_mul_prec_round_assign_ref_val(
1810 &mut self,
1811 y: &Self,
1812 z: Self,
1813 prec: u64,
1814 rm: RoundingMode,
1815 ) -> Ordering {
1816 let (s, o) = add_mul_helper(self, y, &z, false, prec, rm);
1817 *self = s;
1818 o
1819 }
1820
1821 /// Adds the product of two [`Float`]s to a [`Float`] in place, rounding the result to the
1822 /// specified precision and with the specified rounding mode. Both [`Float`]s on the right-hand
1823 /// side are taken by reference. An [`Ordering`] is returned, indicating whether the rounded sum
1824 /// is less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
1825 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1826 ///
1827 /// See [`RoundingMode`] for a description of the possible rounding modes.
1828 ///
1829 /// $$
1830 /// x \gets x+yz+\varepsilon.
1831 /// $$
1832 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1833 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
1834 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1835 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
1836 ///
1837 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
1838 /// overflow, and underflow.
1839 ///
1840 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_prec_assign`]
1841 /// instead. If you know that your target precision is the maximum of the precisions of the
1842 /// inputs, consider using [`Float::add_mul_round_assign`] instead. If both of these things are
1843 /// true, consider using
1844 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
1845 /// instead.
1846 ///
1847 /// # Worst-case complexity
1848 /// $T(n, m) = O(n \log n \log\log n + m)$
1849 ///
1850 /// $M(n, m) = O(n \log n + m)$
1851 ///
1852 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1853 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1854 ///
1855 /// # Panics
1856 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
1857 /// representable with `prec` bits.
1858 ///
1859 /// # Examples
1860 /// ```
1861 /// use core::f64::consts::{E, PI, SQRT_2};
1862 /// use malachite_base::rounding_modes::RoundingMode::*;
1863 /// use malachite_float::Float;
1864 /// use std::cmp::Ordering::*;
1865 ///
1866 /// let y = Float::from(E);
1867 /// let z = Float::from(SQRT_2);
1868 ///
1869 /// let mut x = Float::from(PI);
1870 /// assert_eq!(x.add_mul_prec_round_assign_ref_ref(&y, &z, 5, Floor), Less);
1871 /// assert_eq!(x.to_string(), "6.75");
1872 ///
1873 /// let mut x = Float::from(PI);
1874 /// assert_eq!(
1875 /// x.add_mul_prec_round_assign_ref_ref(&y, &z, 5, Ceiling),
1876 /// Greater
1877 /// );
1878 /// assert_eq!(x.to_string(), "7.00");
1879 ///
1880 /// let mut x = Float::from(PI);
1881 /// assert_eq!(
1882 /// x.add_mul_prec_round_assign_ref_ref(&y, &z, 5, Nearest),
1883 /// Greater
1884 /// );
1885 /// assert_eq!(x.to_string(), "7.00");
1886 /// ```
1887 #[inline]
1888 pub fn add_mul_prec_round_assign_ref_ref(
1889 &mut self,
1890 y: &Self,
1891 z: &Self,
1892 prec: u64,
1893 rm: RoundingMode,
1894 ) -> Ordering {
1895 let (s, o) = add_mul_helper(self, y, z, false, prec, rm);
1896 *self = s;
1897 o
1898 }
1899
1900 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the nearest
1901 /// value of the specified precision. All three [`Float`]s are taken by value. An [`Ordering`]
1902 /// is also returned, indicating whether the rounded sum is less than, equal to, or greater than
1903 /// the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
1904 /// returns a `NaN` it also returns `Equal`.
1905 ///
1906 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1907 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1908 /// the `Nearest` rounding mode.
1909 ///
1910 /// $$
1911 /// f(x,y,z,p) = x+yz+\varepsilon.
1912 /// $$
1913 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1914 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1915 /// |x+yz|\rfloor-p}$.
1916 ///
1917 /// If the output has a precision, it is `prec`.
1918 ///
1919 /// Special cases:
1920 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
1921 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
1922 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
1923 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
1924 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
1925 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
1926 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
1927 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
1928 /// - $f(0.0,y,z,p)=0.0$ if $yz=0.0$
1929 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=-0.0$
1930 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of different signs
1931 /// - $f(x,y,z,p)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
1932 ///
1933 /// Overflow and underflow:
1934 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1935 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
1936 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1937 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1938 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
1939 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1940 ///
1941 /// If you want to use a rounding mode other than `Nearest`, consider using
1942 /// [`Float::add_mul_prec_round`] instead. If you know that your target precision is the maximum
1943 /// of the precisions of the inputs, consider using
1944 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
1945 ///
1946 /// # Worst-case complexity
1947 /// $T(n, m) = O(n \log n \log\log n + m)$
1948 ///
1949 /// $M(n, m) = O(n \log n + m)$
1950 ///
1951 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1952 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1953 ///
1954 /// # Panics
1955 /// Panics if `prec` is zero.
1956 ///
1957 /// # Examples
1958 /// ```
1959 /// use core::f64::consts::{E, PI, SQRT_2};
1960 /// use malachite_float::Float;
1961 /// use std::cmp::Ordering::*;
1962 ///
1963 /// let x = Float::from(PI);
1964 /// let y = Float::from(E);
1965 /// let z = Float::from(SQRT_2);
1966 ///
1967 /// let (sum, o) = x.clone().add_mul_prec(y.clone(), z.clone(), 5);
1968 /// assert_eq!(sum.to_string(), "7.00");
1969 /// assert_eq!(o, Greater);
1970 ///
1971 /// let (sum, o) = x.clone().add_mul_prec(y.clone(), z.clone(), 20);
1972 /// assert_eq!(sum.to_string(), "6.9858246");
1973 /// assert_eq!(o, Greater);
1974 /// ```
1975 #[allow(clippy::needless_pass_by_value)]
1976 #[inline]
1977 pub fn add_mul_prec(self, y: Self, z: Self, prec: u64) -> (Self, Ordering) {
1978 self.add_mul_prec_round(y, z, prec, Nearest)
1979 }
1980
1981 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the nearest
1982 /// value of the specified precision. The first two [`Float`]s are taken by value and the third
1983 /// by reference. An [`Ordering`] is also returned, indicating whether the rounded sum is less
1984 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
1985 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1986 ///
1987 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1988 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1989 /// the `Nearest` rounding mode.
1990 ///
1991 /// $$
1992 /// f(x,y,z,p) = x+yz+\varepsilon.
1993 /// $$
1994 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1995 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1996 /// |x+yz|\rfloor-p}$.
1997 ///
1998 /// If the output has a precision, it is `prec`.
1999 ///
2000 /// Special cases:
2001 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
2002 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
2003 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
2004 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
2005 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2006 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2007 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
2008 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
2009 /// - $f(0.0,y,z,p)=0.0$ if $yz=0.0$
2010 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=-0.0$
2011 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of different signs
2012 /// - $f(x,y,z,p)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
2013 ///
2014 /// Overflow and underflow:
2015 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2016 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2017 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2018 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2019 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
2020 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2021 ///
2022 /// If you want to use a rounding mode other than `Nearest`, consider using
2023 /// [`Float::add_mul_prec_round`] instead. If you know that your target precision is the maximum
2024 /// of the precisions of the inputs, consider using
2025 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
2026 ///
2027 /// # Worst-case complexity
2028 /// $T(n, m) = O(n \log n \log\log n + m)$
2029 ///
2030 /// $M(n, m) = O(n \log n + m)$
2031 ///
2032 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2033 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2034 ///
2035 /// # Panics
2036 /// Panics if `prec` is zero.
2037 ///
2038 /// # Examples
2039 /// ```
2040 /// use core::f64::consts::{E, PI, SQRT_2};
2041 /// use malachite_float::Float;
2042 /// use std::cmp::Ordering::*;
2043 ///
2044 /// let x = Float::from(PI);
2045 /// let y = Float::from(E);
2046 /// let z = Float::from(SQRT_2);
2047 ///
2048 /// let (sum, o) = x.clone().add_mul_prec_val_val_ref(y.clone(), &z, 5);
2049 /// assert_eq!(sum.to_string(), "7.00");
2050 /// assert_eq!(o, Greater);
2051 ///
2052 /// let (sum, o) = x.clone().add_mul_prec_val_val_ref(y.clone(), &z, 20);
2053 /// assert_eq!(sum.to_string(), "6.9858246");
2054 /// assert_eq!(o, Greater);
2055 /// ```
2056 #[allow(clippy::needless_pass_by_value)]
2057 #[inline]
2058 pub fn add_mul_prec_val_val_ref(self, y: Self, z: &Self, prec: u64) -> (Self, Ordering) {
2059 self.add_mul_prec_round_val_val_ref(y, z, prec, Nearest)
2060 }
2061
2062 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the nearest
2063 /// value of the specified precision. The first and third [`Float`]s are taken by value and the
2064 /// second by reference. An [`Ordering`] is also returned, indicating whether the rounded sum is
2065 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
2066 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2067 ///
2068 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2069 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2070 /// the `Nearest` rounding mode.
2071 ///
2072 /// $$
2073 /// f(x,y,z,p) = x+yz+\varepsilon.
2074 /// $$
2075 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2076 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2077 /// |x+yz|\rfloor-p}$.
2078 ///
2079 /// If the output has a precision, it is `prec`.
2080 ///
2081 /// Special cases:
2082 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
2083 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
2084 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
2085 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
2086 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2087 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2088 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
2089 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
2090 /// - $f(0.0,y,z,p)=0.0$ if $yz=0.0$
2091 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=-0.0$
2092 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of different signs
2093 /// - $f(x,y,z,p)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
2094 ///
2095 /// Overflow and underflow:
2096 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2097 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2098 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2099 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2100 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
2101 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2102 ///
2103 /// If you want to use a rounding mode other than `Nearest`, consider using
2104 /// [`Float::add_mul_prec_round`] instead. If you know that your target precision is the maximum
2105 /// of the precisions of the inputs, consider using
2106 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
2107 ///
2108 /// # Worst-case complexity
2109 /// $T(n, m) = O(n \log n \log\log n + m)$
2110 ///
2111 /// $M(n, m) = O(n \log n + m)$
2112 ///
2113 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2114 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2115 ///
2116 /// # Panics
2117 /// Panics if `prec` is zero.
2118 ///
2119 /// # Examples
2120 /// ```
2121 /// use core::f64::consts::{E, PI, SQRT_2};
2122 /// use malachite_float::Float;
2123 /// use std::cmp::Ordering::*;
2124 ///
2125 /// let x = Float::from(PI);
2126 /// let y = Float::from(E);
2127 /// let z = Float::from(SQRT_2);
2128 ///
2129 /// let (sum, o) = x.clone().add_mul_prec_val_ref_val(&y, z.clone(), 5);
2130 /// assert_eq!(sum.to_string(), "7.00");
2131 /// assert_eq!(o, Greater);
2132 ///
2133 /// let (sum, o) = x.clone().add_mul_prec_val_ref_val(&y, z.clone(), 20);
2134 /// assert_eq!(sum.to_string(), "6.9858246");
2135 /// assert_eq!(o, Greater);
2136 /// ```
2137 #[allow(clippy::needless_pass_by_value)]
2138 #[inline]
2139 pub fn add_mul_prec_val_ref_val(self, y: &Self, z: Self, prec: u64) -> (Self, Ordering) {
2140 self.add_mul_prec_round_val_ref_val(y, z, prec, Nearest)
2141 }
2142
2143 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the nearest
2144 /// value of the specified precision. The first [`Float`] is taken by value and the second and
2145 /// third by reference. An [`Ordering`] is also returned, indicating whether the rounded sum is
2146 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
2147 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2148 ///
2149 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2150 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2151 /// the `Nearest` rounding mode.
2152 ///
2153 /// $$
2154 /// f(x,y,z,p) = x+yz+\varepsilon.
2155 /// $$
2156 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2157 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2158 /// |x+yz|\rfloor-p}$.
2159 ///
2160 /// If the output has a precision, it is `prec`.
2161 ///
2162 /// Special cases:
2163 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
2164 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
2165 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
2166 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
2167 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2168 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2169 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
2170 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
2171 /// - $f(0.0,y,z,p)=0.0$ if $yz=0.0$
2172 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=-0.0$
2173 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of different signs
2174 /// - $f(x,y,z,p)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
2175 ///
2176 /// Overflow and underflow:
2177 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2178 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2179 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2180 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2181 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
2182 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2183 ///
2184 /// If you want to use a rounding mode other than `Nearest`, consider using
2185 /// [`Float::add_mul_prec_round`] instead. If you know that your target precision is the maximum
2186 /// of the precisions of the inputs, consider using
2187 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
2188 ///
2189 /// # Worst-case complexity
2190 /// $T(n, m) = O(n \log n \log\log n + m)$
2191 ///
2192 /// $M(n, m) = O(n \log n + m)$
2193 ///
2194 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2195 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2196 ///
2197 /// # Panics
2198 /// Panics if `prec` is zero.
2199 ///
2200 /// # Examples
2201 /// ```
2202 /// use core::f64::consts::{E, PI, SQRT_2};
2203 /// use malachite_float::Float;
2204 /// use std::cmp::Ordering::*;
2205 ///
2206 /// let x = Float::from(PI);
2207 /// let y = Float::from(E);
2208 /// let z = Float::from(SQRT_2);
2209 ///
2210 /// let (sum, o) = x.clone().add_mul_prec_val_ref_ref(&y, &z, 5);
2211 /// assert_eq!(sum.to_string(), "7.00");
2212 /// assert_eq!(o, Greater);
2213 ///
2214 /// let (sum, o) = x.clone().add_mul_prec_val_ref_ref(&y, &z, 20);
2215 /// assert_eq!(sum.to_string(), "6.9858246");
2216 /// assert_eq!(o, Greater);
2217 /// ```
2218 #[inline]
2219 pub fn add_mul_prec_val_ref_ref(self, y: &Self, z: &Self, prec: u64) -> (Self, Ordering) {
2220 self.add_mul_prec_round_val_ref_ref(y, z, prec, Nearest)
2221 }
2222
2223 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the nearest
2224 /// value of the specified precision. The first [`Float`] is taken by reference and the second
2225 /// and third by value. An [`Ordering`] is also returned, indicating whether the rounded sum is
2226 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
2227 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2228 ///
2229 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2230 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2231 /// the `Nearest` rounding mode.
2232 ///
2233 /// $$
2234 /// f(x,y,z,p) = x+yz+\varepsilon.
2235 /// $$
2236 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2237 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2238 /// |x+yz|\rfloor-p}$.
2239 ///
2240 /// If the output has a precision, it is `prec`.
2241 ///
2242 /// Special cases:
2243 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
2244 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
2245 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
2246 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
2247 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2248 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2249 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
2250 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
2251 /// - $f(0.0,y,z,p)=0.0$ if $yz=0.0$
2252 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=-0.0$
2253 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of different signs
2254 /// - $f(x,y,z,p)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
2255 ///
2256 /// Overflow and underflow:
2257 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2258 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2259 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2260 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2261 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
2262 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2263 ///
2264 /// If you want to use a rounding mode other than `Nearest`, consider using
2265 /// [`Float::add_mul_prec_round`] instead. If you know that your target precision is the maximum
2266 /// of the precisions of the inputs, consider using
2267 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
2268 ///
2269 /// # Worst-case complexity
2270 /// $T(n, m) = O(n \log n \log\log n + m)$
2271 ///
2272 /// $M(n, m) = O(n \log n + m)$
2273 ///
2274 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2275 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2276 ///
2277 /// # Panics
2278 /// Panics if `prec` is zero.
2279 ///
2280 /// # Examples
2281 /// ```
2282 /// use core::f64::consts::{E, PI, SQRT_2};
2283 /// use malachite_float::Float;
2284 /// use std::cmp::Ordering::*;
2285 ///
2286 /// let x = Float::from(PI);
2287 /// let y = Float::from(E);
2288 /// let z = Float::from(SQRT_2);
2289 ///
2290 /// let (sum, o) = x.add_mul_prec_ref_val_val(y.clone(), z.clone(), 5);
2291 /// assert_eq!(sum.to_string(), "7.00");
2292 /// assert_eq!(o, Greater);
2293 ///
2294 /// let (sum, o) = x.add_mul_prec_ref_val_val(y.clone(), z.clone(), 20);
2295 /// assert_eq!(sum.to_string(), "6.9858246");
2296 /// assert_eq!(o, Greater);
2297 /// ```
2298 #[allow(clippy::needless_pass_by_value)]
2299 #[inline]
2300 pub fn add_mul_prec_ref_val_val(&self, y: Self, z: Self, prec: u64) -> (Self, Ordering) {
2301 self.add_mul_prec_round_ref_val_val(y, z, prec, Nearest)
2302 }
2303
2304 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the nearest
2305 /// value of the specified precision. The first and third [`Float`]s are taken by reference and
2306 /// the second by value. An [`Ordering`] is also returned, indicating whether the rounded sum is
2307 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
2308 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2309 ///
2310 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2311 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2312 /// the `Nearest` rounding mode.
2313 ///
2314 /// $$
2315 /// f(x,y,z,p) = x+yz+\varepsilon.
2316 /// $$
2317 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2318 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2319 /// |x+yz|\rfloor-p}$.
2320 ///
2321 /// If the output has a precision, it is `prec`.
2322 ///
2323 /// Special cases:
2324 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
2325 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
2326 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
2327 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
2328 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2329 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2330 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
2331 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
2332 /// - $f(0.0,y,z,p)=0.0$ if $yz=0.0$
2333 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=-0.0$
2334 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of different signs
2335 /// - $f(x,y,z,p)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
2336 ///
2337 /// Overflow and underflow:
2338 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2339 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2340 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2341 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2342 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
2343 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2344 ///
2345 /// If you want to use a rounding mode other than `Nearest`, consider using
2346 /// [`Float::add_mul_prec_round`] instead. If you know that your target precision is the maximum
2347 /// of the precisions of the inputs, consider using
2348 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
2349 ///
2350 /// # Worst-case complexity
2351 /// $T(n, m) = O(n \log n \log\log n + m)$
2352 ///
2353 /// $M(n, m) = O(n \log n + m)$
2354 ///
2355 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2356 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2357 ///
2358 /// # Panics
2359 /// Panics if `prec` is zero.
2360 ///
2361 /// # Examples
2362 /// ```
2363 /// use core::f64::consts::{E, PI, SQRT_2};
2364 /// use malachite_float::Float;
2365 /// use std::cmp::Ordering::*;
2366 ///
2367 /// let x = Float::from(PI);
2368 /// let y = Float::from(E);
2369 /// let z = Float::from(SQRT_2);
2370 ///
2371 /// let (sum, o) = x.add_mul_prec_ref_val_ref(y.clone(), &z, 5);
2372 /// assert_eq!(sum.to_string(), "7.00");
2373 /// assert_eq!(o, Greater);
2374 ///
2375 /// let (sum, o) = x.add_mul_prec_ref_val_ref(y.clone(), &z, 20);
2376 /// assert_eq!(sum.to_string(), "6.9858246");
2377 /// assert_eq!(o, Greater);
2378 /// ```
2379 #[allow(clippy::needless_pass_by_value)]
2380 #[inline]
2381 pub fn add_mul_prec_ref_val_ref(&self, y: Self, z: &Self, prec: u64) -> (Self, Ordering) {
2382 self.add_mul_prec_round_ref_val_ref(y, z, prec, Nearest)
2383 }
2384
2385 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the nearest
2386 /// value of the specified precision. The first two [`Float`]s are taken by reference and the
2387 /// third by value. An [`Ordering`] is also returned, indicating whether the rounded sum is less
2388 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
2389 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2390 ///
2391 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2392 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2393 /// the `Nearest` rounding mode.
2394 ///
2395 /// $$
2396 /// f(x,y,z,p) = x+yz+\varepsilon.
2397 /// $$
2398 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2399 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2400 /// |x+yz|\rfloor-p}$.
2401 ///
2402 /// If the output has a precision, it is `prec`.
2403 ///
2404 /// Special cases:
2405 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
2406 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
2407 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
2408 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
2409 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2410 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2411 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
2412 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
2413 /// - $f(0.0,y,z,p)=0.0$ if $yz=0.0$
2414 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=-0.0$
2415 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of different signs
2416 /// - $f(x,y,z,p)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
2417 ///
2418 /// Overflow and underflow:
2419 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2420 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2421 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2422 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2423 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
2424 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2425 ///
2426 /// If you want to use a rounding mode other than `Nearest`, consider using
2427 /// [`Float::add_mul_prec_round`] instead. If you know that your target precision is the maximum
2428 /// of the precisions of the inputs, consider using
2429 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
2430 ///
2431 /// # Worst-case complexity
2432 /// $T(n, m) = O(n \log n \log\log n + m)$
2433 ///
2434 /// $M(n, m) = O(n \log n + m)$
2435 ///
2436 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2437 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2438 ///
2439 /// # Panics
2440 /// Panics if `prec` is zero.
2441 ///
2442 /// # Examples
2443 /// ```
2444 /// use core::f64::consts::{E, PI, SQRT_2};
2445 /// use malachite_float::Float;
2446 /// use std::cmp::Ordering::*;
2447 ///
2448 /// let x = Float::from(PI);
2449 /// let y = Float::from(E);
2450 /// let z = Float::from(SQRT_2);
2451 ///
2452 /// let (sum, o) = x.add_mul_prec_ref_ref_val(&y, z.clone(), 5);
2453 /// assert_eq!(sum.to_string(), "7.00");
2454 /// assert_eq!(o, Greater);
2455 ///
2456 /// let (sum, o) = x.add_mul_prec_ref_ref_val(&y, z.clone(), 20);
2457 /// assert_eq!(sum.to_string(), "6.9858246");
2458 /// assert_eq!(o, Greater);
2459 /// ```
2460 #[allow(clippy::needless_pass_by_value)]
2461 #[inline]
2462 pub fn add_mul_prec_ref_ref_val(&self, y: &Self, z: Self, prec: u64) -> (Self, Ordering) {
2463 self.add_mul_prec_round_ref_ref_val(y, z, prec, Nearest)
2464 }
2465
2466 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result to the nearest
2467 /// value of the specified precision. All three [`Float`]s are taken by reference. An
2468 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
2469 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
2470 /// this function returns a `NaN` it also returns `Equal`.
2471 ///
2472 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2473 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2474 /// the `Nearest` rounding mode.
2475 ///
2476 /// $$
2477 /// f(x,y,z,p) = x+yz+\varepsilon.
2478 /// $$
2479 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2480 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2481 /// |x+yz|\rfloor-p}$.
2482 ///
2483 /// If the output has a precision, it is `prec`.
2484 ///
2485 /// Special cases:
2486 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
2487 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
2488 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
2489 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
2490 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2491 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2492 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
2493 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
2494 /// - $f(0.0,y,z,p)=0.0$ if $yz=0.0$
2495 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=-0.0$
2496 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of different signs
2497 /// - $f(x,y,z,p)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
2498 ///
2499 /// Overflow and underflow:
2500 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2501 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2502 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2503 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2504 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
2505 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2506 ///
2507 /// If you want to use a rounding mode other than `Nearest`, consider using
2508 /// [`Float::add_mul_prec_round`] instead. If you know that your target precision is the maximum
2509 /// of the precisions of the inputs, consider using
2510 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
2511 ///
2512 /// # Worst-case complexity
2513 /// $T(n, m) = O(n \log n \log\log n + m)$
2514 ///
2515 /// $M(n, m) = O(n \log n + m)$
2516 ///
2517 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2518 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2519 ///
2520 /// # Panics
2521 /// Panics if `prec` is zero.
2522 ///
2523 /// # Examples
2524 /// ```
2525 /// use core::f64::consts::{E, PI, SQRT_2};
2526 /// use malachite_float::Float;
2527 /// use std::cmp::Ordering::*;
2528 ///
2529 /// let x = Float::from(PI);
2530 /// let y = Float::from(E);
2531 /// let z = Float::from(SQRT_2);
2532 ///
2533 /// let (sum, o) = x.add_mul_prec_ref_ref_ref(&y, &z, 5);
2534 /// assert_eq!(sum.to_string(), "7.00");
2535 /// assert_eq!(o, Greater);
2536 ///
2537 /// let (sum, o) = x.add_mul_prec_ref_ref_ref(&y, &z, 20);
2538 /// assert_eq!(sum.to_string(), "6.9858246");
2539 /// assert_eq!(o, Greater);
2540 /// ```
2541 #[inline]
2542 pub fn add_mul_prec_ref_ref_ref(&self, y: &Self, z: &Self, prec: u64) -> (Self, Ordering) {
2543 self.add_mul_prec_round_ref_ref_ref(y, z, prec, Nearest)
2544 }
2545
2546 /// Adds the product of two [`Float`]s to a [`Float`] in place, rounding the result to the
2547 /// nearest value of the specified precision. Both [`Float`]s on the right-hand side are taken
2548 /// by value. An [`Ordering`] is returned, indicating whether the rounded sum is less than,
2549 /// equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
2550 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
2551 ///
2552 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2553 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2554 /// the `Nearest` rounding mode.
2555 ///
2556 /// $$
2557 /// x \gets x+yz+\varepsilon.
2558 /// $$
2559 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2560 /// |x+yz|\rfloor-p}$.
2561 ///
2562 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
2563 /// overflow, and underflow.
2564 ///
2565 /// If you want to use a rounding mode other than `Nearest`, consider using
2566 /// [`Float::add_mul_prec_round_assign`] instead. If you know that your target precision is the
2567 /// maximum of the precisions of the inputs, consider using
2568 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
2569 /// instead.
2570 ///
2571 /// # Worst-case complexity
2572 /// $T(n, m) = O(n \log n \log\log n + m)$
2573 ///
2574 /// $M(n, m) = O(n \log n + m)$
2575 ///
2576 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2577 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2578 ///
2579 /// # Panics
2580 /// Panics if `prec` is zero.
2581 ///
2582 /// # Examples
2583 /// ```
2584 /// use core::f64::consts::{E, PI, SQRT_2};
2585 /// use malachite_float::Float;
2586 /// use std::cmp::Ordering::*;
2587 ///
2588 /// let y = Float::from(E);
2589 /// let z = Float::from(SQRT_2);
2590 ///
2591 /// let mut x = Float::from(PI);
2592 /// assert_eq!(x.add_mul_prec_assign(y.clone(), z.clone(), 5), Greater);
2593 /// assert_eq!(x.to_string(), "7.00");
2594 ///
2595 /// let mut x = Float::from(PI);
2596 /// assert_eq!(x.add_mul_prec_assign(y.clone(), z.clone(), 20), Greater);
2597 /// assert_eq!(x.to_string(), "6.9858246");
2598 /// ```
2599 #[allow(clippy::needless_pass_by_value)]
2600 #[inline]
2601 pub fn add_mul_prec_assign(&mut self, y: Self, z: Self, prec: u64) -> Ordering {
2602 self.add_mul_prec_round_assign(y, z, prec, Nearest)
2603 }
2604
2605 /// Adds the product of two [`Float`]s to a [`Float`] in place, rounding the result to the
2606 /// nearest value of the specified precision. The first [`Float`] on the right-hand side is
2607 /// taken by value and the second by reference. An [`Ordering`] is returned, indicating whether
2608 /// the rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are
2609 /// not comparable to any [`Float`], whenever this function assigns a `NaN` it also returns
2610 /// `Equal`.
2611 ///
2612 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2613 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2614 /// the `Nearest` rounding mode.
2615 ///
2616 /// $$
2617 /// x \gets x+yz+\varepsilon.
2618 /// $$
2619 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2620 /// |x+yz|\rfloor-p}$.
2621 ///
2622 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
2623 /// overflow, and underflow.
2624 ///
2625 /// If you want to use a rounding mode other than `Nearest`, consider using
2626 /// [`Float::add_mul_prec_round_assign`] instead. If you know that your target precision is the
2627 /// maximum of the precisions of the inputs, consider using
2628 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
2629 /// instead.
2630 ///
2631 /// # Worst-case complexity
2632 /// $T(n, m) = O(n \log n \log\log n + m)$
2633 ///
2634 /// $M(n, m) = O(n \log n + m)$
2635 ///
2636 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2637 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2638 ///
2639 /// # Panics
2640 /// Panics if `prec` is zero.
2641 ///
2642 /// # Examples
2643 /// ```
2644 /// use core::f64::consts::{E, PI, SQRT_2};
2645 /// use malachite_float::Float;
2646 /// use std::cmp::Ordering::*;
2647 ///
2648 /// let y = Float::from(E);
2649 /// let z = Float::from(SQRT_2);
2650 ///
2651 /// let mut x = Float::from(PI);
2652 /// assert_eq!(x.add_mul_prec_assign_val_ref(y.clone(), &z, 5), Greater);
2653 /// assert_eq!(x.to_string(), "7.00");
2654 ///
2655 /// let mut x = Float::from(PI);
2656 /// assert_eq!(x.add_mul_prec_assign_val_ref(y.clone(), &z, 20), Greater);
2657 /// assert_eq!(x.to_string(), "6.9858246");
2658 /// ```
2659 #[allow(clippy::needless_pass_by_value)]
2660 #[inline]
2661 pub fn add_mul_prec_assign_val_ref(&mut self, y: Self, z: &Self, prec: u64) -> Ordering {
2662 self.add_mul_prec_round_assign_val_ref(y, z, prec, Nearest)
2663 }
2664
2665 /// Adds the product of two [`Float`]s to a [`Float`] in place, rounding the result to the
2666 /// nearest value of the specified precision. The first [`Float`] on the right-hand side is
2667 /// taken by reference and the second by value. An [`Ordering`] is returned, indicating whether
2668 /// the rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are
2669 /// not comparable to any [`Float`], whenever this function assigns a `NaN` it also returns
2670 /// `Equal`.
2671 ///
2672 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2673 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2674 /// the `Nearest` rounding mode.
2675 ///
2676 /// $$
2677 /// x \gets x+yz+\varepsilon.
2678 /// $$
2679 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2680 /// |x+yz|\rfloor-p}$.
2681 ///
2682 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
2683 /// overflow, and underflow.
2684 ///
2685 /// If you want to use a rounding mode other than `Nearest`, consider using
2686 /// [`Float::add_mul_prec_round_assign`] instead. If you know that your target precision is the
2687 /// maximum of the precisions of the inputs, consider using
2688 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
2689 /// instead.
2690 ///
2691 /// # Worst-case complexity
2692 /// $T(n, m) = O(n \log n \log\log n + m)$
2693 ///
2694 /// $M(n, m) = O(n \log n + m)$
2695 ///
2696 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2697 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2698 ///
2699 /// # Panics
2700 /// Panics if `prec` is zero.
2701 ///
2702 /// # Examples
2703 /// ```
2704 /// use core::f64::consts::{E, PI, SQRT_2};
2705 /// use malachite_float::Float;
2706 /// use std::cmp::Ordering::*;
2707 ///
2708 /// let y = Float::from(E);
2709 /// let z = Float::from(SQRT_2);
2710 ///
2711 /// let mut x = Float::from(PI);
2712 /// assert_eq!(x.add_mul_prec_assign_ref_val(&y, z.clone(), 5), Greater);
2713 /// assert_eq!(x.to_string(), "7.00");
2714 ///
2715 /// let mut x = Float::from(PI);
2716 /// assert_eq!(x.add_mul_prec_assign_ref_val(&y, z.clone(), 20), Greater);
2717 /// assert_eq!(x.to_string(), "6.9858246");
2718 /// ```
2719 #[allow(clippy::needless_pass_by_value)]
2720 #[inline]
2721 pub fn add_mul_prec_assign_ref_val(&mut self, y: &Self, z: Self, prec: u64) -> Ordering {
2722 self.add_mul_prec_round_assign_ref_val(y, z, prec, Nearest)
2723 }
2724
2725 /// Adds the product of two [`Float`]s to a [`Float`] in place, rounding the result to the
2726 /// nearest value of the specified precision. Both [`Float`]s on the right-hand side are taken
2727 /// by reference. An [`Ordering`] is returned, indicating whether the rounded sum is less than,
2728 /// equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
2729 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
2730 ///
2731 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2732 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2733 /// the `Nearest` rounding mode.
2734 ///
2735 /// $$
2736 /// x \gets x+yz+\varepsilon.
2737 /// $$
2738 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2739 /// |x+yz|\rfloor-p}$.
2740 ///
2741 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
2742 /// overflow, and underflow.
2743 ///
2744 /// If you want to use a rounding mode other than `Nearest`, consider using
2745 /// [`Float::add_mul_prec_round_assign`] instead. If you know that your target precision is the
2746 /// maximum of the precisions of the inputs, consider using
2747 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
2748 /// instead.
2749 ///
2750 /// # Worst-case complexity
2751 /// $T(n, m) = O(n \log n \log\log n + m)$
2752 ///
2753 /// $M(n, m) = O(n \log n + m)$
2754 ///
2755 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2756 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2757 ///
2758 /// # Panics
2759 /// Panics if `prec` is zero.
2760 ///
2761 /// # Examples
2762 /// ```
2763 /// use core::f64::consts::{E, PI, SQRT_2};
2764 /// use malachite_float::Float;
2765 /// use std::cmp::Ordering::*;
2766 ///
2767 /// let y = Float::from(E);
2768 /// let z = Float::from(SQRT_2);
2769 ///
2770 /// let mut x = Float::from(PI);
2771 /// assert_eq!(x.add_mul_prec_assign_ref_ref(&y, &z, 5), Greater);
2772 /// assert_eq!(x.to_string(), "7.00");
2773 ///
2774 /// let mut x = Float::from(PI);
2775 /// assert_eq!(x.add_mul_prec_assign_ref_ref(&y, &z, 20), Greater);
2776 /// assert_eq!(x.to_string(), "6.9858246");
2777 /// ```
2778 #[inline]
2779 pub fn add_mul_prec_assign_ref_ref(&mut self, y: &Self, z: &Self, prec: u64) -> Ordering {
2780 self.add_mul_prec_round_assign_ref_ref(y, z, prec, Nearest)
2781 }
2782
2783 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result with the
2784 /// specified rounding mode. All three [`Float`]s are taken by value. An [`Ordering`] is also
2785 /// returned, indicating whether the rounded sum is less than, equal to, or greater than the
2786 /// exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
2787 /// returns a `NaN` it also returns `Equal`.
2788 ///
2789 /// The precision of the output is the maximum of the precisions of the inputs. See
2790 /// [`RoundingMode`] for a description of the possible rounding modes.
2791 ///
2792 /// $$
2793 /// f(x,y,z,m) = x+yz+\varepsilon.
2794 /// $$
2795 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2796 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2797 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
2798 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
2799 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
2800 ///
2801 /// If the output has a precision, it is the maximum of the precisions of the inputs.
2802 ///
2803 /// Special cases:
2804 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
2805 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
2806 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
2807 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
2808 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2809 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2810 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
2811 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
2812 /// - $f(0.0,y,z,m)=0.0$ if $yz=0.0$
2813 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=-0.0$
2814 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
2815 /// not `Floor`
2816 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
2817 /// `Floor`
2818 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
2819 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
2820 ///
2821 /// Overflow and underflow:
2822 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
2823 /// returned instead.
2824 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
2825 /// is returned instead, where `p` is the precision of the output.
2826 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
2827 /// returned instead.
2828 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
2829 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
2830 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
2831 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
2832 /// instead.
2833 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
2834 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
2835 /// instead.
2836 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
2837 /// instead.
2838 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
2839 /// instead.
2840 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
2841 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
2842 /// returned instead.
2843 ///
2844 /// If you want to specify an output precision, consider using [`Float::add_mul_prec_round`]
2845 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
2846 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
2847 ///
2848 /// # Worst-case complexity
2849 /// $T(n, m) = O(n \log n \log\log n + m)$
2850 ///
2851 /// $M(n, m) = O(n \log n + m)$
2852 ///
2853 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2854 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
2855 ///
2856 /// # Panics
2857 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
2858 /// represent the output.
2859 ///
2860 /// # Examples
2861 /// ```
2862 /// use core::f64::consts::{E, PI, SQRT_2};
2863 /// use malachite_base::rounding_modes::RoundingMode::*;
2864 /// use malachite_float::Float;
2865 /// use std::cmp::Ordering::*;
2866 ///
2867 /// let x = Float::from(PI);
2868 /// let y = Float::from(E);
2869 /// let z = Float::from(SQRT_2);
2870 ///
2871 /// let (sum, o) = x.clone().add_mul_round(y.clone(), z.clone(), Floor);
2872 /// assert_eq!(sum.to_string(), "6.9858236817489097");
2873 /// assert_eq!(o, Less);
2874 ///
2875 /// let (sum, o) = x.clone().add_mul_round(y.clone(), z.clone(), Ceiling);
2876 /// assert_eq!(sum.to_string(), "6.9858236817489106");
2877 /// assert_eq!(o, Greater);
2878 ///
2879 /// let (sum, o) = x.clone().add_mul_round(y.clone(), z.clone(), Nearest);
2880 /// assert_eq!(sum.to_string(), "6.9858236817489097");
2881 /// assert_eq!(o, Less);
2882 /// ```
2883 #[allow(clippy::needless_pass_by_value)]
2884 #[inline]
2885 pub fn add_mul_round(self, y: Self, z: Self, rm: RoundingMode) -> (Self, Ordering) {
2886 let prec = max!(
2887 self.significant_bits(),
2888 y.significant_bits(),
2889 z.significant_bits()
2890 );
2891 self.add_mul_prec_round(y, z, prec, rm)
2892 }
2893
2894 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result with the
2895 /// specified rounding mode. The first two [`Float`]s are taken by value and the third by
2896 /// reference. An [`Ordering`] is also returned, indicating whether the rounded sum is less
2897 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
2898 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2899 ///
2900 /// The precision of the output is the maximum of the precisions of the inputs. See
2901 /// [`RoundingMode`] for a description of the possible rounding modes.
2902 ///
2903 /// $$
2904 /// f(x,y,z,m) = x+yz+\varepsilon.
2905 /// $$
2906 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2907 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2908 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
2909 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
2910 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
2911 ///
2912 /// If the output has a precision, it is the maximum of the precisions of the inputs.
2913 ///
2914 /// Special cases:
2915 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
2916 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
2917 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
2918 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
2919 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2920 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2921 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
2922 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
2923 /// - $f(0.0,y,z,m)=0.0$ if $yz=0.0$
2924 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=-0.0$
2925 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
2926 /// not `Floor`
2927 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
2928 /// `Floor`
2929 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
2930 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
2931 ///
2932 /// Overflow and underflow:
2933 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
2934 /// returned instead.
2935 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
2936 /// is returned instead, where `p` is the precision of the output.
2937 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
2938 /// returned instead.
2939 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
2940 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
2941 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
2942 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
2943 /// instead.
2944 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
2945 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
2946 /// instead.
2947 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
2948 /// instead.
2949 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
2950 /// instead.
2951 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
2952 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
2953 /// returned instead.
2954 ///
2955 /// If you want to specify an output precision, consider using [`Float::add_mul_prec_round`]
2956 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
2957 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
2958 ///
2959 /// # Worst-case complexity
2960 /// $T(n, m) = O(n \log n \log\log n + m)$
2961 ///
2962 /// $M(n, m) = O(n \log n + m)$
2963 ///
2964 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2965 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
2966 ///
2967 /// # Panics
2968 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
2969 /// represent the output.
2970 ///
2971 /// # Examples
2972 /// ```
2973 /// use core::f64::consts::{E, PI, SQRT_2};
2974 /// use malachite_base::rounding_modes::RoundingMode::*;
2975 /// use malachite_float::Float;
2976 /// use std::cmp::Ordering::*;
2977 ///
2978 /// let x = Float::from(PI);
2979 /// let y = Float::from(E);
2980 /// let z = Float::from(SQRT_2);
2981 ///
2982 /// let (sum, o) = x.clone().add_mul_round_val_val_ref(y.clone(), &z, Floor);
2983 /// assert_eq!(sum.to_string(), "6.9858236817489097");
2984 /// assert_eq!(o, Less);
2985 ///
2986 /// let (sum, o) = x.clone().add_mul_round_val_val_ref(y.clone(), &z, Ceiling);
2987 /// assert_eq!(sum.to_string(), "6.9858236817489106");
2988 /// assert_eq!(o, Greater);
2989 ///
2990 /// let (sum, o) = x.clone().add_mul_round_val_val_ref(y.clone(), &z, Nearest);
2991 /// assert_eq!(sum.to_string(), "6.9858236817489097");
2992 /// assert_eq!(o, Less);
2993 /// ```
2994 #[allow(clippy::needless_pass_by_value)]
2995 #[inline]
2996 pub fn add_mul_round_val_val_ref(
2997 self,
2998 y: Self,
2999 z: &Self,
3000 rm: RoundingMode,
3001 ) -> (Self, Ordering) {
3002 let prec = max!(
3003 self.significant_bits(),
3004 y.significant_bits(),
3005 z.significant_bits()
3006 );
3007 self.add_mul_prec_round_val_val_ref(y, z, prec, rm)
3008 }
3009
3010 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result with the
3011 /// specified rounding mode. The first and third [`Float`]s are taken by value and the second by
3012 /// reference. An [`Ordering`] is also returned, indicating whether the rounded sum is less
3013 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
3014 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3015 ///
3016 /// The precision of the output is the maximum of the precisions of the inputs. See
3017 /// [`RoundingMode`] for a description of the possible rounding modes.
3018 ///
3019 /// $$
3020 /// f(x,y,z,m) = x+yz+\varepsilon.
3021 /// $$
3022 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3023 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3024 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3025 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3026 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3027 ///
3028 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3029 ///
3030 /// Special cases:
3031 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
3032 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
3033 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
3034 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
3035 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
3036 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
3037 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
3038 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
3039 /// - $f(0.0,y,z,m)=0.0$ if $yz=0.0$
3040 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=-0.0$
3041 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
3042 /// not `Floor`
3043 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
3044 /// `Floor`
3045 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
3046 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
3047 ///
3048 /// Overflow and underflow:
3049 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3050 /// returned instead.
3051 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
3052 /// is returned instead, where `p` is the precision of the output.
3053 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3054 /// returned instead.
3055 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3056 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3057 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3058 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3059 /// instead.
3060 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3061 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
3062 /// instead.
3063 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3064 /// instead.
3065 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3066 /// instead.
3067 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3068 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3069 /// returned instead.
3070 ///
3071 /// If you want to specify an output precision, consider using [`Float::add_mul_prec_round`]
3072 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3073 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
3074 ///
3075 /// # Worst-case complexity
3076 /// $T(n, m) = O(n \log n \log\log n + m)$
3077 ///
3078 /// $M(n, m) = O(n \log n + m)$
3079 ///
3080 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3081 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3082 ///
3083 /// # Panics
3084 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3085 /// represent the output.
3086 ///
3087 /// # Examples
3088 /// ```
3089 /// use core::f64::consts::{E, PI, SQRT_2};
3090 /// use malachite_base::rounding_modes::RoundingMode::*;
3091 /// use malachite_float::Float;
3092 /// use std::cmp::Ordering::*;
3093 ///
3094 /// let x = Float::from(PI);
3095 /// let y = Float::from(E);
3096 /// let z = Float::from(SQRT_2);
3097 ///
3098 /// let (sum, o) = x.clone().add_mul_round_val_ref_val(&y, z.clone(), Floor);
3099 /// assert_eq!(sum.to_string(), "6.9858236817489097");
3100 /// assert_eq!(o, Less);
3101 ///
3102 /// let (sum, o) = x.clone().add_mul_round_val_ref_val(&y, z.clone(), Ceiling);
3103 /// assert_eq!(sum.to_string(), "6.9858236817489106");
3104 /// assert_eq!(o, Greater);
3105 ///
3106 /// let (sum, o) = x.clone().add_mul_round_val_ref_val(&y, z.clone(), Nearest);
3107 /// assert_eq!(sum.to_string(), "6.9858236817489097");
3108 /// assert_eq!(o, Less);
3109 /// ```
3110 #[allow(clippy::needless_pass_by_value)]
3111 #[inline]
3112 pub fn add_mul_round_val_ref_val(
3113 self,
3114 y: &Self,
3115 z: Self,
3116 rm: RoundingMode,
3117 ) -> (Self, Ordering) {
3118 let prec = max!(
3119 self.significant_bits(),
3120 y.significant_bits(),
3121 z.significant_bits()
3122 );
3123 self.add_mul_prec_round_val_ref_val(y, z, prec, rm)
3124 }
3125
3126 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result with the
3127 /// specified rounding mode. The first [`Float`] is taken by value and the second and third by
3128 /// reference. An [`Ordering`] is also returned, indicating whether the rounded sum is less
3129 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
3130 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3131 ///
3132 /// The precision of the output is the maximum of the precisions of the inputs. See
3133 /// [`RoundingMode`] for a description of the possible rounding modes.
3134 ///
3135 /// $$
3136 /// f(x,y,z,m) = x+yz+\varepsilon.
3137 /// $$
3138 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3139 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3140 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3141 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3142 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3143 ///
3144 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3145 ///
3146 /// Special cases:
3147 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
3148 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
3149 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
3150 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
3151 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
3152 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
3153 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
3154 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
3155 /// - $f(0.0,y,z,m)=0.0$ if $yz=0.0$
3156 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=-0.0$
3157 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
3158 /// not `Floor`
3159 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
3160 /// `Floor`
3161 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
3162 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
3163 ///
3164 /// Overflow and underflow:
3165 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3166 /// returned instead.
3167 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
3168 /// is returned instead, where `p` is the precision of the output.
3169 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3170 /// returned instead.
3171 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3172 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3173 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3174 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3175 /// instead.
3176 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3177 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
3178 /// instead.
3179 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3180 /// instead.
3181 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3182 /// instead.
3183 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3184 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3185 /// returned instead.
3186 ///
3187 /// If you want to specify an output precision, consider using [`Float::add_mul_prec_round`]
3188 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3189 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
3190 ///
3191 /// # Worst-case complexity
3192 /// $T(n, m) = O(n \log n \log\log n + m)$
3193 ///
3194 /// $M(n, m) = O(n \log n + m)$
3195 ///
3196 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3197 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3198 ///
3199 /// # Panics
3200 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3201 /// represent the output.
3202 ///
3203 /// # Examples
3204 /// ```
3205 /// use core::f64::consts::{E, PI, SQRT_2};
3206 /// use malachite_base::rounding_modes::RoundingMode::*;
3207 /// use malachite_float::Float;
3208 /// use std::cmp::Ordering::*;
3209 ///
3210 /// let x = Float::from(PI);
3211 /// let y = Float::from(E);
3212 /// let z = Float::from(SQRT_2);
3213 ///
3214 /// let (sum, o) = x.clone().add_mul_round_val_ref_ref(&y, &z, Floor);
3215 /// assert_eq!(sum.to_string(), "6.9858236817489097");
3216 /// assert_eq!(o, Less);
3217 ///
3218 /// let (sum, o) = x.clone().add_mul_round_val_ref_ref(&y, &z, Ceiling);
3219 /// assert_eq!(sum.to_string(), "6.9858236817489106");
3220 /// assert_eq!(o, Greater);
3221 ///
3222 /// let (sum, o) = x.clone().add_mul_round_val_ref_ref(&y, &z, Nearest);
3223 /// assert_eq!(sum.to_string(), "6.9858236817489097");
3224 /// assert_eq!(o, Less);
3225 /// ```
3226 #[inline]
3227 pub fn add_mul_round_val_ref_ref(
3228 self,
3229 y: &Self,
3230 z: &Self,
3231 rm: RoundingMode,
3232 ) -> (Self, Ordering) {
3233 let prec = max!(
3234 self.significant_bits(),
3235 y.significant_bits(),
3236 z.significant_bits()
3237 );
3238 self.add_mul_prec_round_val_ref_ref(y, z, prec, rm)
3239 }
3240
3241 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result with the
3242 /// specified rounding mode. The first [`Float`] is taken by reference and the second and third
3243 /// by value. An [`Ordering`] is also returned, indicating whether the rounded sum is less than,
3244 /// equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
3245 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3246 ///
3247 /// The precision of the output is the maximum of the precisions of the inputs. See
3248 /// [`RoundingMode`] for a description of the possible rounding modes.
3249 ///
3250 /// $$
3251 /// f(x,y,z,m) = x+yz+\varepsilon.
3252 /// $$
3253 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3254 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3255 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3256 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3257 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3258 ///
3259 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3260 ///
3261 /// Special cases:
3262 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
3263 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
3264 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
3265 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
3266 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
3267 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
3268 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
3269 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
3270 /// - $f(0.0,y,z,m)=0.0$ if $yz=0.0$
3271 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=-0.0$
3272 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
3273 /// not `Floor`
3274 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
3275 /// `Floor`
3276 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
3277 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
3278 ///
3279 /// Overflow and underflow:
3280 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3281 /// returned instead.
3282 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
3283 /// is returned instead, where `p` is the precision of the output.
3284 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3285 /// returned instead.
3286 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3287 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3288 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3289 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3290 /// instead.
3291 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3292 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
3293 /// instead.
3294 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3295 /// instead.
3296 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3297 /// instead.
3298 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3299 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3300 /// returned instead.
3301 ///
3302 /// If you want to specify an output precision, consider using [`Float::add_mul_prec_round`]
3303 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3304 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
3305 ///
3306 /// # Worst-case complexity
3307 /// $T(n, m) = O(n \log n \log\log n + m)$
3308 ///
3309 /// $M(n, m) = O(n \log n + m)$
3310 ///
3311 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3312 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3313 ///
3314 /// # Panics
3315 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3316 /// represent the output.
3317 ///
3318 /// # Examples
3319 /// ```
3320 /// use core::f64::consts::{E, PI, SQRT_2};
3321 /// use malachite_base::rounding_modes::RoundingMode::*;
3322 /// use malachite_float::Float;
3323 /// use std::cmp::Ordering::*;
3324 ///
3325 /// let x = Float::from(PI);
3326 /// let y = Float::from(E);
3327 /// let z = Float::from(SQRT_2);
3328 ///
3329 /// let (sum, o) = x.add_mul_round_ref_val_val(y.clone(), z.clone(), Floor);
3330 /// assert_eq!(sum.to_string(), "6.9858236817489097");
3331 /// assert_eq!(o, Less);
3332 ///
3333 /// let (sum, o) = x.add_mul_round_ref_val_val(y.clone(), z.clone(), Ceiling);
3334 /// assert_eq!(sum.to_string(), "6.9858236817489106");
3335 /// assert_eq!(o, Greater);
3336 ///
3337 /// let (sum, o) = x.add_mul_round_ref_val_val(y.clone(), z.clone(), Nearest);
3338 /// assert_eq!(sum.to_string(), "6.9858236817489097");
3339 /// assert_eq!(o, Less);
3340 /// ```
3341 #[allow(clippy::needless_pass_by_value)]
3342 #[inline]
3343 pub fn add_mul_round_ref_val_val(
3344 &self,
3345 y: Self,
3346 z: Self,
3347 rm: RoundingMode,
3348 ) -> (Self, Ordering) {
3349 let prec = max!(
3350 self.significant_bits(),
3351 y.significant_bits(),
3352 z.significant_bits()
3353 );
3354 self.add_mul_prec_round_ref_val_val(y, z, prec, rm)
3355 }
3356
3357 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result with the
3358 /// specified rounding mode. The first and third [`Float`]s are taken by reference and the
3359 /// second by value. An [`Ordering`] is also returned, indicating whether the rounded sum is
3360 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
3361 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3362 ///
3363 /// The precision of the output is the maximum of the precisions of the inputs. See
3364 /// [`RoundingMode`] for a description of the possible rounding modes.
3365 ///
3366 /// $$
3367 /// f(x,y,z,m) = x+yz+\varepsilon.
3368 /// $$
3369 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3370 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3371 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3372 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3373 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3374 ///
3375 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3376 ///
3377 /// Special cases:
3378 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
3379 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
3380 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
3381 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
3382 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
3383 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
3384 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
3385 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
3386 /// - $f(0.0,y,z,m)=0.0$ if $yz=0.0$
3387 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=-0.0$
3388 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
3389 /// not `Floor`
3390 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
3391 /// `Floor`
3392 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
3393 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
3394 ///
3395 /// Overflow and underflow:
3396 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3397 /// returned instead.
3398 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
3399 /// is returned instead, where `p` is the precision of the output.
3400 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3401 /// returned instead.
3402 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3403 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3404 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3405 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3406 /// instead.
3407 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3408 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
3409 /// instead.
3410 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3411 /// instead.
3412 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3413 /// instead.
3414 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3415 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3416 /// returned instead.
3417 ///
3418 /// If you want to specify an output precision, consider using [`Float::add_mul_prec_round`]
3419 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3420 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
3421 ///
3422 /// # Worst-case complexity
3423 /// $T(n, m) = O(n \log n \log\log n + m)$
3424 ///
3425 /// $M(n, m) = O(n \log n + m)$
3426 ///
3427 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3428 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3429 ///
3430 /// # Panics
3431 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3432 /// represent the output.
3433 ///
3434 /// # Examples
3435 /// ```
3436 /// use core::f64::consts::{E, PI, SQRT_2};
3437 /// use malachite_base::rounding_modes::RoundingMode::*;
3438 /// use malachite_float::Float;
3439 /// use std::cmp::Ordering::*;
3440 ///
3441 /// let x = Float::from(PI);
3442 /// let y = Float::from(E);
3443 /// let z = Float::from(SQRT_2);
3444 ///
3445 /// let (sum, o) = x.add_mul_round_ref_val_ref(y.clone(), &z, Floor);
3446 /// assert_eq!(sum.to_string(), "6.9858236817489097");
3447 /// assert_eq!(o, Less);
3448 ///
3449 /// let (sum, o) = x.add_mul_round_ref_val_ref(y.clone(), &z, Ceiling);
3450 /// assert_eq!(sum.to_string(), "6.9858236817489106");
3451 /// assert_eq!(o, Greater);
3452 ///
3453 /// let (sum, o) = x.add_mul_round_ref_val_ref(y.clone(), &z, Nearest);
3454 /// assert_eq!(sum.to_string(), "6.9858236817489097");
3455 /// assert_eq!(o, Less);
3456 /// ```
3457 #[allow(clippy::needless_pass_by_value)]
3458 #[inline]
3459 pub fn add_mul_round_ref_val_ref(
3460 &self,
3461 y: Self,
3462 z: &Self,
3463 rm: RoundingMode,
3464 ) -> (Self, Ordering) {
3465 let prec = max!(
3466 self.significant_bits(),
3467 y.significant_bits(),
3468 z.significant_bits()
3469 );
3470 self.add_mul_prec_round_ref_val_ref(y, z, prec, rm)
3471 }
3472
3473 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result with the
3474 /// specified rounding mode. The first two [`Float`]s are taken by reference and the third by
3475 /// value. An [`Ordering`] is also returned, indicating whether the rounded sum is less than,
3476 /// equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
3477 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3478 ///
3479 /// The precision of the output is the maximum of the precisions of the inputs. See
3480 /// [`RoundingMode`] for a description of the possible rounding modes.
3481 ///
3482 /// $$
3483 /// f(x,y,z,m) = x+yz+\varepsilon.
3484 /// $$
3485 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3486 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3487 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3488 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3489 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3490 ///
3491 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3492 ///
3493 /// Special cases:
3494 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
3495 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
3496 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
3497 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
3498 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
3499 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
3500 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
3501 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
3502 /// - $f(0.0,y,z,m)=0.0$ if $yz=0.0$
3503 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=-0.0$
3504 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
3505 /// not `Floor`
3506 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
3507 /// `Floor`
3508 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
3509 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
3510 ///
3511 /// Overflow and underflow:
3512 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3513 /// returned instead.
3514 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
3515 /// is returned instead, where `p` is the precision of the output.
3516 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3517 /// returned instead.
3518 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3519 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3520 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3521 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3522 /// instead.
3523 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3524 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
3525 /// instead.
3526 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3527 /// instead.
3528 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3529 /// instead.
3530 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3531 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3532 /// returned instead.
3533 ///
3534 /// If you want to specify an output precision, consider using [`Float::add_mul_prec_round`]
3535 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3536 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
3537 ///
3538 /// # Worst-case complexity
3539 /// $T(n, m) = O(n \log n \log\log n + m)$
3540 ///
3541 /// $M(n, m) = O(n \log n + m)$
3542 ///
3543 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3544 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3545 ///
3546 /// # Panics
3547 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3548 /// represent the output.
3549 ///
3550 /// # Examples
3551 /// ```
3552 /// use core::f64::consts::{E, PI, SQRT_2};
3553 /// use malachite_base::rounding_modes::RoundingMode::*;
3554 /// use malachite_float::Float;
3555 /// use std::cmp::Ordering::*;
3556 ///
3557 /// let x = Float::from(PI);
3558 /// let y = Float::from(E);
3559 /// let z = Float::from(SQRT_2);
3560 ///
3561 /// let (sum, o) = x.add_mul_round_ref_ref_val(&y, z.clone(), Floor);
3562 /// assert_eq!(sum.to_string(), "6.9858236817489097");
3563 /// assert_eq!(o, Less);
3564 ///
3565 /// let (sum, o) = x.add_mul_round_ref_ref_val(&y, z.clone(), Ceiling);
3566 /// assert_eq!(sum.to_string(), "6.9858236817489106");
3567 /// assert_eq!(o, Greater);
3568 ///
3569 /// let (sum, o) = x.add_mul_round_ref_ref_val(&y, z.clone(), Nearest);
3570 /// assert_eq!(sum.to_string(), "6.9858236817489097");
3571 /// assert_eq!(o, Less);
3572 /// ```
3573 #[allow(clippy::needless_pass_by_value)]
3574 #[inline]
3575 pub fn add_mul_round_ref_ref_val(
3576 &self,
3577 y: &Self,
3578 z: Self,
3579 rm: RoundingMode,
3580 ) -> (Self, Ordering) {
3581 let prec = max!(
3582 self.significant_bits(),
3583 y.significant_bits(),
3584 z.significant_bits()
3585 );
3586 self.add_mul_prec_round_ref_ref_val(y, z, prec, rm)
3587 }
3588
3589 /// Adds a [`Float`] and the product of two other [`Float`]s, rounding the result with the
3590 /// specified rounding mode. All three [`Float`]s are taken by reference. An [`Ordering`] is
3591 /// also returned, indicating whether the rounded sum is less than, equal to, or greater than
3592 /// the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
3593 /// returns a `NaN` it also returns `Equal`.
3594 ///
3595 /// The precision of the output is the maximum of the precisions of the inputs. See
3596 /// [`RoundingMode`] for a description of the possible rounding modes.
3597 ///
3598 /// $$
3599 /// f(x,y,z,m) = x+yz+\varepsilon.
3600 /// $$
3601 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3602 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3603 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3604 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3605 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3606 ///
3607 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3608 ///
3609 /// Special cases:
3610 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
3611 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
3612 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
3613 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
3614 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
3615 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
3616 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
3617 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
3618 /// - $f(0.0,y,z,m)=0.0$ if $yz=0.0$
3619 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=-0.0$
3620 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
3621 /// not `Floor`
3622 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of different signs and $m$ is
3623 /// `Floor`
3624 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
3625 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
3626 ///
3627 /// Overflow and underflow:
3628 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3629 /// returned instead.
3630 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
3631 /// is returned instead, where `p` is the precision of the output.
3632 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3633 /// returned instead.
3634 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3635 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3636 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3637 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3638 /// instead.
3639 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3640 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
3641 /// instead.
3642 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3643 /// instead.
3644 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3645 /// instead.
3646 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3647 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3648 /// returned instead.
3649 ///
3650 /// If you want to specify an output precision, consider using [`Float::add_mul_prec_round`]
3651 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3652 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
3653 ///
3654 /// # Worst-case complexity
3655 /// $T(n, m) = O(n \log n \log\log n + m)$
3656 ///
3657 /// $M(n, m) = O(n \log n + m)$
3658 ///
3659 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3660 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3661 ///
3662 /// # Panics
3663 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3664 /// represent the output.
3665 ///
3666 /// # Examples
3667 /// ```
3668 /// use core::f64::consts::{E, PI, SQRT_2};
3669 /// use malachite_base::rounding_modes::RoundingMode::*;
3670 /// use malachite_float::Float;
3671 /// use std::cmp::Ordering::*;
3672 ///
3673 /// let x = Float::from(PI);
3674 /// let y = Float::from(E);
3675 /// let z = Float::from(SQRT_2);
3676 ///
3677 /// let (sum, o) = x.add_mul_round_ref_ref_ref(&y, &z, Floor);
3678 /// assert_eq!(sum.to_string(), "6.9858236817489097");
3679 /// assert_eq!(o, Less);
3680 ///
3681 /// let (sum, o) = x.add_mul_round_ref_ref_ref(&y, &z, Ceiling);
3682 /// assert_eq!(sum.to_string(), "6.9858236817489106");
3683 /// assert_eq!(o, Greater);
3684 ///
3685 /// let (sum, o) = x.add_mul_round_ref_ref_ref(&y, &z, Nearest);
3686 /// assert_eq!(sum.to_string(), "6.9858236817489097");
3687 /// assert_eq!(o, Less);
3688 /// ```
3689 #[inline]
3690 pub fn add_mul_round_ref_ref_ref(
3691 &self,
3692 y: &Self,
3693 z: &Self,
3694 rm: RoundingMode,
3695 ) -> (Self, Ordering) {
3696 let prec = max!(
3697 self.significant_bits(),
3698 y.significant_bits(),
3699 z.significant_bits()
3700 );
3701 self.add_mul_prec_round_ref_ref_ref(y, z, prec, rm)
3702 }
3703
3704 /// Adds the product of two [`Float`]s to a [`Float`] in place, rounding the result with the
3705 /// specified rounding mode. Both [`Float`]s on the right-hand side are taken by value. An
3706 /// [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
3707 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
3708 /// this function assigns a `NaN` it also returns `Equal`.
3709 ///
3710 /// The precision of the output is the maximum of the precisions of the inputs. See
3711 /// [`RoundingMode`] for a description of the possible rounding modes.
3712 ///
3713 /// $$
3714 /// x \gets x+yz+\varepsilon.
3715 /// $$
3716 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3717 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3718 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3719 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3720 ///
3721 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
3722 /// overflow, and underflow.
3723 ///
3724 /// If you want to specify an output precision, consider using
3725 /// [`Float::add_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
3726 /// rounding mode, consider using
3727 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
3728 /// instead.
3729 ///
3730 /// # Worst-case complexity
3731 /// $T(n, m) = O(n \log n \log\log n + m)$
3732 ///
3733 /// $M(n, m) = O(n \log n + m)$
3734 ///
3735 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3736 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3737 ///
3738 /// # Panics
3739 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3740 /// represent the output.
3741 ///
3742 /// # Examples
3743 /// ```
3744 /// use core::f64::consts::{E, PI, SQRT_2};
3745 /// use malachite_base::rounding_modes::RoundingMode::*;
3746 /// use malachite_float::Float;
3747 /// use std::cmp::Ordering::*;
3748 ///
3749 /// let y = Float::from(E);
3750 /// let z = Float::from(SQRT_2);
3751 ///
3752 /// let mut x = Float::from(PI);
3753 /// assert_eq!(x.add_mul_round_assign(y.clone(), z.clone(), Floor), Less);
3754 /// assert_eq!(x.to_string(), "6.9858236817489097");
3755 ///
3756 /// let mut x = Float::from(PI);
3757 /// assert_eq!(
3758 /// x.add_mul_round_assign(y.clone(), z.clone(), Ceiling),
3759 /// Greater
3760 /// );
3761 /// assert_eq!(x.to_string(), "6.9858236817489106");
3762 ///
3763 /// let mut x = Float::from(PI);
3764 /// assert_eq!(x.add_mul_round_assign(y.clone(), z.clone(), Nearest), Less);
3765 /// assert_eq!(x.to_string(), "6.9858236817489097");
3766 /// ```
3767 #[allow(clippy::needless_pass_by_value)]
3768 #[inline]
3769 pub fn add_mul_round_assign(&mut self, y: Self, z: Self, rm: RoundingMode) -> Ordering {
3770 let prec = max!(
3771 self.significant_bits(),
3772 y.significant_bits(),
3773 z.significant_bits()
3774 );
3775 self.add_mul_prec_round_assign(y, z, prec, rm)
3776 }
3777
3778 /// Adds the product of two [`Float`]s to a [`Float`] in place, rounding the result with the
3779 /// specified rounding mode. The first [`Float`] on the right-hand side is taken by value and
3780 /// the second by reference. An [`Ordering`] is returned, indicating whether the rounded sum is
3781 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
3782 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
3783 ///
3784 /// The precision of the output is the maximum of the precisions of the inputs. See
3785 /// [`RoundingMode`] for a description of the possible rounding modes.
3786 ///
3787 /// $$
3788 /// x \gets x+yz+\varepsilon.
3789 /// $$
3790 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3791 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3792 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3793 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3794 ///
3795 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
3796 /// overflow, and underflow.
3797 ///
3798 /// If you want to specify an output precision, consider using
3799 /// [`Float::add_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
3800 /// rounding mode, consider using
3801 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
3802 /// instead.
3803 ///
3804 /// # Worst-case complexity
3805 /// $T(n, m) = O(n \log n \log\log n + m)$
3806 ///
3807 /// $M(n, m) = O(n \log n + m)$
3808 ///
3809 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3810 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3811 ///
3812 /// # Panics
3813 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3814 /// represent the output.
3815 ///
3816 /// # Examples
3817 /// ```
3818 /// use core::f64::consts::{E, PI, SQRT_2};
3819 /// use malachite_base::rounding_modes::RoundingMode::*;
3820 /// use malachite_float::Float;
3821 /// use std::cmp::Ordering::*;
3822 ///
3823 /// let y = Float::from(E);
3824 /// let z = Float::from(SQRT_2);
3825 ///
3826 /// let mut x = Float::from(PI);
3827 /// assert_eq!(x.add_mul_round_assign_val_ref(y.clone(), &z, Floor), Less);
3828 /// assert_eq!(x.to_string(), "6.9858236817489097");
3829 ///
3830 /// let mut x = Float::from(PI);
3831 /// assert_eq!(
3832 /// x.add_mul_round_assign_val_ref(y.clone(), &z, Ceiling),
3833 /// Greater
3834 /// );
3835 /// assert_eq!(x.to_string(), "6.9858236817489106");
3836 ///
3837 /// let mut x = Float::from(PI);
3838 /// assert_eq!(x.add_mul_round_assign_val_ref(y.clone(), &z, Nearest), Less);
3839 /// assert_eq!(x.to_string(), "6.9858236817489097");
3840 /// ```
3841 #[allow(clippy::needless_pass_by_value)]
3842 #[inline]
3843 pub fn add_mul_round_assign_val_ref(
3844 &mut self,
3845 y: Self,
3846 z: &Self,
3847 rm: RoundingMode,
3848 ) -> Ordering {
3849 let prec = max!(
3850 self.significant_bits(),
3851 y.significant_bits(),
3852 z.significant_bits()
3853 );
3854 self.add_mul_prec_round_assign_val_ref(y, z, prec, rm)
3855 }
3856
3857 /// Adds the product of two [`Float`]s to a [`Float`] in place, rounding the result with the
3858 /// specified rounding mode. The first [`Float`] on the right-hand side is taken by reference
3859 /// and the second by value. An [`Ordering`] is returned, indicating whether the rounded sum is
3860 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
3861 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
3862 ///
3863 /// The precision of the output is the maximum of the precisions of the inputs. See
3864 /// [`RoundingMode`] for a description of the possible rounding modes.
3865 ///
3866 /// $$
3867 /// x \gets x+yz+\varepsilon.
3868 /// $$
3869 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3870 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3871 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3872 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3873 ///
3874 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
3875 /// overflow, and underflow.
3876 ///
3877 /// If you want to specify an output precision, consider using
3878 /// [`Float::add_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
3879 /// rounding mode, consider using
3880 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
3881 /// instead.
3882 ///
3883 /// # Worst-case complexity
3884 /// $T(n, m) = O(n \log n \log\log n + m)$
3885 ///
3886 /// $M(n, m) = O(n \log n + m)$
3887 ///
3888 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3889 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3890 ///
3891 /// # Panics
3892 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3893 /// represent the output.
3894 ///
3895 /// # Examples
3896 /// ```
3897 /// use core::f64::consts::{E, PI, SQRT_2};
3898 /// use malachite_base::rounding_modes::RoundingMode::*;
3899 /// use malachite_float::Float;
3900 /// use std::cmp::Ordering::*;
3901 ///
3902 /// let y = Float::from(E);
3903 /// let z = Float::from(SQRT_2);
3904 ///
3905 /// let mut x = Float::from(PI);
3906 /// assert_eq!(x.add_mul_round_assign_ref_val(&y, z.clone(), Floor), Less);
3907 /// assert_eq!(x.to_string(), "6.9858236817489097");
3908 ///
3909 /// let mut x = Float::from(PI);
3910 /// assert_eq!(
3911 /// x.add_mul_round_assign_ref_val(&y, z.clone(), Ceiling),
3912 /// Greater
3913 /// );
3914 /// assert_eq!(x.to_string(), "6.9858236817489106");
3915 ///
3916 /// let mut x = Float::from(PI);
3917 /// assert_eq!(x.add_mul_round_assign_ref_val(&y, z.clone(), Nearest), Less);
3918 /// assert_eq!(x.to_string(), "6.9858236817489097");
3919 /// ```
3920 #[allow(clippy::needless_pass_by_value)]
3921 #[inline]
3922 pub fn add_mul_round_assign_ref_val(
3923 &mut self,
3924 y: &Self,
3925 z: Self,
3926 rm: RoundingMode,
3927 ) -> Ordering {
3928 let prec = max!(
3929 self.significant_bits(),
3930 y.significant_bits(),
3931 z.significant_bits()
3932 );
3933 self.add_mul_prec_round_assign_ref_val(y, z, prec, rm)
3934 }
3935
3936 /// Adds the product of two [`Float`]s to a [`Float`] in place, rounding the result with the
3937 /// specified rounding mode. Both [`Float`]s on the right-hand side are taken by reference. An
3938 /// [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
3939 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
3940 /// this function assigns a `NaN` it also returns `Equal`.
3941 ///
3942 /// The precision of the output is the maximum of the precisions of the inputs. See
3943 /// [`RoundingMode`] for a description of the possible rounding modes.
3944 ///
3945 /// $$
3946 /// x \gets x+yz+\varepsilon.
3947 /// $$
3948 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3949 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3950 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3951 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3952 ///
3953 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
3954 /// overflow, and underflow.
3955 ///
3956 /// If you want to specify an output precision, consider using
3957 /// [`Float::add_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
3958 /// rounding mode, consider using
3959 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
3960 /// instead.
3961 ///
3962 /// # Worst-case complexity
3963 /// $T(n, m) = O(n \log n \log\log n + m)$
3964 ///
3965 /// $M(n, m) = O(n \log n + m)$
3966 ///
3967 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3968 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3969 ///
3970 /// # Panics
3971 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3972 /// represent the output.
3973 ///
3974 /// # Examples
3975 /// ```
3976 /// use core::f64::consts::{E, PI, SQRT_2};
3977 /// use malachite_base::rounding_modes::RoundingMode::*;
3978 /// use malachite_float::Float;
3979 /// use std::cmp::Ordering::*;
3980 ///
3981 /// let y = Float::from(E);
3982 /// let z = Float::from(SQRT_2);
3983 ///
3984 /// let mut x = Float::from(PI);
3985 /// assert_eq!(x.add_mul_round_assign_ref_ref(&y, &z, Floor), Less);
3986 /// assert_eq!(x.to_string(), "6.9858236817489097");
3987 ///
3988 /// let mut x = Float::from(PI);
3989 /// assert_eq!(x.add_mul_round_assign_ref_ref(&y, &z, Ceiling), Greater);
3990 /// assert_eq!(x.to_string(), "6.9858236817489106");
3991 ///
3992 /// let mut x = Float::from(PI);
3993 /// assert_eq!(x.add_mul_round_assign_ref_ref(&y, &z, Nearest), Less);
3994 /// assert_eq!(x.to_string(), "6.9858236817489097");
3995 /// ```
3996 #[inline]
3997 pub fn add_mul_round_assign_ref_ref(
3998 &mut self,
3999 y: &Self,
4000 z: &Self,
4001 rm: RoundingMode,
4002 ) -> Ordering {
4003 let prec = max!(
4004 self.significant_bits(),
4005 y.significant_bits(),
4006 z.significant_bits()
4007 );
4008 self.add_mul_prec_round_assign_ref_ref(y, z, prec, rm)
4009 }
4010}
4011
4012impl AddMul<Self, Self> for Float {
4013 type Output = Self;
4014 /// Adds a [`Float`] and the product of two other [`Float`]s, taking all three by value.
4015 ///
4016 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
4017 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
4018 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4019 /// rounding mode.
4020 ///
4021 /// $$
4022 /// f(x,y,z) = x+yz+\varepsilon.
4023 /// $$
4024 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4025 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4026 ///
4027 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4028 ///
4029 /// Special cases:
4030 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
4031 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
4032 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
4033 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
4034 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
4035 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
4036 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
4037 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
4038 /// - $f(0.0,y,z)=0.0$ if $yz=0.0$
4039 /// - $f(-0.0,y,z)=-0.0$ if $yz=-0.0$
4040 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of different signs
4041 /// - $f(x,y,z)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
4042 ///
4043 /// Overflow and underflow:
4044 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
4045 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
4046 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
4047 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
4048 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
4049 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
4050 ///
4051 /// If you want to use a rounding mode other than `Nearest`, consider using
4052 /// [`Float::add_mul_round`]. If you want to specify the output precision, consider using
4053 /// [`Float::add_mul_prec`]. If you want both of these things, consider using
4054 /// [`Float::add_mul_prec_round`].
4055 ///
4056 /// # Worst-case complexity
4057 /// $T(n, m) = O(n \log n \log\log n + m)$
4058 ///
4059 /// $M(n, m) = O(n \log n + m)$
4060 ///
4061 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4062 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4063 ///
4064 /// # Examples
4065 /// ```
4066 /// use core::f64::consts::{E, PI, SQRT_2};
4067 /// use malachite_base::num::arithmetic::traits::AddMul;
4068 /// use malachite_float::Float;
4069 ///
4070 /// let x = Float::from(PI);
4071 /// let y = Float::from(E);
4072 /// let z = Float::from(SQRT_2);
4073 /// assert_eq!(x.add_mul(y, z).to_string(), "6.9858236817489097");
4074 /// ```
4075 #[inline]
4076 fn add_mul(self, y: Self, z: Self) -> Self {
4077 let prec = max!(
4078 self.significant_bits(),
4079 y.significant_bits(),
4080 z.significant_bits()
4081 );
4082 self.add_mul_prec(y, z, prec).0
4083 }
4084}
4085
4086impl AddMul<Self, &Self> for Float {
4087 type Output = Self;
4088 /// Adds a [`Float`] and the product of two other [`Float`]s, taking the first two by value and
4089 /// the third by reference.
4090 ///
4091 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
4092 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
4093 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4094 /// rounding mode.
4095 ///
4096 /// $$
4097 /// f(x,y,z) = x+yz+\varepsilon.
4098 /// $$
4099 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4100 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4101 ///
4102 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4103 ///
4104 /// Special cases:
4105 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
4106 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
4107 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
4108 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
4109 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
4110 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
4111 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
4112 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
4113 /// - $f(0.0,y,z)=0.0$ if $yz=0.0$
4114 /// - $f(-0.0,y,z)=-0.0$ if $yz=-0.0$
4115 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of different signs
4116 /// - $f(x,y,z)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
4117 ///
4118 /// Overflow and underflow:
4119 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
4120 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
4121 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
4122 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
4123 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
4124 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
4125 ///
4126 /// If you want to use a rounding mode other than `Nearest`, consider using
4127 /// [`Float::add_mul_round`]. If you want to specify the output precision, consider using
4128 /// [`Float::add_mul_prec`]. If you want both of these things, consider using
4129 /// [`Float::add_mul_prec_round`].
4130 ///
4131 /// # Worst-case complexity
4132 /// $T(n, m) = O(n \log n \log\log n + m)$
4133 ///
4134 /// $M(n, m) = O(n \log n + m)$
4135 ///
4136 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4137 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4138 ///
4139 /// # Examples
4140 /// ```
4141 /// use core::f64::consts::{E, PI, SQRT_2};
4142 /// use malachite_base::num::arithmetic::traits::AddMul;
4143 /// use malachite_float::Float;
4144 ///
4145 /// let x = Float::from(PI);
4146 /// let y = Float::from(E);
4147 /// let z = Float::from(SQRT_2);
4148 /// assert_eq!(x.add_mul(y, &z).to_string(), "6.9858236817489097");
4149 /// ```
4150 #[inline]
4151 fn add_mul(self, y: Self, z: &Self) -> Self {
4152 let prec = max!(
4153 self.significant_bits(),
4154 y.significant_bits(),
4155 z.significant_bits()
4156 );
4157 self.add_mul_prec_val_val_ref(y, z, prec).0
4158 }
4159}
4160
4161impl AddMul<&Self, Self> for Float {
4162 type Output = Self;
4163 /// Adds a [`Float`] and the product of two other [`Float`]s, taking the first and third by
4164 /// value and the second by reference.
4165 ///
4166 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
4167 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
4168 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4169 /// rounding mode.
4170 ///
4171 /// $$
4172 /// f(x,y,z) = x+yz+\varepsilon.
4173 /// $$
4174 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4175 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4176 ///
4177 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4178 ///
4179 /// Special cases:
4180 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
4181 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
4182 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
4183 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
4184 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
4185 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
4186 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
4187 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
4188 /// - $f(0.0,y,z)=0.0$ if $yz=0.0$
4189 /// - $f(-0.0,y,z)=-0.0$ if $yz=-0.0$
4190 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of different signs
4191 /// - $f(x,y,z)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
4192 ///
4193 /// Overflow and underflow:
4194 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
4195 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
4196 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
4197 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
4198 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
4199 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
4200 ///
4201 /// If you want to use a rounding mode other than `Nearest`, consider using
4202 /// [`Float::add_mul_round`]. If you want to specify the output precision, consider using
4203 /// [`Float::add_mul_prec`]. If you want both of these things, consider using
4204 /// [`Float::add_mul_prec_round`].
4205 ///
4206 /// # Worst-case complexity
4207 /// $T(n, m) = O(n \log n \log\log n + m)$
4208 ///
4209 /// $M(n, m) = O(n \log n + m)$
4210 ///
4211 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4212 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4213 ///
4214 /// # Examples
4215 /// ```
4216 /// use core::f64::consts::{E, PI, SQRT_2};
4217 /// use malachite_base::num::arithmetic::traits::AddMul;
4218 /// use malachite_float::Float;
4219 ///
4220 /// let x = Float::from(PI);
4221 /// let y = Float::from(E);
4222 /// let z = Float::from(SQRT_2);
4223 /// assert_eq!(x.add_mul(&y, z).to_string(), "6.9858236817489097");
4224 /// ```
4225 #[inline]
4226 fn add_mul(self, y: &Self, z: Self) -> Self {
4227 let prec = max!(
4228 self.significant_bits(),
4229 y.significant_bits(),
4230 z.significant_bits()
4231 );
4232 self.add_mul_prec_val_ref_val(y, z, prec).0
4233 }
4234}
4235
4236impl AddMul<&Self, &Self> for Float {
4237 type Output = Self;
4238 /// Adds a [`Float`] and the product of two other [`Float`]s, taking the first by value and the
4239 /// second and third by reference.
4240 ///
4241 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
4242 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
4243 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4244 /// rounding mode.
4245 ///
4246 /// $$
4247 /// f(x,y,z) = x+yz+\varepsilon.
4248 /// $$
4249 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4250 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4251 ///
4252 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4253 ///
4254 /// Special cases:
4255 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
4256 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
4257 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
4258 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
4259 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
4260 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
4261 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
4262 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
4263 /// - $f(0.0,y,z)=0.0$ if $yz=0.0$
4264 /// - $f(-0.0,y,z)=-0.0$ if $yz=-0.0$
4265 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of different signs
4266 /// - $f(x,y,z)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
4267 ///
4268 /// Overflow and underflow:
4269 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
4270 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
4271 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
4272 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
4273 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
4274 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
4275 ///
4276 /// If you want to use a rounding mode other than `Nearest`, consider using
4277 /// [`Float::add_mul_round`]. If you want to specify the output precision, consider using
4278 /// [`Float::add_mul_prec`]. If you want both of these things, consider using
4279 /// [`Float::add_mul_prec_round`].
4280 ///
4281 /// # Worst-case complexity
4282 /// $T(n, m) = O(n \log n \log\log n + m)$
4283 ///
4284 /// $M(n, m) = O(n \log n + m)$
4285 ///
4286 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4287 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4288 ///
4289 /// # Examples
4290 /// ```
4291 /// use core::f64::consts::{E, PI, SQRT_2};
4292 /// use malachite_base::num::arithmetic::traits::AddMul;
4293 /// use malachite_float::Float;
4294 ///
4295 /// let x = Float::from(PI);
4296 /// let y = Float::from(E);
4297 /// let z = Float::from(SQRT_2);
4298 /// assert_eq!(x.add_mul(&y, &z).to_string(), "6.9858236817489097");
4299 /// ```
4300 #[inline]
4301 fn add_mul(self, y: &Self, z: &Self) -> Self {
4302 let prec = max!(
4303 self.significant_bits(),
4304 y.significant_bits(),
4305 z.significant_bits()
4306 );
4307 self.add_mul_prec_val_ref_ref(y, z, prec).0
4308 }
4309}
4310
4311impl AddMul<Float, Float> for &Float {
4312 type Output = Float;
4313 /// Adds a [`Float`] and the product of two other [`Float`]s, taking the first by reference and
4314 /// the second and third by value.
4315 ///
4316 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
4317 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
4318 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4319 /// rounding mode.
4320 ///
4321 /// $$
4322 /// f(x,y,z) = x+yz+\varepsilon.
4323 /// $$
4324 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4325 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4326 ///
4327 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4328 ///
4329 /// Special cases:
4330 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
4331 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
4332 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
4333 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
4334 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
4335 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
4336 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
4337 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
4338 /// - $f(0.0,y,z)=0.0$ if $yz=0.0$
4339 /// - $f(-0.0,y,z)=-0.0$ if $yz=-0.0$
4340 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of different signs
4341 /// - $f(x,y,z)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
4342 ///
4343 /// Overflow and underflow:
4344 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
4345 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
4346 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
4347 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
4348 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
4349 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
4350 ///
4351 /// If you want to use a rounding mode other than `Nearest`, consider using
4352 /// [`Float::add_mul_round`]. If you want to specify the output precision, consider using
4353 /// [`Float::add_mul_prec`]. If you want both of these things, consider using
4354 /// [`Float::add_mul_prec_round`].
4355 ///
4356 /// # Worst-case complexity
4357 /// $T(n, m) = O(n \log n \log\log n + m)$
4358 ///
4359 /// $M(n, m) = O(n \log n + m)$
4360 ///
4361 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4362 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4363 ///
4364 /// # Examples
4365 /// ```
4366 /// use core::f64::consts::{E, PI, SQRT_2};
4367 /// use malachite_base::num::arithmetic::traits::AddMul;
4368 /// use malachite_float::Float;
4369 ///
4370 /// let x = Float::from(PI);
4371 /// let y = Float::from(E);
4372 /// let z = Float::from(SQRT_2);
4373 /// assert_eq!(&x.add_mul(y, z).to_string(), "6.9858236817489097");
4374 /// ```
4375 #[inline]
4376 fn add_mul(self, y: Float, z: Float) -> Float {
4377 let prec = max!(
4378 self.significant_bits(),
4379 y.significant_bits(),
4380 z.significant_bits()
4381 );
4382 self.add_mul_prec_ref_val_val(y, z, prec).0
4383 }
4384}
4385
4386impl AddMul<Float, &Float> for &Float {
4387 type Output = Float;
4388 /// Adds a [`Float`] and the product of two other [`Float`]s, taking the first and third by
4389 /// reference and the second by value.
4390 ///
4391 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
4392 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
4393 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4394 /// rounding mode.
4395 ///
4396 /// $$
4397 /// f(x,y,z) = x+yz+\varepsilon.
4398 /// $$
4399 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4400 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4401 ///
4402 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4403 ///
4404 /// Special cases:
4405 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
4406 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
4407 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
4408 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
4409 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
4410 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
4411 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
4412 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
4413 /// - $f(0.0,y,z)=0.0$ if $yz=0.0$
4414 /// - $f(-0.0,y,z)=-0.0$ if $yz=-0.0$
4415 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of different signs
4416 /// - $f(x,y,z)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
4417 ///
4418 /// Overflow and underflow:
4419 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
4420 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
4421 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
4422 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
4423 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
4424 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
4425 ///
4426 /// If you want to use a rounding mode other than `Nearest`, consider using
4427 /// [`Float::add_mul_round`]. If you want to specify the output precision, consider using
4428 /// [`Float::add_mul_prec`]. If you want both of these things, consider using
4429 /// [`Float::add_mul_prec_round`].
4430 ///
4431 /// # Worst-case complexity
4432 /// $T(n, m) = O(n \log n \log\log n + m)$
4433 ///
4434 /// $M(n, m) = O(n \log n + m)$
4435 ///
4436 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4437 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4438 ///
4439 /// # Examples
4440 /// ```
4441 /// use core::f64::consts::{E, PI, SQRT_2};
4442 /// use malachite_base::num::arithmetic::traits::AddMul;
4443 /// use malachite_float::Float;
4444 ///
4445 /// let x = Float::from(PI);
4446 /// let y = Float::from(E);
4447 /// let z = Float::from(SQRT_2);
4448 /// assert_eq!(&x.add_mul(y, &z).to_string(), "6.9858236817489097");
4449 /// ```
4450 #[inline]
4451 fn add_mul(self, y: Float, z: &Float) -> Float {
4452 let prec = max!(
4453 self.significant_bits(),
4454 y.significant_bits(),
4455 z.significant_bits()
4456 );
4457 self.add_mul_prec_ref_val_ref(y, z, prec).0
4458 }
4459}
4460
4461impl AddMul<&Float, Float> for &Float {
4462 type Output = Float;
4463 /// Adds a [`Float`] and the product of two other [`Float`]s, taking the first two by reference
4464 /// and the third by value.
4465 ///
4466 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
4467 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
4468 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4469 /// rounding mode.
4470 ///
4471 /// $$
4472 /// f(x,y,z) = x+yz+\varepsilon.
4473 /// $$
4474 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4475 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4476 ///
4477 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4478 ///
4479 /// Special cases:
4480 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
4481 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
4482 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
4483 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
4484 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
4485 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
4486 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
4487 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
4488 /// - $f(0.0,y,z)=0.0$ if $yz=0.0$
4489 /// - $f(-0.0,y,z)=-0.0$ if $yz=-0.0$
4490 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of different signs
4491 /// - $f(x,y,z)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
4492 ///
4493 /// Overflow and underflow:
4494 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
4495 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
4496 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
4497 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
4498 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
4499 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
4500 ///
4501 /// If you want to use a rounding mode other than `Nearest`, consider using
4502 /// [`Float::add_mul_round`]. If you want to specify the output precision, consider using
4503 /// [`Float::add_mul_prec`]. If you want both of these things, consider using
4504 /// [`Float::add_mul_prec_round`].
4505 ///
4506 /// # Worst-case complexity
4507 /// $T(n, m) = O(n \log n \log\log n + m)$
4508 ///
4509 /// $M(n, m) = O(n \log n + m)$
4510 ///
4511 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4512 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4513 ///
4514 /// # Examples
4515 /// ```
4516 /// use core::f64::consts::{E, PI, SQRT_2};
4517 /// use malachite_base::num::arithmetic::traits::AddMul;
4518 /// use malachite_float::Float;
4519 ///
4520 /// let x = Float::from(PI);
4521 /// let y = Float::from(E);
4522 /// let z = Float::from(SQRT_2);
4523 /// assert_eq!(&x.add_mul(&y, z).to_string(), "6.9858236817489097");
4524 /// ```
4525 #[inline]
4526 fn add_mul(self, y: &Float, z: Float) -> Float {
4527 let prec = max!(
4528 self.significant_bits(),
4529 y.significant_bits(),
4530 z.significant_bits()
4531 );
4532 self.add_mul_prec_ref_ref_val(y, z, prec).0
4533 }
4534}
4535
4536impl AddMul<&Float, &Float> for &Float {
4537 type Output = Float;
4538 /// Adds a [`Float`] and the product of two other [`Float`]s, taking all three by reference.
4539 ///
4540 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
4541 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
4542 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4543 /// rounding mode.
4544 ///
4545 /// $$
4546 /// f(x,y,z) = x+yz+\varepsilon.
4547 /// $$
4548 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4549 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4550 ///
4551 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4552 ///
4553 /// Special cases:
4554 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
4555 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
4556 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
4557 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
4558 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
4559 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
4560 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
4561 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
4562 /// - $f(0.0,y,z)=0.0$ if $yz=0.0$
4563 /// - $f(-0.0,y,z)=-0.0$ if $yz=-0.0$
4564 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of different signs
4565 /// - $f(x,y,z)=0.0$ if $x=-yz$, $x$ is finite and nonzero,
4566 ///
4567 /// Overflow and underflow:
4568 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
4569 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
4570 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
4571 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
4572 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
4573 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
4574 ///
4575 /// If you want to use a rounding mode other than `Nearest`, consider using
4576 /// [`Float::add_mul_round`]. If you want to specify the output precision, consider using
4577 /// [`Float::add_mul_prec`]. If you want both of these things, consider using
4578 /// [`Float::add_mul_prec_round`].
4579 ///
4580 /// # Worst-case complexity
4581 /// $T(n, m) = O(n \log n \log\log n + m)$
4582 ///
4583 /// $M(n, m) = O(n \log n + m)$
4584 ///
4585 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4586 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4587 ///
4588 /// # Examples
4589 /// ```
4590 /// use core::f64::consts::{E, PI, SQRT_2};
4591 /// use malachite_base::num::arithmetic::traits::AddMul;
4592 /// use malachite_float::Float;
4593 ///
4594 /// let x = Float::from(PI);
4595 /// let y = Float::from(E);
4596 /// let z = Float::from(SQRT_2);
4597 /// assert_eq!(&x.add_mul(&y, &z).to_string(), "6.9858236817489097");
4598 /// ```
4599 #[inline]
4600 fn add_mul(self, y: &Float, z: &Float) -> Float {
4601 let prec = max!(
4602 self.significant_bits(),
4603 y.significant_bits(),
4604 z.significant_bits()
4605 );
4606 self.add_mul_prec_ref_ref_ref(y, z, prec).0
4607 }
4608}
4609
4610impl AddMulAssign<Self, Self> for Float {
4611 /// Adds the product of two [`Float`]s to a [`Float`] in place, both [`Float`]s on the
4612 /// right-hand side being taken by value.
4613 ///
4614 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
4615 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
4616 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4617 /// rounding mode.
4618 ///
4619 /// $$
4620 /// x \gets x+yz+\varepsilon.
4621 /// $$
4622 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4623 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4624 ///
4625 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
4626 /// overflow, and underflow.
4627 ///
4628 /// If you want to use a rounding mode other than `Nearest`, consider using
4629 /// [`Float::add_mul_round_assign`]. If you want to specify the output precision, consider using
4630 /// [`Float::add_mul_prec_assign`]. If you want both of these things, consider using
4631 /// [`Float::add_mul_prec_round_assign`].
4632 ///
4633 /// # Worst-case complexity
4634 /// $T(n, m) = O(n \log n \log\log n + m)$
4635 ///
4636 /// $M(n, m) = O(n \log n + m)$
4637 ///
4638 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4639 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4640 ///
4641 /// # Examples
4642 /// ```
4643 /// use core::f64::consts::{E, PI, SQRT_2};
4644 /// use malachite_base::num::arithmetic::traits::AddMulAssign;
4645 /// use malachite_float::Float;
4646 ///
4647 /// let mut x = Float::from(PI);
4648 /// let y = Float::from(E);
4649 /// let z = Float::from(SQRT_2);
4650 /// x.add_mul_assign(y, z);
4651 /// assert_eq!(x.to_string(), "6.9858236817489097");
4652 /// ```
4653 #[inline]
4654 fn add_mul_assign(&mut self, y: Self, z: Self) {
4655 let prec = max!(
4656 self.significant_bits(),
4657 y.significant_bits(),
4658 z.significant_bits()
4659 );
4660 self.add_mul_prec_assign(y, z, prec);
4661 }
4662}
4663
4664impl AddMulAssign<Self, &Self> for Float {
4665 /// Adds the product of two [`Float`]s to a [`Float`] in place, the first [`Float`] on the
4666 /// right-hand side being taken by value and the second by reference.
4667 ///
4668 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
4669 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
4670 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4671 /// rounding mode.
4672 ///
4673 /// $$
4674 /// x \gets x+yz+\varepsilon.
4675 /// $$
4676 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4677 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4678 ///
4679 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
4680 /// overflow, and underflow.
4681 ///
4682 /// If you want to use a rounding mode other than `Nearest`, consider using
4683 /// [`Float::add_mul_round_assign`]. If you want to specify the output precision, consider using
4684 /// [`Float::add_mul_prec_assign`]. If you want both of these things, consider using
4685 /// [`Float::add_mul_prec_round_assign`].
4686 ///
4687 /// # Worst-case complexity
4688 /// $T(n, m) = O(n \log n \log\log n + m)$
4689 ///
4690 /// $M(n, m) = O(n \log n + m)$
4691 ///
4692 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4693 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4694 ///
4695 /// # Examples
4696 /// ```
4697 /// use core::f64::consts::{E, PI, SQRT_2};
4698 /// use malachite_base::num::arithmetic::traits::AddMulAssign;
4699 /// use malachite_float::Float;
4700 ///
4701 /// let mut x = Float::from(PI);
4702 /// let y = Float::from(E);
4703 /// let z = Float::from(SQRT_2);
4704 /// x.add_mul_assign(y, &z);
4705 /// assert_eq!(x.to_string(), "6.9858236817489097");
4706 /// ```
4707 #[inline]
4708 fn add_mul_assign(&mut self, y: Self, z: &Self) {
4709 let prec = max!(
4710 self.significant_bits(),
4711 y.significant_bits(),
4712 z.significant_bits()
4713 );
4714 self.add_mul_prec_assign_val_ref(y, z, prec);
4715 }
4716}
4717
4718impl AddMulAssign<&Self, Self> for Float {
4719 /// Adds the product of two [`Float`]s to a [`Float`] in place, the first [`Float`] on the
4720 /// right-hand side being taken by reference and the second by value.
4721 ///
4722 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
4723 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
4724 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4725 /// rounding mode.
4726 ///
4727 /// $$
4728 /// x \gets x+yz+\varepsilon.
4729 /// $$
4730 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4731 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4732 ///
4733 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
4734 /// overflow, and underflow.
4735 ///
4736 /// If you want to use a rounding mode other than `Nearest`, consider using
4737 /// [`Float::add_mul_round_assign`]. If you want to specify the output precision, consider using
4738 /// [`Float::add_mul_prec_assign`]. If you want both of these things, consider using
4739 /// [`Float::add_mul_prec_round_assign`].
4740 ///
4741 /// # Worst-case complexity
4742 /// $T(n, m) = O(n \log n \log\log n + m)$
4743 ///
4744 /// $M(n, m) = O(n \log n + m)$
4745 ///
4746 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4747 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4748 ///
4749 /// # Examples
4750 /// ```
4751 /// use core::f64::consts::{E, PI, SQRT_2};
4752 /// use malachite_base::num::arithmetic::traits::AddMulAssign;
4753 /// use malachite_float::Float;
4754 ///
4755 /// let mut x = Float::from(PI);
4756 /// let y = Float::from(E);
4757 /// let z = Float::from(SQRT_2);
4758 /// x.add_mul_assign(&y, z);
4759 /// assert_eq!(x.to_string(), "6.9858236817489097");
4760 /// ```
4761 #[inline]
4762 fn add_mul_assign(&mut self, y: &Self, z: Self) {
4763 let prec = max!(
4764 self.significant_bits(),
4765 y.significant_bits(),
4766 z.significant_bits()
4767 );
4768 self.add_mul_prec_assign_ref_val(y, z, prec);
4769 }
4770}
4771
4772impl AddMulAssign<&Self, &Self> for Float {
4773 /// Adds the product of two [`Float`]s to a [`Float`] in place, both [`Float`]s on the
4774 /// right-hand side being taken by reference.
4775 ///
4776 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
4777 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
4778 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4779 /// rounding mode.
4780 ///
4781 /// $$
4782 /// x \gets x+yz+\varepsilon.
4783 /// $$
4784 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4785 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4786 ///
4787 /// See the [`Float::add_mul_prec_round`] documentation for information on special cases,
4788 /// overflow, and underflow.
4789 ///
4790 /// If you want to use a rounding mode other than `Nearest`, consider using
4791 /// [`Float::add_mul_round_assign`]. If you want to specify the output precision, consider using
4792 /// [`Float::add_mul_prec_assign`]. If you want both of these things, consider using
4793 /// [`Float::add_mul_prec_round_assign`].
4794 ///
4795 /// # Worst-case complexity
4796 /// $T(n, m) = O(n \log n \log\log n + m)$
4797 ///
4798 /// $M(n, m) = O(n \log n + m)$
4799 ///
4800 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4801 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4802 ///
4803 /// # Examples
4804 /// ```
4805 /// use core::f64::consts::{E, PI, SQRT_2};
4806 /// use malachite_base::num::arithmetic::traits::AddMulAssign;
4807 /// use malachite_float::Float;
4808 ///
4809 /// let mut x = Float::from(PI);
4810 /// let y = Float::from(E);
4811 /// let z = Float::from(SQRT_2);
4812 /// x.add_mul_assign(&y, &z);
4813 /// assert_eq!(x.to_string(), "6.9858236817489097");
4814 /// ```
4815 #[inline]
4816 fn add_mul_assign(&mut self, y: &Self, z: &Self) {
4817 let prec = max!(
4818 self.significant_bits(),
4819 y.significant_bits(),
4820 z.significant_bits()
4821 );
4822 self.add_mul_prec_assign_ref_ref(y, z, prec);
4823 }
4824}
4825
4826impl Float {
4827 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
4828 /// result to the specified precision and with the specified rounding mode. The [`Float`]s and
4829 /// the [`Rational`] are all taken by value. An [`Ordering`] is also returned, indicating
4830 /// whether the rounded sum is less than, equal to, or greater than the exact sum. Although
4831 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
4832 /// returns `Equal`.
4833 ///
4834 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
4835 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
4836 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
4837 ///
4838 /// See [`RoundingMode`] for a description of the possible rounding modes.
4839 ///
4840 /// $$
4841 /// f(x,y,z,p,m) = x+yz+\varepsilon.
4842 /// $$
4843 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4844 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4845 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
4846 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4847 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
4848 ///
4849 /// If the output has a precision, it is `prec`.
4850 ///
4851 /// Special cases:
4852 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
4853 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
4854 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
4855 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
4856 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
4857 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
4858 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
4859 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
4860 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
4861 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
4862 /// [`Rational`] counting as positive.
4863 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
4864 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
4865 ///
4866 /// Overflow and underflow:
4867 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4868 /// returned instead.
4869 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
4870 /// is returned instead, where `p` is the precision of the output.
4871 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4872 /// returned instead.
4873 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4874 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4875 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4876 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4877 /// instead.
4878 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4879 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4880 /// returned instead.
4881 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4882 /// instead.
4883 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4884 /// instead.
4885 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4886 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4887 /// returned instead.
4888 ///
4889 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_rational_prec`]
4890 /// instead. If you know that your target precision is the maximum of the precisions of the
4891 /// inputs, consider using [`Float::add_mul_rational_round`] instead. If both of these things
4892 /// are true, consider using
4893 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
4894 ///
4895 /// # Worst-case complexity
4896 /// $T(n, m) = O(n \log n \log\log n + m)$
4897 ///
4898 /// $M(n, m) = O(n \log n + m)$
4899 ///
4900 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4901 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
4902 /// prec)`.
4903 ///
4904 /// # Panics
4905 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
4906 /// representable with `prec` bits.
4907 ///
4908 /// # Examples
4909 /// ```
4910 /// use core::f64::consts::{E, PI};
4911 /// use malachite_base::rounding_modes::RoundingMode::*;
4912 /// use malachite_float::Float;
4913 /// use malachite_q::Rational;
4914 /// use std::cmp::Ordering::*;
4915 ///
4916 /// let x = Float::from(PI);
4917 /// let y = Float::from(E);
4918 /// let z = Rational::from_signeds(1, 3);
4919 ///
4920 /// let (sum, o) = x
4921 /// .clone()
4922 /// .add_mul_rational_prec_round(y.clone(), z.clone(), 5, Floor);
4923 /// assert_eq!(sum.to_string(), "4.00");
4924 /// assert_eq!(o, Less);
4925 ///
4926 /// let (sum, o) = x
4927 /// .clone()
4928 /// .add_mul_rational_prec_round(y.clone(), z.clone(), 5, Ceiling);
4929 /// assert_eq!(sum.to_string(), "4.25");
4930 /// assert_eq!(o, Greater);
4931 ///
4932 /// let (sum, o) = x
4933 /// .clone()
4934 /// .add_mul_rational_prec_round(y.clone(), z.clone(), 5, Nearest);
4935 /// assert_eq!(sum.to_string(), "4.00");
4936 /// assert_eq!(o, Less);
4937 ///
4938 /// let (sum, o) = x
4939 /// .clone()
4940 /// .add_mul_rational_prec_round(y.clone(), z.clone(), 20, Floor);
4941 /// assert_eq!(sum.to_string(), "4.0476837");
4942 /// assert_eq!(o, Less);
4943 ///
4944 /// let (sum, o) = x
4945 /// .clone()
4946 /// .add_mul_rational_prec_round(y.clone(), z.clone(), 20, Ceiling);
4947 /// assert_eq!(sum.to_string(), "4.0476913");
4948 /// assert_eq!(o, Greater);
4949 ///
4950 /// let (sum, o) = x
4951 /// .clone()
4952 /// .add_mul_rational_prec_round(y.clone(), z.clone(), 20, Nearest);
4953 /// assert_eq!(sum.to_string(), "4.0476837");
4954 /// assert_eq!(o, Less);
4955 /// ```
4956 #[allow(clippy::needless_pass_by_value)]
4957 #[inline]
4958 pub fn add_mul_rational_prec_round(
4959 self,
4960 y: Self,
4961 z: Rational,
4962 prec: u64,
4963 rm: RoundingMode,
4964 ) -> (Self, Ordering) {
4965 add_mul_rational_helper(&self, &y, &z, false, prec, rm)
4966 }
4967
4968 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
4969 /// result to the specified precision and with the specified rounding mode. The [`Float`]s are
4970 /// taken by value and the [`Rational`] by reference. An [`Ordering`] is also returned,
4971 /// indicating whether the rounded sum is less than, equal to, or greater than the exact sum.
4972 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
4973 /// it also returns `Equal`.
4974 ///
4975 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
4976 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
4977 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
4978 ///
4979 /// See [`RoundingMode`] for a description of the possible rounding modes.
4980 ///
4981 /// $$
4982 /// f(x,y,z,p,m) = x+yz+\varepsilon.
4983 /// $$
4984 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4985 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4986 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
4987 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4988 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
4989 ///
4990 /// If the output has a precision, it is `prec`.
4991 ///
4992 /// Special cases:
4993 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
4994 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
4995 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
4996 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
4997 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
4998 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
4999 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
5000 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
5001 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
5002 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
5003 /// [`Rational`] counting as positive.
5004 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
5005 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
5006 ///
5007 /// Overflow and underflow:
5008 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5009 /// returned instead.
5010 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
5011 /// is returned instead, where `p` is the precision of the output.
5012 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5013 /// returned instead.
5014 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5015 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5016 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
5017 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5018 /// instead.
5019 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5020 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5021 /// returned instead.
5022 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5023 /// instead.
5024 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5025 /// instead.
5026 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
5027 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5028 /// returned instead.
5029 ///
5030 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_rational_prec`]
5031 /// instead. If you know that your target precision is the maximum of the precisions of the
5032 /// inputs, consider using [`Float::add_mul_rational_round`] instead. If both of these things
5033 /// are true, consider using
5034 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
5035 ///
5036 /// # Worst-case complexity
5037 /// $T(n, m) = O(n \log n \log\log n + m)$
5038 ///
5039 /// $M(n, m) = O(n \log n + m)$
5040 ///
5041 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5042 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5043 /// prec)`.
5044 ///
5045 /// # Panics
5046 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
5047 /// representable with `prec` bits.
5048 ///
5049 /// # Examples
5050 /// ```
5051 /// use core::f64::consts::{E, PI};
5052 /// use malachite_base::rounding_modes::RoundingMode::*;
5053 /// use malachite_float::Float;
5054 /// use malachite_q::Rational;
5055 /// use std::cmp::Ordering::*;
5056 ///
5057 /// let x = Float::from(PI);
5058 /// let y = Float::from(E);
5059 /// let z = Rational::from_signeds(1, 3);
5060 ///
5061 /// let (sum, o) = x
5062 /// .clone()
5063 /// .add_mul_rational_prec_round_val_val_ref(y.clone(), &z, 5, Floor);
5064 /// assert_eq!(sum.to_string(), "4.00");
5065 /// assert_eq!(o, Less);
5066 ///
5067 /// let (sum, o) = x
5068 /// .clone()
5069 /// .add_mul_rational_prec_round_val_val_ref(y.clone(), &z, 5, Ceiling);
5070 /// assert_eq!(sum.to_string(), "4.25");
5071 /// assert_eq!(o, Greater);
5072 ///
5073 /// let (sum, o) = x
5074 /// .clone()
5075 /// .add_mul_rational_prec_round_val_val_ref(y.clone(), &z, 5, Nearest);
5076 /// assert_eq!(sum.to_string(), "4.00");
5077 /// assert_eq!(o, Less);
5078 ///
5079 /// let (sum, o) = x
5080 /// .clone()
5081 /// .add_mul_rational_prec_round_val_val_ref(y.clone(), &z, 20, Floor);
5082 /// assert_eq!(sum.to_string(), "4.0476837");
5083 /// assert_eq!(o, Less);
5084 ///
5085 /// let (sum, o) =
5086 /// x.clone()
5087 /// .add_mul_rational_prec_round_val_val_ref(y.clone(), &z, 20, Ceiling);
5088 /// assert_eq!(sum.to_string(), "4.0476913");
5089 /// assert_eq!(o, Greater);
5090 ///
5091 /// let (sum, o) =
5092 /// x.clone()
5093 /// .add_mul_rational_prec_round_val_val_ref(y.clone(), &z, 20, Nearest);
5094 /// assert_eq!(sum.to_string(), "4.0476837");
5095 /// assert_eq!(o, Less);
5096 /// ```
5097 #[allow(clippy::needless_pass_by_value)]
5098 #[inline]
5099 pub fn add_mul_rational_prec_round_val_val_ref(
5100 self,
5101 y: Self,
5102 z: &Rational,
5103 prec: u64,
5104 rm: RoundingMode,
5105 ) -> (Self, Ordering) {
5106 add_mul_rational_helper(&self, &y, z, false, prec, rm)
5107 }
5108
5109 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
5110 /// result to the specified precision and with the specified rounding mode. The first [`Float`]
5111 /// and the [`Rational`] are taken by value and the second [`Float`] by reference. An
5112 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
5113 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
5114 /// this function returns a `NaN` it also returns `Equal`.
5115 ///
5116 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5117 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
5118 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5119 ///
5120 /// See [`RoundingMode`] for a description of the possible rounding modes.
5121 ///
5122 /// $$
5123 /// f(x,y,z,p,m) = x+yz+\varepsilon.
5124 /// $$
5125 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5126 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5127 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
5128 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5129 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
5130 ///
5131 /// If the output has a precision, it is `prec`.
5132 ///
5133 /// Special cases:
5134 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
5135 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
5136 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
5137 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
5138 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
5139 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
5140 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
5141 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
5142 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
5143 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
5144 /// [`Rational`] counting as positive.
5145 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
5146 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
5147 ///
5148 /// Overflow and underflow:
5149 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5150 /// returned instead.
5151 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
5152 /// is returned instead, where `p` is the precision of the output.
5153 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5154 /// returned instead.
5155 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5156 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5157 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
5158 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5159 /// instead.
5160 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5161 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5162 /// returned instead.
5163 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5164 /// instead.
5165 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5166 /// instead.
5167 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
5168 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5169 /// returned instead.
5170 ///
5171 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_rational_prec`]
5172 /// instead. If you know that your target precision is the maximum of the precisions of the
5173 /// inputs, consider using [`Float::add_mul_rational_round`] instead. If both of these things
5174 /// are true, consider using
5175 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
5176 ///
5177 /// # Worst-case complexity
5178 /// $T(n, m) = O(n \log n \log\log n + m)$
5179 ///
5180 /// $M(n, m) = O(n \log n + m)$
5181 ///
5182 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5183 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5184 /// prec)`.
5185 ///
5186 /// # Panics
5187 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
5188 /// representable with `prec` bits.
5189 ///
5190 /// # Examples
5191 /// ```
5192 /// use core::f64::consts::{E, PI};
5193 /// use malachite_base::rounding_modes::RoundingMode::*;
5194 /// use malachite_float::Float;
5195 /// use malachite_q::Rational;
5196 /// use std::cmp::Ordering::*;
5197 ///
5198 /// let x = Float::from(PI);
5199 /// let y = Float::from(E);
5200 /// let z = Rational::from_signeds(1, 3);
5201 ///
5202 /// let (sum, o) = x
5203 /// .clone()
5204 /// .add_mul_rational_prec_round_val_ref_val(&y, z.clone(), 5, Floor);
5205 /// assert_eq!(sum.to_string(), "4.00");
5206 /// assert_eq!(o, Less);
5207 ///
5208 /// let (sum, o) = x
5209 /// .clone()
5210 /// .add_mul_rational_prec_round_val_ref_val(&y, z.clone(), 5, Ceiling);
5211 /// assert_eq!(sum.to_string(), "4.25");
5212 /// assert_eq!(o, Greater);
5213 ///
5214 /// let (sum, o) = x
5215 /// .clone()
5216 /// .add_mul_rational_prec_round_val_ref_val(&y, z.clone(), 5, Nearest);
5217 /// assert_eq!(sum.to_string(), "4.00");
5218 /// assert_eq!(o, Less);
5219 ///
5220 /// let (sum, o) = x
5221 /// .clone()
5222 /// .add_mul_rational_prec_round_val_ref_val(&y, z.clone(), 20, Floor);
5223 /// assert_eq!(sum.to_string(), "4.0476837");
5224 /// assert_eq!(o, Less);
5225 ///
5226 /// let (sum, o) =
5227 /// x.clone()
5228 /// .add_mul_rational_prec_round_val_ref_val(&y, z.clone(), 20, Ceiling);
5229 /// assert_eq!(sum.to_string(), "4.0476913");
5230 /// assert_eq!(o, Greater);
5231 ///
5232 /// let (sum, o) =
5233 /// x.clone()
5234 /// .add_mul_rational_prec_round_val_ref_val(&y, z.clone(), 20, Nearest);
5235 /// assert_eq!(sum.to_string(), "4.0476837");
5236 /// assert_eq!(o, Less);
5237 /// ```
5238 #[allow(clippy::needless_pass_by_value)]
5239 #[inline]
5240 pub fn add_mul_rational_prec_round_val_ref_val(
5241 self,
5242 y: &Self,
5243 z: Rational,
5244 prec: u64,
5245 rm: RoundingMode,
5246 ) -> (Self, Ordering) {
5247 add_mul_rational_helper(&self, y, &z, false, prec, rm)
5248 }
5249
5250 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
5251 /// result to the specified precision and with the specified rounding mode. The first [`Float`]
5252 /// is taken by value and the second [`Float`] and the [`Rational`] by reference. An
5253 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
5254 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
5255 /// this function returns a `NaN` it also returns `Equal`.
5256 ///
5257 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5258 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
5259 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5260 ///
5261 /// See [`RoundingMode`] for a description of the possible rounding modes.
5262 ///
5263 /// $$
5264 /// f(x,y,z,p,m) = x+yz+\varepsilon.
5265 /// $$
5266 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5267 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5268 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
5269 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5270 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
5271 ///
5272 /// If the output has a precision, it is `prec`.
5273 ///
5274 /// Special cases:
5275 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
5276 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
5277 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
5278 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
5279 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
5280 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
5281 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
5282 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
5283 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
5284 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
5285 /// [`Rational`] counting as positive.
5286 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
5287 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
5288 ///
5289 /// Overflow and underflow:
5290 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5291 /// returned instead.
5292 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
5293 /// is returned instead, where `p` is the precision of the output.
5294 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5295 /// returned instead.
5296 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5297 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5298 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
5299 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5300 /// instead.
5301 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5302 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5303 /// returned instead.
5304 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5305 /// instead.
5306 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5307 /// instead.
5308 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
5309 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5310 /// returned instead.
5311 ///
5312 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_rational_prec`]
5313 /// instead. If you know that your target precision is the maximum of the precisions of the
5314 /// inputs, consider using [`Float::add_mul_rational_round`] instead. If both of these things
5315 /// are true, consider using
5316 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
5317 ///
5318 /// # Worst-case complexity
5319 /// $T(n, m) = O(n \log n \log\log n + m)$
5320 ///
5321 /// $M(n, m) = O(n \log n + m)$
5322 ///
5323 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5324 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5325 /// prec)`.
5326 ///
5327 /// # Panics
5328 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
5329 /// representable with `prec` bits.
5330 ///
5331 /// # Examples
5332 /// ```
5333 /// use core::f64::consts::{E, PI};
5334 /// use malachite_base::rounding_modes::RoundingMode::*;
5335 /// use malachite_float::Float;
5336 /// use malachite_q::Rational;
5337 /// use std::cmp::Ordering::*;
5338 ///
5339 /// let x = Float::from(PI);
5340 /// let y = Float::from(E);
5341 /// let z = Rational::from_signeds(1, 3);
5342 ///
5343 /// let (sum, o) = x
5344 /// .clone()
5345 /// .add_mul_rational_prec_round_val_ref_ref(&y, &z, 5, Floor);
5346 /// assert_eq!(sum.to_string(), "4.00");
5347 /// assert_eq!(o, Less);
5348 ///
5349 /// let (sum, o) = x
5350 /// .clone()
5351 /// .add_mul_rational_prec_round_val_ref_ref(&y, &z, 5, Ceiling);
5352 /// assert_eq!(sum.to_string(), "4.25");
5353 /// assert_eq!(o, Greater);
5354 ///
5355 /// let (sum, o) = x
5356 /// .clone()
5357 /// .add_mul_rational_prec_round_val_ref_ref(&y, &z, 5, Nearest);
5358 /// assert_eq!(sum.to_string(), "4.00");
5359 /// assert_eq!(o, Less);
5360 ///
5361 /// let (sum, o) = x
5362 /// .clone()
5363 /// .add_mul_rational_prec_round_val_ref_ref(&y, &z, 20, Floor);
5364 /// assert_eq!(sum.to_string(), "4.0476837");
5365 /// assert_eq!(o, Less);
5366 ///
5367 /// let (sum, o) = x
5368 /// .clone()
5369 /// .add_mul_rational_prec_round_val_ref_ref(&y, &z, 20, Ceiling);
5370 /// assert_eq!(sum.to_string(), "4.0476913");
5371 /// assert_eq!(o, Greater);
5372 ///
5373 /// let (sum, o) = x
5374 /// .clone()
5375 /// .add_mul_rational_prec_round_val_ref_ref(&y, &z, 20, Nearest);
5376 /// assert_eq!(sum.to_string(), "4.0476837");
5377 /// assert_eq!(o, Less);
5378 /// ```
5379 #[allow(clippy::needless_pass_by_value)]
5380 #[inline]
5381 pub fn add_mul_rational_prec_round_val_ref_ref(
5382 self,
5383 y: &Self,
5384 z: &Rational,
5385 prec: u64,
5386 rm: RoundingMode,
5387 ) -> (Self, Ordering) {
5388 add_mul_rational_helper(&self, y, z, false, prec, rm)
5389 }
5390
5391 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
5392 /// result to the specified precision and with the specified rounding mode. The first [`Float`]
5393 /// is taken by reference and the second [`Float`] and the [`Rational`] by value. An
5394 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
5395 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
5396 /// this function returns a `NaN` it also returns `Equal`.
5397 ///
5398 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5399 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
5400 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5401 ///
5402 /// See [`RoundingMode`] for a description of the possible rounding modes.
5403 ///
5404 /// $$
5405 /// f(x,y,z,p,m) = x+yz+\varepsilon.
5406 /// $$
5407 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5408 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5409 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
5410 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5411 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
5412 ///
5413 /// If the output has a precision, it is `prec`.
5414 ///
5415 /// Special cases:
5416 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
5417 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
5418 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
5419 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
5420 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
5421 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
5422 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
5423 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
5424 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
5425 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
5426 /// [`Rational`] counting as positive.
5427 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
5428 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
5429 ///
5430 /// Overflow and underflow:
5431 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5432 /// returned instead.
5433 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
5434 /// is returned instead, where `p` is the precision of the output.
5435 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5436 /// returned instead.
5437 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5438 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5439 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
5440 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5441 /// instead.
5442 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5443 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5444 /// returned instead.
5445 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5446 /// instead.
5447 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5448 /// instead.
5449 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
5450 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5451 /// returned instead.
5452 ///
5453 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_rational_prec`]
5454 /// instead. If you know that your target precision is the maximum of the precisions of the
5455 /// inputs, consider using [`Float::add_mul_rational_round`] instead. If both of these things
5456 /// are true, consider using
5457 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
5458 ///
5459 /// # Worst-case complexity
5460 /// $T(n, m) = O(n \log n \log\log n + m)$
5461 ///
5462 /// $M(n, m) = O(n \log n + m)$
5463 ///
5464 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5465 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5466 /// prec)`.
5467 ///
5468 /// # Panics
5469 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
5470 /// representable with `prec` bits.
5471 ///
5472 /// # Examples
5473 /// ```
5474 /// use core::f64::consts::{E, PI};
5475 /// use malachite_base::rounding_modes::RoundingMode::*;
5476 /// use malachite_float::Float;
5477 /// use malachite_q::Rational;
5478 /// use std::cmp::Ordering::*;
5479 ///
5480 /// let x = Float::from(PI);
5481 /// let y = Float::from(E);
5482 /// let z = Rational::from_signeds(1, 3);
5483 ///
5484 /// let (sum, o) = x.add_mul_rational_prec_round_ref_val_val(y.clone(), z.clone(), 5, Floor);
5485 /// assert_eq!(sum.to_string(), "4.00");
5486 /// assert_eq!(o, Less);
5487 ///
5488 /// let (sum, o) = x.add_mul_rational_prec_round_ref_val_val(y.clone(), z.clone(), 5, Ceiling);
5489 /// assert_eq!(sum.to_string(), "4.25");
5490 /// assert_eq!(o, Greater);
5491 ///
5492 /// let (sum, o) = x.add_mul_rational_prec_round_ref_val_val(y.clone(), z.clone(), 5, Nearest);
5493 /// assert_eq!(sum.to_string(), "4.00");
5494 /// assert_eq!(o, Less);
5495 ///
5496 /// let (sum, o) = x.add_mul_rational_prec_round_ref_val_val(y.clone(), z.clone(), 20, Floor);
5497 /// assert_eq!(sum.to_string(), "4.0476837");
5498 /// assert_eq!(o, Less);
5499 ///
5500 /// let (sum, o) = x.add_mul_rational_prec_round_ref_val_val(y.clone(), z.clone(), 20, Ceiling);
5501 /// assert_eq!(sum.to_string(), "4.0476913");
5502 /// assert_eq!(o, Greater);
5503 ///
5504 /// let (sum, o) = x.add_mul_rational_prec_round_ref_val_val(y.clone(), z.clone(), 20, Nearest);
5505 /// assert_eq!(sum.to_string(), "4.0476837");
5506 /// assert_eq!(o, Less);
5507 /// ```
5508 #[allow(clippy::needless_pass_by_value)]
5509 #[inline]
5510 pub fn add_mul_rational_prec_round_ref_val_val(
5511 &self,
5512 y: Self,
5513 z: Rational,
5514 prec: u64,
5515 rm: RoundingMode,
5516 ) -> (Self, Ordering) {
5517 add_mul_rational_helper(self, &y, &z, false, prec, rm)
5518 }
5519
5520 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
5521 /// result to the specified precision and with the specified rounding mode. The second [`Float`]
5522 /// is taken by value and the first [`Float`] and the [`Rational`] by reference. An [`Ordering`]
5523 /// is also returned, indicating whether the rounded sum is less than, equal to, or greater than
5524 /// the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
5525 /// returns a `NaN` it also returns `Equal`.
5526 ///
5527 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5528 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
5529 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5530 ///
5531 /// See [`RoundingMode`] for a description of the possible rounding modes.
5532 ///
5533 /// $$
5534 /// f(x,y,z,p,m) = x+yz+\varepsilon.
5535 /// $$
5536 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5537 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5538 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
5539 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5540 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
5541 ///
5542 /// If the output has a precision, it is `prec`.
5543 ///
5544 /// Special cases:
5545 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
5546 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
5547 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
5548 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
5549 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
5550 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
5551 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
5552 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
5553 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
5554 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
5555 /// [`Rational`] counting as positive.
5556 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
5557 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
5558 ///
5559 /// Overflow and underflow:
5560 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5561 /// returned instead.
5562 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
5563 /// is returned instead, where `p` is the precision of the output.
5564 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5565 /// returned instead.
5566 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5567 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5568 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
5569 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5570 /// instead.
5571 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5572 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5573 /// returned instead.
5574 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5575 /// instead.
5576 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5577 /// instead.
5578 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
5579 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5580 /// returned instead.
5581 ///
5582 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_rational_prec`]
5583 /// instead. If you know that your target precision is the maximum of the precisions of the
5584 /// inputs, consider using [`Float::add_mul_rational_round`] instead. If both of these things
5585 /// are true, consider using
5586 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
5587 ///
5588 /// # Worst-case complexity
5589 /// $T(n, m) = O(n \log n \log\log n + m)$
5590 ///
5591 /// $M(n, m) = O(n \log n + m)$
5592 ///
5593 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5594 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5595 /// prec)`.
5596 ///
5597 /// # Panics
5598 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
5599 /// representable with `prec` bits.
5600 ///
5601 /// # Examples
5602 /// ```
5603 /// use core::f64::consts::{E, PI};
5604 /// use malachite_base::rounding_modes::RoundingMode::*;
5605 /// use malachite_float::Float;
5606 /// use malachite_q::Rational;
5607 /// use std::cmp::Ordering::*;
5608 ///
5609 /// let x = Float::from(PI);
5610 /// let y = Float::from(E);
5611 /// let z = Rational::from_signeds(1, 3);
5612 ///
5613 /// let (sum, o) = x.add_mul_rational_prec_round_ref_val_ref(y.clone(), &z, 5, Floor);
5614 /// assert_eq!(sum.to_string(), "4.00");
5615 /// assert_eq!(o, Less);
5616 ///
5617 /// let (sum, o) = x.add_mul_rational_prec_round_ref_val_ref(y.clone(), &z, 5, Ceiling);
5618 /// assert_eq!(sum.to_string(), "4.25");
5619 /// assert_eq!(o, Greater);
5620 ///
5621 /// let (sum, o) = x.add_mul_rational_prec_round_ref_val_ref(y.clone(), &z, 5, Nearest);
5622 /// assert_eq!(sum.to_string(), "4.00");
5623 /// assert_eq!(o, Less);
5624 ///
5625 /// let (sum, o) = x.add_mul_rational_prec_round_ref_val_ref(y.clone(), &z, 20, Floor);
5626 /// assert_eq!(sum.to_string(), "4.0476837");
5627 /// assert_eq!(o, Less);
5628 ///
5629 /// let (sum, o) = x.add_mul_rational_prec_round_ref_val_ref(y.clone(), &z, 20, Ceiling);
5630 /// assert_eq!(sum.to_string(), "4.0476913");
5631 /// assert_eq!(o, Greater);
5632 ///
5633 /// let (sum, o) = x.add_mul_rational_prec_round_ref_val_ref(y.clone(), &z, 20, Nearest);
5634 /// assert_eq!(sum.to_string(), "4.0476837");
5635 /// assert_eq!(o, Less);
5636 /// ```
5637 #[allow(clippy::needless_pass_by_value)]
5638 #[inline]
5639 pub fn add_mul_rational_prec_round_ref_val_ref(
5640 &self,
5641 y: Self,
5642 z: &Rational,
5643 prec: u64,
5644 rm: RoundingMode,
5645 ) -> (Self, Ordering) {
5646 add_mul_rational_helper(self, &y, z, false, prec, rm)
5647 }
5648
5649 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
5650 /// result to the specified precision and with the specified rounding mode. The [`Float`]s are
5651 /// taken by reference and the [`Rational`] by value. An [`Ordering`] is also returned,
5652 /// indicating whether the rounded sum is less than, equal to, or greater than the exact sum.
5653 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
5654 /// it also returns `Equal`.
5655 ///
5656 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5657 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
5658 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5659 ///
5660 /// See [`RoundingMode`] for a description of the possible rounding modes.
5661 ///
5662 /// $$
5663 /// f(x,y,z,p,m) = x+yz+\varepsilon.
5664 /// $$
5665 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5666 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5667 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
5668 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5669 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
5670 ///
5671 /// If the output has a precision, it is `prec`.
5672 ///
5673 /// Special cases:
5674 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
5675 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
5676 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
5677 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
5678 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
5679 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
5680 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
5681 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
5682 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
5683 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
5684 /// [`Rational`] counting as positive.
5685 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
5686 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
5687 ///
5688 /// Overflow and underflow:
5689 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5690 /// returned instead.
5691 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
5692 /// is returned instead, where `p` is the precision of the output.
5693 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5694 /// returned instead.
5695 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5696 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5697 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
5698 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5699 /// instead.
5700 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5701 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5702 /// returned instead.
5703 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5704 /// instead.
5705 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5706 /// instead.
5707 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
5708 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5709 /// returned instead.
5710 ///
5711 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_rational_prec`]
5712 /// instead. If you know that your target precision is the maximum of the precisions of the
5713 /// inputs, consider using [`Float::add_mul_rational_round`] instead. If both of these things
5714 /// are true, consider using
5715 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
5716 ///
5717 /// # Worst-case complexity
5718 /// $T(n, m) = O(n \log n \log\log n + m)$
5719 ///
5720 /// $M(n, m) = O(n \log n + m)$
5721 ///
5722 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5723 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5724 /// prec)`.
5725 ///
5726 /// # Panics
5727 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
5728 /// representable with `prec` bits.
5729 ///
5730 /// # Examples
5731 /// ```
5732 /// use core::f64::consts::{E, PI};
5733 /// use malachite_base::rounding_modes::RoundingMode::*;
5734 /// use malachite_float::Float;
5735 /// use malachite_q::Rational;
5736 /// use std::cmp::Ordering::*;
5737 ///
5738 /// let x = Float::from(PI);
5739 /// let y = Float::from(E);
5740 /// let z = Rational::from_signeds(1, 3);
5741 ///
5742 /// let (sum, o) = x.add_mul_rational_prec_round_ref_ref_val(&y, z.clone(), 5, Floor);
5743 /// assert_eq!(sum.to_string(), "4.00");
5744 /// assert_eq!(o, Less);
5745 ///
5746 /// let (sum, o) = x.add_mul_rational_prec_round_ref_ref_val(&y, z.clone(), 5, Ceiling);
5747 /// assert_eq!(sum.to_string(), "4.25");
5748 /// assert_eq!(o, Greater);
5749 ///
5750 /// let (sum, o) = x.add_mul_rational_prec_round_ref_ref_val(&y, z.clone(), 5, Nearest);
5751 /// assert_eq!(sum.to_string(), "4.00");
5752 /// assert_eq!(o, Less);
5753 ///
5754 /// let (sum, o) = x.add_mul_rational_prec_round_ref_ref_val(&y, z.clone(), 20, Floor);
5755 /// assert_eq!(sum.to_string(), "4.0476837");
5756 /// assert_eq!(o, Less);
5757 ///
5758 /// let (sum, o) = x.add_mul_rational_prec_round_ref_ref_val(&y, z.clone(), 20, Ceiling);
5759 /// assert_eq!(sum.to_string(), "4.0476913");
5760 /// assert_eq!(o, Greater);
5761 ///
5762 /// let (sum, o) = x.add_mul_rational_prec_round_ref_ref_val(&y, z.clone(), 20, Nearest);
5763 /// assert_eq!(sum.to_string(), "4.0476837");
5764 /// assert_eq!(o, Less);
5765 /// ```
5766 #[allow(clippy::needless_pass_by_value)]
5767 #[inline]
5768 pub fn add_mul_rational_prec_round_ref_ref_val(
5769 &self,
5770 y: &Self,
5771 z: Rational,
5772 prec: u64,
5773 rm: RoundingMode,
5774 ) -> (Self, Ordering) {
5775 add_mul_rational_helper(self, y, &z, false, prec, rm)
5776 }
5777
5778 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
5779 /// result to the specified precision and with the specified rounding mode. The [`Float`]s and
5780 /// the [`Rational`] are all taken by reference. An [`Ordering`] is also returned, indicating
5781 /// whether the rounded sum is less than, equal to, or greater than the exact sum. Although
5782 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
5783 /// returns `Equal`.
5784 ///
5785 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5786 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
5787 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5788 ///
5789 /// See [`RoundingMode`] for a description of the possible rounding modes.
5790 ///
5791 /// $$
5792 /// f(x,y,z,p,m) = x+yz+\varepsilon.
5793 /// $$
5794 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5795 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5796 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
5797 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5798 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
5799 ///
5800 /// If the output has a precision, it is `prec`.
5801 ///
5802 /// Special cases:
5803 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
5804 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
5805 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
5806 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
5807 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
5808 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
5809 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=\infty$
5810 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=-\infty$
5811 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
5812 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
5813 /// [`Rational`] counting as positive.
5814 /// - $f(x,y,z,p,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
5815 /// - $f(x,y,z,p,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
5816 ///
5817 /// Overflow and underflow:
5818 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5819 /// returned instead.
5820 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
5821 /// is returned instead, where `p` is the precision of the output.
5822 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5823 /// returned instead.
5824 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5825 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5826 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
5827 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5828 /// instead.
5829 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5830 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5831 /// returned instead.
5832 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5833 /// instead.
5834 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5835 /// instead.
5836 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
5837 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5838 /// returned instead.
5839 ///
5840 /// If you know you'll be using `Nearest`, consider using [`Float::add_mul_rational_prec`]
5841 /// instead. If you know that your target precision is the maximum of the precisions of the
5842 /// inputs, consider using [`Float::add_mul_rational_round`] instead. If both of these things
5843 /// are true, consider using
5844 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
5845 ///
5846 /// # Worst-case complexity
5847 /// $T(n, m) = O(n \log n \log\log n + m)$
5848 ///
5849 /// $M(n, m) = O(n \log n + m)$
5850 ///
5851 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5852 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5853 /// prec)`.
5854 ///
5855 /// # Panics
5856 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
5857 /// representable with `prec` bits.
5858 ///
5859 /// # Examples
5860 /// ```
5861 /// use core::f64::consts::{E, PI};
5862 /// use malachite_base::rounding_modes::RoundingMode::*;
5863 /// use malachite_float::Float;
5864 /// use malachite_q::Rational;
5865 /// use std::cmp::Ordering::*;
5866 ///
5867 /// let x = Float::from(PI);
5868 /// let y = Float::from(E);
5869 /// let z = Rational::from_signeds(1, 3);
5870 ///
5871 /// let (sum, o) = x.add_mul_rational_prec_round_ref_ref_ref(&y, &z, 5, Floor);
5872 /// assert_eq!(sum.to_string(), "4.00");
5873 /// assert_eq!(o, Less);
5874 ///
5875 /// let (sum, o) = x.add_mul_rational_prec_round_ref_ref_ref(&y, &z, 5, Ceiling);
5876 /// assert_eq!(sum.to_string(), "4.25");
5877 /// assert_eq!(o, Greater);
5878 ///
5879 /// let (sum, o) = x.add_mul_rational_prec_round_ref_ref_ref(&y, &z, 5, Nearest);
5880 /// assert_eq!(sum.to_string(), "4.00");
5881 /// assert_eq!(o, Less);
5882 ///
5883 /// let (sum, o) = x.add_mul_rational_prec_round_ref_ref_ref(&y, &z, 20, Floor);
5884 /// assert_eq!(sum.to_string(), "4.0476837");
5885 /// assert_eq!(o, Less);
5886 ///
5887 /// let (sum, o) = x.add_mul_rational_prec_round_ref_ref_ref(&y, &z, 20, Ceiling);
5888 /// assert_eq!(sum.to_string(), "4.0476913");
5889 /// assert_eq!(o, Greater);
5890 ///
5891 /// let (sum, o) = x.add_mul_rational_prec_round_ref_ref_ref(&y, &z, 20, Nearest);
5892 /// assert_eq!(sum.to_string(), "4.0476837");
5893 /// assert_eq!(o, Less);
5894 /// ```
5895 #[inline]
5896 pub fn add_mul_rational_prec_round_ref_ref_ref(
5897 &self,
5898 y: &Self,
5899 z: &Rational,
5900 prec: u64,
5901 rm: RoundingMode,
5902 ) -> (Self, Ordering) {
5903 add_mul_rational_helper(self, y, z, false, prec, rm)
5904 }
5905
5906 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place, rounding the
5907 /// result to the specified precision and with the specified rounding mode. The [`Float`] and
5908 /// the [`Rational`] on the right-hand side are both taken by value. An [`Ordering`] is
5909 /// returned, indicating whether the rounded sum is less than, equal to, or greater than the
5910 /// exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
5911 /// assigns a `NaN` it also returns `Equal`.
5912 ///
5913 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5914 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
5915 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5916 ///
5917 /// See [`RoundingMode`] for a description of the possible rounding modes.
5918 ///
5919 /// $$
5920 /// x \gets x+yz+\varepsilon.
5921 /// $$
5922 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5923 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5924 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
5925 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5926 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
5927 ///
5928 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
5929 /// cases, overflow, and underflow.
5930 ///
5931 /// If you know you'll be using `Nearest`, consider using
5932 /// [`Float::add_mul_rational_prec_assign`] instead. If you know that your target precision is
5933 /// the maximum of the precisions of the inputs, consider using
5934 /// [`Float::add_mul_rational_round_assign`] instead. If both of these things are true, consider
5935 /// using
5936 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
5937 /// instead.
5938 ///
5939 /// # Worst-case complexity
5940 /// $T(n, m) = O(n \log n \log\log n + m)$
5941 ///
5942 /// $M(n, m) = O(n \log n + m)$
5943 ///
5944 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5945 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5946 /// prec)`.
5947 ///
5948 /// # Panics
5949 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
5950 /// representable with `prec` bits.
5951 ///
5952 /// # Examples
5953 /// ```
5954 /// use core::f64::consts::{E, PI};
5955 /// use malachite_base::rounding_modes::RoundingMode::*;
5956 /// use malachite_float::Float;
5957 /// use malachite_q::Rational;
5958 /// use std::cmp::Ordering::*;
5959 ///
5960 /// let y = Float::from(E);
5961 /// let z = Rational::from_signeds(1, 3);
5962 ///
5963 /// let mut x = Float::from(PI);
5964 /// assert_eq!(
5965 /// x.add_mul_rational_prec_round_assign(y.clone(), z.clone(), 5, Floor),
5966 /// Less
5967 /// );
5968 /// assert_eq!(x.to_string(), "4.00");
5969 ///
5970 /// let mut x = Float::from(PI);
5971 /// assert_eq!(
5972 /// x.add_mul_rational_prec_round_assign(y.clone(), z.clone(), 5, Ceiling),
5973 /// Greater
5974 /// );
5975 /// assert_eq!(x.to_string(), "4.25");
5976 ///
5977 /// let mut x = Float::from(PI);
5978 /// assert_eq!(
5979 /// x.add_mul_rational_prec_round_assign(y.clone(), z.clone(), 5, Nearest),
5980 /// Less
5981 /// );
5982 /// assert_eq!(x.to_string(), "4.00");
5983 /// ```
5984 #[allow(clippy::needless_pass_by_value)]
5985 #[inline]
5986 pub fn add_mul_rational_prec_round_assign(
5987 &mut self,
5988 y: Self,
5989 z: Rational,
5990 prec: u64,
5991 rm: RoundingMode,
5992 ) -> Ordering {
5993 let (s, o) = add_mul_rational_helper(self, &y, &z, false, prec, rm);
5994 *self = s;
5995 o
5996 }
5997
5998 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place, rounding the
5999 /// result to the specified precision and with the specified rounding mode. The [`Float`] on the
6000 /// right-hand side is taken by value and the [`Rational`] by reference. An [`Ordering`] is
6001 /// returned, indicating whether the rounded sum is less than, equal to, or greater than the
6002 /// exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
6003 /// assigns a `NaN` it also returns `Equal`.
6004 ///
6005 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6006 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
6007 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6008 ///
6009 /// See [`RoundingMode`] for a description of the possible rounding modes.
6010 ///
6011 /// $$
6012 /// x \gets x+yz+\varepsilon.
6013 /// $$
6014 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6015 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6016 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
6017 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6018 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
6019 ///
6020 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
6021 /// cases, overflow, and underflow.
6022 ///
6023 /// If you know you'll be using `Nearest`, consider using
6024 /// [`Float::add_mul_rational_prec_assign`] instead. If you know that your target precision is
6025 /// the maximum of the precisions of the inputs, consider using
6026 /// [`Float::add_mul_rational_round_assign`] instead. If both of these things are true, consider
6027 /// using
6028 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
6029 /// instead.
6030 ///
6031 /// # Worst-case complexity
6032 /// $T(n, m) = O(n \log n \log\log n + m)$
6033 ///
6034 /// $M(n, m) = O(n \log n + m)$
6035 ///
6036 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6037 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6038 /// prec)`.
6039 ///
6040 /// # Panics
6041 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
6042 /// representable with `prec` bits.
6043 ///
6044 /// # Examples
6045 /// ```
6046 /// use core::f64::consts::{E, PI};
6047 /// use malachite_base::rounding_modes::RoundingMode::*;
6048 /// use malachite_float::Float;
6049 /// use malachite_q::Rational;
6050 /// use std::cmp::Ordering::*;
6051 ///
6052 /// let y = Float::from(E);
6053 /// let z = Rational::from_signeds(1, 3);
6054 ///
6055 /// let mut x = Float::from(PI);
6056 /// assert_eq!(
6057 /// x.add_mul_rational_prec_round_assign_val_ref(y.clone(), &z, 5, Floor),
6058 /// Less
6059 /// );
6060 /// assert_eq!(x.to_string(), "4.00");
6061 ///
6062 /// let mut x = Float::from(PI);
6063 /// assert_eq!(
6064 /// x.add_mul_rational_prec_round_assign_val_ref(y.clone(), &z, 5, Ceiling),
6065 /// Greater
6066 /// );
6067 /// assert_eq!(x.to_string(), "4.25");
6068 ///
6069 /// let mut x = Float::from(PI);
6070 /// assert_eq!(
6071 /// x.add_mul_rational_prec_round_assign_val_ref(y.clone(), &z, 5, Nearest),
6072 /// Less
6073 /// );
6074 /// assert_eq!(x.to_string(), "4.00");
6075 /// ```
6076 #[allow(clippy::needless_pass_by_value)]
6077 #[inline]
6078 pub fn add_mul_rational_prec_round_assign_val_ref(
6079 &mut self,
6080 y: Self,
6081 z: &Rational,
6082 prec: u64,
6083 rm: RoundingMode,
6084 ) -> Ordering {
6085 let (s, o) = add_mul_rational_helper(self, &y, z, false, prec, rm);
6086 *self = s;
6087 o
6088 }
6089
6090 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place, rounding the
6091 /// result to the specified precision and with the specified rounding mode. The [`Float`] on the
6092 /// right-hand side is taken by reference and the [`Rational`] by value. An [`Ordering`] is
6093 /// returned, indicating whether the rounded sum is less than, equal to, or greater than the
6094 /// exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
6095 /// assigns a `NaN` it also returns `Equal`.
6096 ///
6097 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6098 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
6099 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6100 ///
6101 /// See [`RoundingMode`] for a description of the possible rounding modes.
6102 ///
6103 /// $$
6104 /// x \gets x+yz+\varepsilon.
6105 /// $$
6106 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6107 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6108 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
6109 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6110 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
6111 ///
6112 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
6113 /// cases, overflow, and underflow.
6114 ///
6115 /// If you know you'll be using `Nearest`, consider using
6116 /// [`Float::add_mul_rational_prec_assign`] instead. If you know that your target precision is
6117 /// the maximum of the precisions of the inputs, consider using
6118 /// [`Float::add_mul_rational_round_assign`] instead. If both of these things are true, consider
6119 /// using
6120 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
6121 /// instead.
6122 ///
6123 /// # Worst-case complexity
6124 /// $T(n, m) = O(n \log n \log\log n + m)$
6125 ///
6126 /// $M(n, m) = O(n \log n + m)$
6127 ///
6128 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6129 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6130 /// prec)`.
6131 ///
6132 /// # Panics
6133 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
6134 /// representable with `prec` bits.
6135 ///
6136 /// # Examples
6137 /// ```
6138 /// use core::f64::consts::{E, PI};
6139 /// use malachite_base::rounding_modes::RoundingMode::*;
6140 /// use malachite_float::Float;
6141 /// use malachite_q::Rational;
6142 /// use std::cmp::Ordering::*;
6143 ///
6144 /// let y = Float::from(E);
6145 /// let z = Rational::from_signeds(1, 3);
6146 ///
6147 /// let mut x = Float::from(PI);
6148 /// assert_eq!(
6149 /// x.add_mul_rational_prec_round_assign_ref_val(&y, z.clone(), 5, Floor),
6150 /// Less
6151 /// );
6152 /// assert_eq!(x.to_string(), "4.00");
6153 ///
6154 /// let mut x = Float::from(PI);
6155 /// assert_eq!(
6156 /// x.add_mul_rational_prec_round_assign_ref_val(&y, z.clone(), 5, Ceiling),
6157 /// Greater
6158 /// );
6159 /// assert_eq!(x.to_string(), "4.25");
6160 ///
6161 /// let mut x = Float::from(PI);
6162 /// assert_eq!(
6163 /// x.add_mul_rational_prec_round_assign_ref_val(&y, z.clone(), 5, Nearest),
6164 /// Less
6165 /// );
6166 /// assert_eq!(x.to_string(), "4.00");
6167 /// ```
6168 #[allow(clippy::needless_pass_by_value)]
6169 #[inline]
6170 pub fn add_mul_rational_prec_round_assign_ref_val(
6171 &mut self,
6172 y: &Self,
6173 z: Rational,
6174 prec: u64,
6175 rm: RoundingMode,
6176 ) -> Ordering {
6177 let (s, o) = add_mul_rational_helper(self, y, &z, false, prec, rm);
6178 *self = s;
6179 o
6180 }
6181
6182 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place, rounding the
6183 /// result to the specified precision and with the specified rounding mode. The [`Float`] and
6184 /// the [`Rational`] on the right-hand side are both taken by reference. An [`Ordering`] is
6185 /// returned, indicating whether the rounded sum is less than, equal to, or greater than the
6186 /// exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
6187 /// assigns a `NaN` it also returns `Equal`.
6188 ///
6189 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6190 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
6191 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6192 ///
6193 /// See [`RoundingMode`] for a description of the possible rounding modes.
6194 ///
6195 /// $$
6196 /// x \gets x+yz+\varepsilon.
6197 /// $$
6198 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6199 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6200 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$.
6201 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6202 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$.
6203 ///
6204 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
6205 /// cases, overflow, and underflow.
6206 ///
6207 /// If you know you'll be using `Nearest`, consider using
6208 /// [`Float::add_mul_rational_prec_assign`] instead. If you know that your target precision is
6209 /// the maximum of the precisions of the inputs, consider using
6210 /// [`Float::add_mul_rational_round_assign`] instead. If both of these things are true, consider
6211 /// using
6212 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
6213 /// instead.
6214 ///
6215 /// # Worst-case complexity
6216 /// $T(n, m) = O(n \log n \log\log n + m)$
6217 ///
6218 /// $M(n, m) = O(n \log n + m)$
6219 ///
6220 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6221 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6222 /// prec)`.
6223 ///
6224 /// # Panics
6225 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-add is not exactly
6226 /// representable with `prec` bits.
6227 ///
6228 /// # Examples
6229 /// ```
6230 /// use core::f64::consts::{E, PI};
6231 /// use malachite_base::rounding_modes::RoundingMode::*;
6232 /// use malachite_float::Float;
6233 /// use malachite_q::Rational;
6234 /// use std::cmp::Ordering::*;
6235 ///
6236 /// let y = Float::from(E);
6237 /// let z = Rational::from_signeds(1, 3);
6238 ///
6239 /// let mut x = Float::from(PI);
6240 /// assert_eq!(
6241 /// x.add_mul_rational_prec_round_assign_ref_ref(&y, &z, 5, Floor),
6242 /// Less
6243 /// );
6244 /// assert_eq!(x.to_string(), "4.00");
6245 ///
6246 /// let mut x = Float::from(PI);
6247 /// assert_eq!(
6248 /// x.add_mul_rational_prec_round_assign_ref_ref(&y, &z, 5, Ceiling),
6249 /// Greater
6250 /// );
6251 /// assert_eq!(x.to_string(), "4.25");
6252 ///
6253 /// let mut x = Float::from(PI);
6254 /// assert_eq!(
6255 /// x.add_mul_rational_prec_round_assign_ref_ref(&y, &z, 5, Nearest),
6256 /// Less
6257 /// );
6258 /// assert_eq!(x.to_string(), "4.00");
6259 /// ```
6260 #[inline]
6261 pub fn add_mul_rational_prec_round_assign_ref_ref(
6262 &mut self,
6263 y: &Self,
6264 z: &Rational,
6265 prec: u64,
6266 rm: RoundingMode,
6267 ) -> Ordering {
6268 let (s, o) = add_mul_rational_helper(self, y, z, false, prec, rm);
6269 *self = s;
6270 o
6271 }
6272
6273 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
6274 /// result to the nearest value of the specified precision. The [`Float`]s and the [`Rational`]
6275 /// are all taken by value. An [`Ordering`] is also returned, indicating whether the rounded sum
6276 /// is less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
6277 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
6278 ///
6279 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6280 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
6281 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6282 ///
6283 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6284 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6285 /// the `Nearest` rounding mode.
6286 ///
6287 /// $$
6288 /// f(x,y,z,p) = x+yz+\varepsilon.
6289 /// $$
6290 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6291 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6292 /// |x+yz|\rfloor-p}$.
6293 ///
6294 /// If the output has a precision, it is `prec`.
6295 ///
6296 /// Special cases:
6297 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
6298 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
6299 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
6300 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
6301 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
6302 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
6303 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
6304 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
6305 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
6306 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
6307 /// [`Rational`] counting as positive.
6308 /// - $f(x,y,z,p)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
6309 ///
6310 /// Overflow and underflow:
6311 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
6312 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
6313 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
6314 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
6315 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
6316 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
6317 ///
6318 /// If you want to use a rounding mode other than `Nearest`, consider using
6319 /// [`Float::add_mul_rational_prec_round`] instead. If you know that your target precision is
6320 /// the maximum of the precisions of the inputs, consider using
6321 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
6322 ///
6323 /// # Worst-case complexity
6324 /// $T(n, m) = O(n \log n \log\log n + m)$
6325 ///
6326 /// $M(n, m) = O(n \log n + m)$
6327 ///
6328 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6329 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6330 /// prec)`.
6331 ///
6332 /// # Panics
6333 /// Panics if `prec` is zero.
6334 ///
6335 /// # Examples
6336 /// ```
6337 /// use core::f64::consts::{E, PI};
6338 /// use malachite_float::Float;
6339 /// use malachite_q::Rational;
6340 /// use std::cmp::Ordering::*;
6341 ///
6342 /// let x = Float::from(PI);
6343 /// let y = Float::from(E);
6344 /// let z = Rational::from_signeds(1, 3);
6345 ///
6346 /// let (sum, o) = x.clone().add_mul_rational_prec(y.clone(), z.clone(), 5);
6347 /// assert_eq!(sum.to_string(), "4.00");
6348 /// assert_eq!(o, Less);
6349 ///
6350 /// let (sum, o) = x.clone().add_mul_rational_prec(y.clone(), z.clone(), 20);
6351 /// assert_eq!(sum.to_string(), "4.0476837");
6352 /// assert_eq!(o, Less);
6353 /// ```
6354 #[allow(clippy::needless_pass_by_value)]
6355 #[inline]
6356 pub fn add_mul_rational_prec(self, y: Self, z: Rational, prec: u64) -> (Self, Ordering) {
6357 self.add_mul_rational_prec_round(y, z, prec, Nearest)
6358 }
6359
6360 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
6361 /// result to the nearest value of the specified precision. The [`Float`]s are taken by value
6362 /// and the [`Rational`] by reference. An [`Ordering`] is also returned, indicating whether the
6363 /// rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
6364 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
6365 ///
6366 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6367 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
6368 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6369 ///
6370 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6371 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6372 /// the `Nearest` rounding mode.
6373 ///
6374 /// $$
6375 /// f(x,y,z,p) = x+yz+\varepsilon.
6376 /// $$
6377 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6378 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6379 /// |x+yz|\rfloor-p}$.
6380 ///
6381 /// If the output has a precision, it is `prec`.
6382 ///
6383 /// Special cases:
6384 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
6385 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
6386 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
6387 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
6388 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
6389 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
6390 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
6391 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
6392 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
6393 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
6394 /// [`Rational`] counting as positive.
6395 /// - $f(x,y,z,p)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
6396 ///
6397 /// Overflow and underflow:
6398 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
6399 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
6400 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
6401 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
6402 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
6403 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
6404 ///
6405 /// If you want to use a rounding mode other than `Nearest`, consider using
6406 /// [`Float::add_mul_rational_prec_round`] instead. If you know that your target precision is
6407 /// the maximum of the precisions of the inputs, consider using
6408 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
6409 ///
6410 /// # Worst-case complexity
6411 /// $T(n, m) = O(n \log n \log\log n + m)$
6412 ///
6413 /// $M(n, m) = O(n \log n + m)$
6414 ///
6415 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6416 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6417 /// prec)`.
6418 ///
6419 /// # Panics
6420 /// Panics if `prec` is zero.
6421 ///
6422 /// # Examples
6423 /// ```
6424 /// use core::f64::consts::{E, PI};
6425 /// use malachite_float::Float;
6426 /// use malachite_q::Rational;
6427 /// use std::cmp::Ordering::*;
6428 ///
6429 /// let x = Float::from(PI);
6430 /// let y = Float::from(E);
6431 /// let z = Rational::from_signeds(1, 3);
6432 ///
6433 /// let (sum, o) = x
6434 /// .clone()
6435 /// .add_mul_rational_prec_val_val_ref(y.clone(), &z, 5);
6436 /// assert_eq!(sum.to_string(), "4.00");
6437 /// assert_eq!(o, Less);
6438 ///
6439 /// let (sum, o) = x
6440 /// .clone()
6441 /// .add_mul_rational_prec_val_val_ref(y.clone(), &z, 20);
6442 /// assert_eq!(sum.to_string(), "4.0476837");
6443 /// assert_eq!(o, Less);
6444 /// ```
6445 #[allow(clippy::needless_pass_by_value)]
6446 #[inline]
6447 pub fn add_mul_rational_prec_val_val_ref(
6448 self,
6449 y: Self,
6450 z: &Rational,
6451 prec: u64,
6452 ) -> (Self, Ordering) {
6453 self.add_mul_rational_prec_round_val_val_ref(y, z, prec, Nearest)
6454 }
6455
6456 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
6457 /// result to the nearest value of the specified precision. The first [`Float`] and the
6458 /// [`Rational`] are taken by value and the second [`Float`] by reference. An [`Ordering`] is
6459 /// also returned, indicating whether the rounded sum is less than, equal to, or greater than
6460 /// the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
6461 /// returns a `NaN` it also returns `Equal`.
6462 ///
6463 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6464 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
6465 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6466 ///
6467 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6468 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6469 /// the `Nearest` rounding mode.
6470 ///
6471 /// $$
6472 /// f(x,y,z,p) = x+yz+\varepsilon.
6473 /// $$
6474 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6475 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6476 /// |x+yz|\rfloor-p}$.
6477 ///
6478 /// If the output has a precision, it is `prec`.
6479 ///
6480 /// Special cases:
6481 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
6482 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
6483 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
6484 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
6485 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
6486 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
6487 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
6488 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
6489 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
6490 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
6491 /// [`Rational`] counting as positive.
6492 /// - $f(x,y,z,p)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
6493 ///
6494 /// Overflow and underflow:
6495 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
6496 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
6497 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
6498 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
6499 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
6500 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
6501 ///
6502 /// If you want to use a rounding mode other than `Nearest`, consider using
6503 /// [`Float::add_mul_rational_prec_round`] instead. If you know that your target precision is
6504 /// the maximum of the precisions of the inputs, consider using
6505 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
6506 ///
6507 /// # Worst-case complexity
6508 /// $T(n, m) = O(n \log n \log\log n + m)$
6509 ///
6510 /// $M(n, m) = O(n \log n + m)$
6511 ///
6512 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6513 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6514 /// prec)`.
6515 ///
6516 /// # Panics
6517 /// Panics if `prec` is zero.
6518 ///
6519 /// # Examples
6520 /// ```
6521 /// use core::f64::consts::{E, PI};
6522 /// use malachite_float::Float;
6523 /// use malachite_q::Rational;
6524 /// use std::cmp::Ordering::*;
6525 ///
6526 /// let x = Float::from(PI);
6527 /// let y = Float::from(E);
6528 /// let z = Rational::from_signeds(1, 3);
6529 ///
6530 /// let (sum, o) = x
6531 /// .clone()
6532 /// .add_mul_rational_prec_val_ref_val(&y, z.clone(), 5);
6533 /// assert_eq!(sum.to_string(), "4.00");
6534 /// assert_eq!(o, Less);
6535 ///
6536 /// let (sum, o) = x
6537 /// .clone()
6538 /// .add_mul_rational_prec_val_ref_val(&y, z.clone(), 20);
6539 /// assert_eq!(sum.to_string(), "4.0476837");
6540 /// assert_eq!(o, Less);
6541 /// ```
6542 #[allow(clippy::needless_pass_by_value)]
6543 #[inline]
6544 pub fn add_mul_rational_prec_val_ref_val(
6545 self,
6546 y: &Self,
6547 z: Rational,
6548 prec: u64,
6549 ) -> (Self, Ordering) {
6550 self.add_mul_rational_prec_round_val_ref_val(y, z, prec, Nearest)
6551 }
6552
6553 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
6554 /// result to the nearest value of the specified precision. The first [`Float`] is taken by
6555 /// value and the second [`Float`] and the [`Rational`] by reference. An [`Ordering`] is also
6556 /// returned, indicating whether the rounded sum is less than, equal to, or greater than the
6557 /// exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
6558 /// returns a `NaN` it also returns `Equal`.
6559 ///
6560 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6561 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
6562 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6563 ///
6564 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6565 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6566 /// the `Nearest` rounding mode.
6567 ///
6568 /// $$
6569 /// f(x,y,z,p) = x+yz+\varepsilon.
6570 /// $$
6571 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6572 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6573 /// |x+yz|\rfloor-p}$.
6574 ///
6575 /// If the output has a precision, it is `prec`.
6576 ///
6577 /// Special cases:
6578 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
6579 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
6580 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
6581 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
6582 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
6583 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
6584 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
6585 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
6586 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
6587 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
6588 /// [`Rational`] counting as positive.
6589 /// - $f(x,y,z,p)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
6590 ///
6591 /// Overflow and underflow:
6592 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
6593 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
6594 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
6595 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
6596 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
6597 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
6598 ///
6599 /// If you want to use a rounding mode other than `Nearest`, consider using
6600 /// [`Float::add_mul_rational_prec_round`] instead. If you know that your target precision is
6601 /// the maximum of the precisions of the inputs, consider using
6602 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
6603 ///
6604 /// # Worst-case complexity
6605 /// $T(n, m) = O(n \log n \log\log n + m)$
6606 ///
6607 /// $M(n, m) = O(n \log n + m)$
6608 ///
6609 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6610 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6611 /// prec)`.
6612 ///
6613 /// # Panics
6614 /// Panics if `prec` is zero.
6615 ///
6616 /// # Examples
6617 /// ```
6618 /// use core::f64::consts::{E, PI};
6619 /// use malachite_float::Float;
6620 /// use malachite_q::Rational;
6621 /// use std::cmp::Ordering::*;
6622 ///
6623 /// let x = Float::from(PI);
6624 /// let y = Float::from(E);
6625 /// let z = Rational::from_signeds(1, 3);
6626 ///
6627 /// let (sum, o) = x.clone().add_mul_rational_prec_val_ref_ref(&y, &z, 5);
6628 /// assert_eq!(sum.to_string(), "4.00");
6629 /// assert_eq!(o, Less);
6630 ///
6631 /// let (sum, o) = x.clone().add_mul_rational_prec_val_ref_ref(&y, &z, 20);
6632 /// assert_eq!(sum.to_string(), "4.0476837");
6633 /// assert_eq!(o, Less);
6634 /// ```
6635 #[allow(clippy::needless_pass_by_value)]
6636 #[inline]
6637 pub fn add_mul_rational_prec_val_ref_ref(
6638 self,
6639 y: &Self,
6640 z: &Rational,
6641 prec: u64,
6642 ) -> (Self, Ordering) {
6643 self.add_mul_rational_prec_round_val_ref_ref(y, z, prec, Nearest)
6644 }
6645
6646 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
6647 /// result to the nearest value of the specified precision. The first [`Float`] is taken by
6648 /// reference and the second [`Float`] and the [`Rational`] by value. An [`Ordering`] is also
6649 /// returned, indicating whether the rounded sum is less than, equal to, or greater than the
6650 /// exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
6651 /// returns a `NaN` it also returns `Equal`.
6652 ///
6653 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6654 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
6655 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6656 ///
6657 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6658 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6659 /// the `Nearest` rounding mode.
6660 ///
6661 /// $$
6662 /// f(x,y,z,p) = x+yz+\varepsilon.
6663 /// $$
6664 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6665 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6666 /// |x+yz|\rfloor-p}$.
6667 ///
6668 /// If the output has a precision, it is `prec`.
6669 ///
6670 /// Special cases:
6671 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
6672 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
6673 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
6674 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
6675 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
6676 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
6677 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
6678 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
6679 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
6680 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
6681 /// [`Rational`] counting as positive.
6682 /// - $f(x,y,z,p)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
6683 ///
6684 /// Overflow and underflow:
6685 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
6686 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
6687 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
6688 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
6689 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
6690 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
6691 ///
6692 /// If you want to use a rounding mode other than `Nearest`, consider using
6693 /// [`Float::add_mul_rational_prec_round`] instead. If you know that your target precision is
6694 /// the maximum of the precisions of the inputs, consider using
6695 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
6696 ///
6697 /// # Worst-case complexity
6698 /// $T(n, m) = O(n \log n \log\log n + m)$
6699 ///
6700 /// $M(n, m) = O(n \log n + m)$
6701 ///
6702 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6703 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6704 /// prec)`.
6705 ///
6706 /// # Panics
6707 /// Panics if `prec` is zero.
6708 ///
6709 /// # Examples
6710 /// ```
6711 /// use core::f64::consts::{E, PI};
6712 /// use malachite_float::Float;
6713 /// use malachite_q::Rational;
6714 /// use std::cmp::Ordering::*;
6715 ///
6716 /// let x = Float::from(PI);
6717 /// let y = Float::from(E);
6718 /// let z = Rational::from_signeds(1, 3);
6719 ///
6720 /// let (sum, o) = x.add_mul_rational_prec_ref_val_val(y.clone(), z.clone(), 5);
6721 /// assert_eq!(sum.to_string(), "4.00");
6722 /// assert_eq!(o, Less);
6723 ///
6724 /// let (sum, o) = x.add_mul_rational_prec_ref_val_val(y.clone(), z.clone(), 20);
6725 /// assert_eq!(sum.to_string(), "4.0476837");
6726 /// assert_eq!(o, Less);
6727 /// ```
6728 #[allow(clippy::needless_pass_by_value)]
6729 #[inline]
6730 pub fn add_mul_rational_prec_ref_val_val(
6731 &self,
6732 y: Self,
6733 z: Rational,
6734 prec: u64,
6735 ) -> (Self, Ordering) {
6736 self.add_mul_rational_prec_round_ref_val_val(y, z, prec, Nearest)
6737 }
6738
6739 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
6740 /// result to the nearest value of the specified precision. The second [`Float`] is taken by
6741 /// value and the first [`Float`] and the [`Rational`] by reference. An [`Ordering`] is also
6742 /// returned, indicating whether the rounded sum is less than, equal to, or greater than the
6743 /// exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
6744 /// returns a `NaN` it also returns `Equal`.
6745 ///
6746 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6747 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
6748 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6749 ///
6750 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6751 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6752 /// the `Nearest` rounding mode.
6753 ///
6754 /// $$
6755 /// f(x,y,z,p) = x+yz+\varepsilon.
6756 /// $$
6757 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6758 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6759 /// |x+yz|\rfloor-p}$.
6760 ///
6761 /// If the output has a precision, it is `prec`.
6762 ///
6763 /// Special cases:
6764 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
6765 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
6766 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
6767 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
6768 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
6769 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
6770 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
6771 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
6772 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
6773 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
6774 /// [`Rational`] counting as positive.
6775 /// - $f(x,y,z,p)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
6776 ///
6777 /// Overflow and underflow:
6778 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
6779 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
6780 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
6781 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
6782 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
6783 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
6784 ///
6785 /// If you want to use a rounding mode other than `Nearest`, consider using
6786 /// [`Float::add_mul_rational_prec_round`] instead. If you know that your target precision is
6787 /// the maximum of the precisions of the inputs, consider using
6788 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
6789 ///
6790 /// # Worst-case complexity
6791 /// $T(n, m) = O(n \log n \log\log n + m)$
6792 ///
6793 /// $M(n, m) = O(n \log n + m)$
6794 ///
6795 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6796 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6797 /// prec)`.
6798 ///
6799 /// # Panics
6800 /// Panics if `prec` is zero.
6801 ///
6802 /// # Examples
6803 /// ```
6804 /// use core::f64::consts::{E, PI};
6805 /// use malachite_float::Float;
6806 /// use malachite_q::Rational;
6807 /// use std::cmp::Ordering::*;
6808 ///
6809 /// let x = Float::from(PI);
6810 /// let y = Float::from(E);
6811 /// let z = Rational::from_signeds(1, 3);
6812 ///
6813 /// let (sum, o) = x.add_mul_rational_prec_ref_val_ref(y.clone(), &z, 5);
6814 /// assert_eq!(sum.to_string(), "4.00");
6815 /// assert_eq!(o, Less);
6816 ///
6817 /// let (sum, o) = x.add_mul_rational_prec_ref_val_ref(y.clone(), &z, 20);
6818 /// assert_eq!(sum.to_string(), "4.0476837");
6819 /// assert_eq!(o, Less);
6820 /// ```
6821 #[allow(clippy::needless_pass_by_value)]
6822 #[inline]
6823 pub fn add_mul_rational_prec_ref_val_ref(
6824 &self,
6825 y: Self,
6826 z: &Rational,
6827 prec: u64,
6828 ) -> (Self, Ordering) {
6829 self.add_mul_rational_prec_round_ref_val_ref(y, z, prec, Nearest)
6830 }
6831
6832 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
6833 /// result to the nearest value of the specified precision. The [`Float`]s are taken by
6834 /// reference and the [`Rational`] by value. An [`Ordering`] is also returned, indicating
6835 /// whether the rounded sum is less than, equal to, or greater than the exact sum. Although
6836 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
6837 /// returns `Equal`.
6838 ///
6839 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6840 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
6841 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6842 ///
6843 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6844 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6845 /// the `Nearest` rounding mode.
6846 ///
6847 /// $$
6848 /// f(x,y,z,p) = x+yz+\varepsilon.
6849 /// $$
6850 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6851 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6852 /// |x+yz|\rfloor-p}$.
6853 ///
6854 /// If the output has a precision, it is `prec`.
6855 ///
6856 /// Special cases:
6857 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
6858 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
6859 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
6860 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
6861 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
6862 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
6863 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
6864 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
6865 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
6866 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
6867 /// [`Rational`] counting as positive.
6868 /// - $f(x,y,z,p)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
6869 ///
6870 /// Overflow and underflow:
6871 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
6872 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
6873 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
6874 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
6875 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
6876 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
6877 ///
6878 /// If you want to use a rounding mode other than `Nearest`, consider using
6879 /// [`Float::add_mul_rational_prec_round`] instead. If you know that your target precision is
6880 /// the maximum of the precisions of the inputs, consider using
6881 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
6882 ///
6883 /// # Worst-case complexity
6884 /// $T(n, m) = O(n \log n \log\log n + m)$
6885 ///
6886 /// $M(n, m) = O(n \log n + m)$
6887 ///
6888 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6889 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6890 /// prec)`.
6891 ///
6892 /// # Panics
6893 /// Panics if `prec` is zero.
6894 ///
6895 /// # Examples
6896 /// ```
6897 /// use core::f64::consts::{E, PI};
6898 /// use malachite_float::Float;
6899 /// use malachite_q::Rational;
6900 /// use std::cmp::Ordering::*;
6901 ///
6902 /// let x = Float::from(PI);
6903 /// let y = Float::from(E);
6904 /// let z = Rational::from_signeds(1, 3);
6905 ///
6906 /// let (sum, o) = x.add_mul_rational_prec_ref_ref_val(&y, z.clone(), 5);
6907 /// assert_eq!(sum.to_string(), "4.00");
6908 /// assert_eq!(o, Less);
6909 ///
6910 /// let (sum, o) = x.add_mul_rational_prec_ref_ref_val(&y, z.clone(), 20);
6911 /// assert_eq!(sum.to_string(), "4.0476837");
6912 /// assert_eq!(o, Less);
6913 /// ```
6914 #[allow(clippy::needless_pass_by_value)]
6915 #[inline]
6916 pub fn add_mul_rational_prec_ref_ref_val(
6917 &self,
6918 y: &Self,
6919 z: Rational,
6920 prec: u64,
6921 ) -> (Self, Ordering) {
6922 self.add_mul_rational_prec_round_ref_ref_val(y, z, prec, Nearest)
6923 }
6924
6925 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
6926 /// result to the nearest value of the specified precision. The [`Float`]s and the [`Rational`]
6927 /// are all taken by reference. An [`Ordering`] is also returned, indicating whether the rounded
6928 /// sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
6929 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
6930 ///
6931 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6932 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
6933 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6934 ///
6935 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6936 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6937 /// the `Nearest` rounding mode.
6938 ///
6939 /// $$
6940 /// f(x,y,z,p) = x+yz+\varepsilon.
6941 /// $$
6942 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6943 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6944 /// |x+yz|\rfloor-p}$.
6945 ///
6946 /// If the output has a precision, it is `prec`.
6947 ///
6948 /// Special cases:
6949 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
6950 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
6951 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
6952 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
6953 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
6954 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
6955 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=\infty$
6956 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=-\infty$
6957 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
6958 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
6959 /// [`Rational`] counting as positive.
6960 /// - $f(x,y,z,p)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
6961 ///
6962 /// Overflow and underflow:
6963 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
6964 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
6965 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
6966 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
6967 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
6968 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
6969 ///
6970 /// If you want to use a rounding mode other than `Nearest`, consider using
6971 /// [`Float::add_mul_rational_prec_round`] instead. If you know that your target precision is
6972 /// the maximum of the precisions of the inputs, consider using
6973 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
6974 ///
6975 /// # Worst-case complexity
6976 /// $T(n, m) = O(n \log n \log\log n + m)$
6977 ///
6978 /// $M(n, m) = O(n \log n + m)$
6979 ///
6980 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6981 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6982 /// prec)`.
6983 ///
6984 /// # Panics
6985 /// Panics if `prec` is zero.
6986 ///
6987 /// # Examples
6988 /// ```
6989 /// use core::f64::consts::{E, PI};
6990 /// use malachite_float::Float;
6991 /// use malachite_q::Rational;
6992 /// use std::cmp::Ordering::*;
6993 ///
6994 /// let x = Float::from(PI);
6995 /// let y = Float::from(E);
6996 /// let z = Rational::from_signeds(1, 3);
6997 ///
6998 /// let (sum, o) = x.add_mul_rational_prec_ref_ref_ref(&y, &z, 5);
6999 /// assert_eq!(sum.to_string(), "4.00");
7000 /// assert_eq!(o, Less);
7001 ///
7002 /// let (sum, o) = x.add_mul_rational_prec_ref_ref_ref(&y, &z, 20);
7003 /// assert_eq!(sum.to_string(), "4.0476837");
7004 /// assert_eq!(o, Less);
7005 /// ```
7006 #[inline]
7007 pub fn add_mul_rational_prec_ref_ref_ref(
7008 &self,
7009 y: &Self,
7010 z: &Rational,
7011 prec: u64,
7012 ) -> (Self, Ordering) {
7013 self.add_mul_rational_prec_round_ref_ref_ref(y, z, prec, Nearest)
7014 }
7015
7016 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place, rounding the
7017 /// result to the nearest value of the specified precision. The [`Float`] and the [`Rational`]
7018 /// on the right-hand side are both taken by value. An [`Ordering`] is returned, indicating
7019 /// whether the rounded sum is less than, equal to, or greater than the exact sum. Although
7020 /// `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN` it also
7021 /// returns `Equal`.
7022 ///
7023 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7024 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
7025 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7026 ///
7027 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
7028 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
7029 /// the `Nearest` rounding mode.
7030 ///
7031 /// $$
7032 /// x \gets x+yz+\varepsilon.
7033 /// $$
7034 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7035 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
7036 /// |x+yz|\rfloor-p}$.
7037 ///
7038 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
7039 /// cases, overflow, and underflow.
7040 ///
7041 /// If you want to use a rounding mode other than `Nearest`, consider using
7042 /// [`Float::add_mul_rational_prec_round_assign`] instead. If you know that your target
7043 /// precision is the maximum of the precisions of the inputs, consider using
7044 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
7045 /// instead.
7046 ///
7047 /// # Worst-case complexity
7048 /// $T(n, m) = O(n \log n \log\log n + m)$
7049 ///
7050 /// $M(n, m) = O(n \log n + m)$
7051 ///
7052 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7053 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
7054 /// prec)`.
7055 ///
7056 /// # Panics
7057 /// Panics if `prec` is zero.
7058 ///
7059 /// # Examples
7060 /// ```
7061 /// use core::f64::consts::{E, PI};
7062 /// use malachite_float::Float;
7063 /// use malachite_q::Rational;
7064 /// use std::cmp::Ordering::*;
7065 ///
7066 /// let y = Float::from(E);
7067 /// let z = Rational::from_signeds(1, 3);
7068 ///
7069 /// let mut x = Float::from(PI);
7070 /// assert_eq!(
7071 /// x.add_mul_rational_prec_assign(y.clone(), z.clone(), 5),
7072 /// Less
7073 /// );
7074 /// assert_eq!(x.to_string(), "4.00");
7075 ///
7076 /// let mut x = Float::from(PI);
7077 /// assert_eq!(
7078 /// x.add_mul_rational_prec_assign(y.clone(), z.clone(), 20),
7079 /// Less
7080 /// );
7081 /// assert_eq!(x.to_string(), "4.0476837");
7082 /// ```
7083 #[allow(clippy::needless_pass_by_value)]
7084 #[inline]
7085 pub fn add_mul_rational_prec_assign(&mut self, y: Self, z: Rational, prec: u64) -> Ordering {
7086 self.add_mul_rational_prec_round_assign(y, z, prec, Nearest)
7087 }
7088
7089 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place, rounding the
7090 /// result to the nearest value of the specified precision. The [`Float`] on the right-hand side
7091 /// is taken by value and the [`Rational`] by reference. An [`Ordering`] is returned, indicating
7092 /// whether the rounded sum is less than, equal to, or greater than the exact sum. Although
7093 /// `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN` it also
7094 /// returns `Equal`.
7095 ///
7096 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7097 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
7098 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7099 ///
7100 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
7101 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
7102 /// the `Nearest` rounding mode.
7103 ///
7104 /// $$
7105 /// x \gets x+yz+\varepsilon.
7106 /// $$
7107 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7108 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
7109 /// |x+yz|\rfloor-p}$.
7110 ///
7111 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
7112 /// cases, overflow, and underflow.
7113 ///
7114 /// If you want to use a rounding mode other than `Nearest`, consider using
7115 /// [`Float::add_mul_rational_prec_round_assign`] instead. If you know that your target
7116 /// precision is the maximum of the precisions of the inputs, consider using
7117 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
7118 /// instead.
7119 ///
7120 /// # Worst-case complexity
7121 /// $T(n, m) = O(n \log n \log\log n + m)$
7122 ///
7123 /// $M(n, m) = O(n \log n + m)$
7124 ///
7125 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7126 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
7127 /// prec)`.
7128 ///
7129 /// # Panics
7130 /// Panics if `prec` is zero.
7131 ///
7132 /// # Examples
7133 /// ```
7134 /// use core::f64::consts::{E, PI};
7135 /// use malachite_float::Float;
7136 /// use malachite_q::Rational;
7137 /// use std::cmp::Ordering::*;
7138 ///
7139 /// let y = Float::from(E);
7140 /// let z = Rational::from_signeds(1, 3);
7141 ///
7142 /// let mut x = Float::from(PI);
7143 /// assert_eq!(
7144 /// x.add_mul_rational_prec_assign_val_ref(y.clone(), &z, 5),
7145 /// Less
7146 /// );
7147 /// assert_eq!(x.to_string(), "4.00");
7148 ///
7149 /// let mut x = Float::from(PI);
7150 /// assert_eq!(
7151 /// x.add_mul_rational_prec_assign_val_ref(y.clone(), &z, 20),
7152 /// Less
7153 /// );
7154 /// assert_eq!(x.to_string(), "4.0476837");
7155 /// ```
7156 #[allow(clippy::needless_pass_by_value)]
7157 #[inline]
7158 pub fn add_mul_rational_prec_assign_val_ref(
7159 &mut self,
7160 y: Self,
7161 z: &Rational,
7162 prec: u64,
7163 ) -> Ordering {
7164 self.add_mul_rational_prec_round_assign_val_ref(y, z, prec, Nearest)
7165 }
7166
7167 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place, rounding the
7168 /// result to the nearest value of the specified precision. The [`Float`] on the right-hand side
7169 /// is taken by reference and the [`Rational`] by value. An [`Ordering`] is returned, indicating
7170 /// whether the rounded sum is less than, equal to, or greater than the exact sum. Although
7171 /// `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN` it also
7172 /// returns `Equal`.
7173 ///
7174 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7175 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
7176 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7177 ///
7178 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
7179 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
7180 /// the `Nearest` rounding mode.
7181 ///
7182 /// $$
7183 /// x \gets x+yz+\varepsilon.
7184 /// $$
7185 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7186 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
7187 /// |x+yz|\rfloor-p}$.
7188 ///
7189 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
7190 /// cases, overflow, and underflow.
7191 ///
7192 /// If you want to use a rounding mode other than `Nearest`, consider using
7193 /// [`Float::add_mul_rational_prec_round_assign`] instead. If you know that your target
7194 /// precision is the maximum of the precisions of the inputs, consider using
7195 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
7196 /// instead.
7197 ///
7198 /// # Worst-case complexity
7199 /// $T(n, m) = O(n \log n \log\log n + m)$
7200 ///
7201 /// $M(n, m) = O(n \log n + m)$
7202 ///
7203 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7204 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
7205 /// prec)`.
7206 ///
7207 /// # Panics
7208 /// Panics if `prec` is zero.
7209 ///
7210 /// # Examples
7211 /// ```
7212 /// use core::f64::consts::{E, PI};
7213 /// use malachite_float::Float;
7214 /// use malachite_q::Rational;
7215 /// use std::cmp::Ordering::*;
7216 ///
7217 /// let y = Float::from(E);
7218 /// let z = Rational::from_signeds(1, 3);
7219 ///
7220 /// let mut x = Float::from(PI);
7221 /// assert_eq!(
7222 /// x.add_mul_rational_prec_assign_ref_val(&y, z.clone(), 5),
7223 /// Less
7224 /// );
7225 /// assert_eq!(x.to_string(), "4.00");
7226 ///
7227 /// let mut x = Float::from(PI);
7228 /// assert_eq!(
7229 /// x.add_mul_rational_prec_assign_ref_val(&y, z.clone(), 20),
7230 /// Less
7231 /// );
7232 /// assert_eq!(x.to_string(), "4.0476837");
7233 /// ```
7234 #[allow(clippy::needless_pass_by_value)]
7235 #[inline]
7236 pub fn add_mul_rational_prec_assign_ref_val(
7237 &mut self,
7238 y: &Self,
7239 z: Rational,
7240 prec: u64,
7241 ) -> Ordering {
7242 self.add_mul_rational_prec_round_assign_ref_val(y, z, prec, Nearest)
7243 }
7244
7245 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place, rounding the
7246 /// result to the nearest value of the specified precision. The [`Float`] and the [`Rational`]
7247 /// on the right-hand side are both taken by reference. An [`Ordering`] is returned, indicating
7248 /// whether the rounded sum is less than, equal to, or greater than the exact sum. Although
7249 /// `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN` it also
7250 /// returns `Equal`.
7251 ///
7252 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7253 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
7254 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7255 ///
7256 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
7257 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
7258 /// the `Nearest` rounding mode.
7259 ///
7260 /// $$
7261 /// x \gets x+yz+\varepsilon.
7262 /// $$
7263 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7264 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
7265 /// |x+yz|\rfloor-p}$.
7266 ///
7267 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
7268 /// cases, overflow, and underflow.
7269 ///
7270 /// If you want to use a rounding mode other than `Nearest`, consider using
7271 /// [`Float::add_mul_rational_prec_round_assign`] instead. If you know that your target
7272 /// precision is the maximum of the precisions of the inputs, consider using
7273 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
7274 /// instead.
7275 ///
7276 /// # Worst-case complexity
7277 /// $T(n, m) = O(n \log n \log\log n + m)$
7278 ///
7279 /// $M(n, m) = O(n \log n + m)$
7280 ///
7281 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7282 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
7283 /// prec)`.
7284 ///
7285 /// # Panics
7286 /// Panics if `prec` is zero.
7287 ///
7288 /// # Examples
7289 /// ```
7290 /// use core::f64::consts::{E, PI};
7291 /// use malachite_float::Float;
7292 /// use malachite_q::Rational;
7293 /// use std::cmp::Ordering::*;
7294 ///
7295 /// let y = Float::from(E);
7296 /// let z = Rational::from_signeds(1, 3);
7297 ///
7298 /// let mut x = Float::from(PI);
7299 /// assert_eq!(x.add_mul_rational_prec_assign_ref_ref(&y, &z, 5), Less);
7300 /// assert_eq!(x.to_string(), "4.00");
7301 ///
7302 /// let mut x = Float::from(PI);
7303 /// assert_eq!(x.add_mul_rational_prec_assign_ref_ref(&y, &z, 20), Less);
7304 /// assert_eq!(x.to_string(), "4.0476837");
7305 /// ```
7306 #[inline]
7307 pub fn add_mul_rational_prec_assign_ref_ref(
7308 &mut self,
7309 y: &Self,
7310 z: &Rational,
7311 prec: u64,
7312 ) -> Ordering {
7313 self.add_mul_rational_prec_round_assign_ref_ref(y, z, prec, Nearest)
7314 }
7315
7316 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
7317 /// result with the specified rounding mode. The [`Float`]s and the [`Rational`] are all taken
7318 /// by value. An [`Ordering`] is also returned, indicating whether the rounded sum is less than,
7319 /// equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
7320 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
7321 ///
7322 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7323 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
7324 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7325 ///
7326 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
7327 /// [`RoundingMode`] for a description of the possible rounding modes.
7328 ///
7329 /// $$
7330 /// f(x,y,z,m) = x+yz+\varepsilon.
7331 /// $$
7332 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7333 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7334 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
7335 /// [`Float`]s.
7336 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7337 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input
7338 /// [`Float`]s.
7339 ///
7340 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
7341 ///
7342 /// Special cases:
7343 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
7344 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
7345 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
7346 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
7347 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
7348 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
7349 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
7350 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
7351 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
7352 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
7353 /// [`Rational`] counting as positive.
7354 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
7355 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
7356 ///
7357 /// Overflow and underflow:
7358 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
7359 /// returned instead.
7360 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
7361 /// is returned instead, where `p` is the precision of the output.
7362 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
7363 /// returned instead.
7364 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
7365 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
7366 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
7367 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
7368 /// instead.
7369 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
7370 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
7371 /// instead.
7372 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
7373 /// instead.
7374 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
7375 /// instead.
7376 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
7377 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
7378 /// returned instead.
7379 ///
7380 /// If you want to specify an output precision, consider using
7381 /// [`Float::add_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
7382 /// rounding mode, consider using
7383 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
7384 ///
7385 /// # Worst-case complexity
7386 /// $T(n, m) = O(n \log n \log\log n + m)$
7387 ///
7388 /// $M(n, m) = O(n \log n + m)$
7389 ///
7390 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7391 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
7392 ///
7393 /// # Panics
7394 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
7395 /// enough to represent the output.
7396 ///
7397 /// # Examples
7398 /// ```
7399 /// use core::f64::consts::{E, PI};
7400 /// use malachite_base::rounding_modes::RoundingMode::*;
7401 /// use malachite_float::Float;
7402 /// use malachite_q::Rational;
7403 /// use std::cmp::Ordering::*;
7404 ///
7405 /// let x = Float::from(PI);
7406 /// let y = Float::from(E);
7407 /// let z = Rational::from_signeds(1, 3);
7408 ///
7409 /// let (sum, o) = x
7410 /// .clone()
7411 /// .add_mul_rational_round(y.clone(), z.clone(), Floor);
7412 /// assert_eq!(sum.to_string(), "4.0476865964094744");
7413 /// assert_eq!(o, Less);
7414 ///
7415 /// let (sum, o) = x
7416 /// .clone()
7417 /// .add_mul_rational_round(y.clone(), z.clone(), Ceiling);
7418 /// assert_eq!(sum.to_string(), "4.0476865964094753");
7419 /// assert_eq!(o, Greater);
7420 ///
7421 /// let (sum, o) = x
7422 /// .clone()
7423 /// .add_mul_rational_round(y.clone(), z.clone(), Nearest);
7424 /// assert_eq!(sum.to_string(), "4.0476865964094753");
7425 /// assert_eq!(o, Greater);
7426 /// ```
7427 #[allow(clippy::needless_pass_by_value)]
7428 #[inline]
7429 pub fn add_mul_rational_round(
7430 self,
7431 y: Self,
7432 z: Rational,
7433 rm: RoundingMode,
7434 ) -> (Self, Ordering) {
7435 let prec = max(self.significant_bits(), y.significant_bits());
7436 self.add_mul_rational_prec_round(y, z, prec, rm)
7437 }
7438
7439 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
7440 /// result with the specified rounding mode. The [`Float`]s are taken by value and the
7441 /// [`Rational`] by reference. An [`Ordering`] is also returned, indicating whether the rounded
7442 /// sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
7443 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
7444 ///
7445 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7446 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
7447 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7448 ///
7449 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
7450 /// [`RoundingMode`] for a description of the possible rounding modes.
7451 ///
7452 /// $$
7453 /// f(x,y,z,m) = x+yz+\varepsilon.
7454 /// $$
7455 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7456 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7457 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
7458 /// [`Float`]s.
7459 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7460 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input
7461 /// [`Float`]s.
7462 ///
7463 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
7464 ///
7465 /// Special cases:
7466 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
7467 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
7468 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
7469 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
7470 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
7471 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
7472 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
7473 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
7474 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
7475 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
7476 /// [`Rational`] counting as positive.
7477 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
7478 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
7479 ///
7480 /// Overflow and underflow:
7481 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
7482 /// returned instead.
7483 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
7484 /// is returned instead, where `p` is the precision of the output.
7485 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
7486 /// returned instead.
7487 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
7488 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
7489 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
7490 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
7491 /// instead.
7492 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
7493 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
7494 /// instead.
7495 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
7496 /// instead.
7497 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
7498 /// instead.
7499 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
7500 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
7501 /// returned instead.
7502 ///
7503 /// If you want to specify an output precision, consider using
7504 /// [`Float::add_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
7505 /// rounding mode, consider using
7506 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
7507 ///
7508 /// # Worst-case complexity
7509 /// $T(n, m) = O(n \log n \log\log n + m)$
7510 ///
7511 /// $M(n, m) = O(n \log n + m)$
7512 ///
7513 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7514 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
7515 ///
7516 /// # Panics
7517 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
7518 /// enough to represent the output.
7519 ///
7520 /// # Examples
7521 /// ```
7522 /// use core::f64::consts::{E, PI};
7523 /// use malachite_base::rounding_modes::RoundingMode::*;
7524 /// use malachite_float::Float;
7525 /// use malachite_q::Rational;
7526 /// use std::cmp::Ordering::*;
7527 ///
7528 /// let x = Float::from(PI);
7529 /// let y = Float::from(E);
7530 /// let z = Rational::from_signeds(1, 3);
7531 ///
7532 /// let (sum, o) = x
7533 /// .clone()
7534 /// .add_mul_rational_round_val_val_ref(y.clone(), &z, Floor);
7535 /// assert_eq!(sum.to_string(), "4.0476865964094744");
7536 /// assert_eq!(o, Less);
7537 ///
7538 /// let (sum, o) = x
7539 /// .clone()
7540 /// .add_mul_rational_round_val_val_ref(y.clone(), &z, Ceiling);
7541 /// assert_eq!(sum.to_string(), "4.0476865964094753");
7542 /// assert_eq!(o, Greater);
7543 ///
7544 /// let (sum, o) = x
7545 /// .clone()
7546 /// .add_mul_rational_round_val_val_ref(y.clone(), &z, Nearest);
7547 /// assert_eq!(sum.to_string(), "4.0476865964094753");
7548 /// assert_eq!(o, Greater);
7549 /// ```
7550 #[allow(clippy::needless_pass_by_value)]
7551 #[inline]
7552 pub fn add_mul_rational_round_val_val_ref(
7553 self,
7554 y: Self,
7555 z: &Rational,
7556 rm: RoundingMode,
7557 ) -> (Self, Ordering) {
7558 let prec = max(self.significant_bits(), y.significant_bits());
7559 self.add_mul_rational_prec_round_val_val_ref(y, z, prec, rm)
7560 }
7561
7562 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
7563 /// result with the specified rounding mode. The first [`Float`] and the [`Rational`] are taken
7564 /// by value and the second [`Float`] by reference. An [`Ordering`] is also returned, indicating
7565 /// whether the rounded sum is less than, equal to, or greater than the exact sum. Although
7566 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
7567 /// returns `Equal`.
7568 ///
7569 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7570 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
7571 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7572 ///
7573 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
7574 /// [`RoundingMode`] for a description of the possible rounding modes.
7575 ///
7576 /// $$
7577 /// f(x,y,z,m) = x+yz+\varepsilon.
7578 /// $$
7579 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7580 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7581 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
7582 /// [`Float`]s.
7583 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7584 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input
7585 /// [`Float`]s.
7586 ///
7587 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
7588 ///
7589 /// Special cases:
7590 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
7591 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
7592 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
7593 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
7594 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
7595 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
7596 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
7597 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
7598 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
7599 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
7600 /// [`Rational`] counting as positive.
7601 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
7602 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
7603 ///
7604 /// Overflow and underflow:
7605 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
7606 /// returned instead.
7607 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
7608 /// is returned instead, where `p` is the precision of the output.
7609 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
7610 /// returned instead.
7611 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
7612 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
7613 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
7614 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
7615 /// instead.
7616 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
7617 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
7618 /// instead.
7619 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
7620 /// instead.
7621 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
7622 /// instead.
7623 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
7624 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
7625 /// returned instead.
7626 ///
7627 /// If you want to specify an output precision, consider using
7628 /// [`Float::add_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
7629 /// rounding mode, consider using
7630 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
7631 ///
7632 /// # Worst-case complexity
7633 /// $T(n, m) = O(n \log n \log\log n + m)$
7634 ///
7635 /// $M(n, m) = O(n \log n + m)$
7636 ///
7637 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7638 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
7639 ///
7640 /// # Panics
7641 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
7642 /// enough to represent the output.
7643 ///
7644 /// # Examples
7645 /// ```
7646 /// use core::f64::consts::{E, PI};
7647 /// use malachite_base::rounding_modes::RoundingMode::*;
7648 /// use malachite_float::Float;
7649 /// use malachite_q::Rational;
7650 /// use std::cmp::Ordering::*;
7651 ///
7652 /// let x = Float::from(PI);
7653 /// let y = Float::from(E);
7654 /// let z = Rational::from_signeds(1, 3);
7655 ///
7656 /// let (sum, o) = x
7657 /// .clone()
7658 /// .add_mul_rational_round_val_ref_val(&y, z.clone(), Floor);
7659 /// assert_eq!(sum.to_string(), "4.0476865964094744");
7660 /// assert_eq!(o, Less);
7661 ///
7662 /// let (sum, o) = x
7663 /// .clone()
7664 /// .add_mul_rational_round_val_ref_val(&y, z.clone(), Ceiling);
7665 /// assert_eq!(sum.to_string(), "4.0476865964094753");
7666 /// assert_eq!(o, Greater);
7667 ///
7668 /// let (sum, o) = x
7669 /// .clone()
7670 /// .add_mul_rational_round_val_ref_val(&y, z.clone(), Nearest);
7671 /// assert_eq!(sum.to_string(), "4.0476865964094753");
7672 /// assert_eq!(o, Greater);
7673 /// ```
7674 #[allow(clippy::needless_pass_by_value)]
7675 #[inline]
7676 pub fn add_mul_rational_round_val_ref_val(
7677 self,
7678 y: &Self,
7679 z: Rational,
7680 rm: RoundingMode,
7681 ) -> (Self, Ordering) {
7682 let prec = max(self.significant_bits(), y.significant_bits());
7683 self.add_mul_rational_prec_round_val_ref_val(y, z, prec, rm)
7684 }
7685
7686 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
7687 /// result with the specified rounding mode. The first [`Float`] is taken by value and the
7688 /// second [`Float`] and the [`Rational`] by reference. An [`Ordering`] is also returned,
7689 /// indicating whether the rounded sum is less than, equal to, or greater than the exact sum.
7690 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
7691 /// it also returns `Equal`.
7692 ///
7693 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7694 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
7695 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7696 ///
7697 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
7698 /// [`RoundingMode`] for a description of the possible rounding modes.
7699 ///
7700 /// $$
7701 /// f(x,y,z,m) = x+yz+\varepsilon.
7702 /// $$
7703 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7704 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7705 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
7706 /// [`Float`]s.
7707 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7708 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input
7709 /// [`Float`]s.
7710 ///
7711 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
7712 ///
7713 /// Special cases:
7714 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
7715 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
7716 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
7717 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
7718 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
7719 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
7720 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
7721 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
7722 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
7723 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
7724 /// [`Rational`] counting as positive.
7725 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
7726 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
7727 ///
7728 /// Overflow and underflow:
7729 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
7730 /// returned instead.
7731 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
7732 /// is returned instead, where `p` is the precision of the output.
7733 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
7734 /// returned instead.
7735 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
7736 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
7737 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
7738 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
7739 /// instead.
7740 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
7741 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
7742 /// instead.
7743 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
7744 /// instead.
7745 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
7746 /// instead.
7747 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
7748 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
7749 /// returned instead.
7750 ///
7751 /// If you want to specify an output precision, consider using
7752 /// [`Float::add_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
7753 /// rounding mode, consider using
7754 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
7755 ///
7756 /// # Worst-case complexity
7757 /// $T(n, m) = O(n \log n \log\log n + m)$
7758 ///
7759 /// $M(n, m) = O(n \log n + m)$
7760 ///
7761 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7762 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
7763 ///
7764 /// # Panics
7765 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
7766 /// enough to represent the output.
7767 ///
7768 /// # Examples
7769 /// ```
7770 /// use core::f64::consts::{E, PI};
7771 /// use malachite_base::rounding_modes::RoundingMode::*;
7772 /// use malachite_float::Float;
7773 /// use malachite_q::Rational;
7774 /// use std::cmp::Ordering::*;
7775 ///
7776 /// let x = Float::from(PI);
7777 /// let y = Float::from(E);
7778 /// let z = Rational::from_signeds(1, 3);
7779 ///
7780 /// let (sum, o) = x.clone().add_mul_rational_round_val_ref_ref(&y, &z, Floor);
7781 /// assert_eq!(sum.to_string(), "4.0476865964094744");
7782 /// assert_eq!(o, Less);
7783 ///
7784 /// let (sum, o) = x
7785 /// .clone()
7786 /// .add_mul_rational_round_val_ref_ref(&y, &z, Ceiling);
7787 /// assert_eq!(sum.to_string(), "4.0476865964094753");
7788 /// assert_eq!(o, Greater);
7789 ///
7790 /// let (sum, o) = x
7791 /// .clone()
7792 /// .add_mul_rational_round_val_ref_ref(&y, &z, Nearest);
7793 /// assert_eq!(sum.to_string(), "4.0476865964094753");
7794 /// assert_eq!(o, Greater);
7795 /// ```
7796 #[allow(clippy::needless_pass_by_value)]
7797 #[inline]
7798 pub fn add_mul_rational_round_val_ref_ref(
7799 self,
7800 y: &Self,
7801 z: &Rational,
7802 rm: RoundingMode,
7803 ) -> (Self, Ordering) {
7804 let prec = max(self.significant_bits(), y.significant_bits());
7805 self.add_mul_rational_prec_round_val_ref_ref(y, z, prec, rm)
7806 }
7807
7808 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
7809 /// result with the specified rounding mode. The first [`Float`] is taken by reference and the
7810 /// second [`Float`] and the [`Rational`] by value. An [`Ordering`] is also returned, indicating
7811 /// whether the rounded sum is less than, equal to, or greater than the exact sum. Although
7812 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
7813 /// returns `Equal`.
7814 ///
7815 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7816 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
7817 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7818 ///
7819 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
7820 /// [`RoundingMode`] for a description of the possible rounding modes.
7821 ///
7822 /// $$
7823 /// f(x,y,z,m) = x+yz+\varepsilon.
7824 /// $$
7825 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7826 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7827 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
7828 /// [`Float`]s.
7829 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7830 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input
7831 /// [`Float`]s.
7832 ///
7833 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
7834 ///
7835 /// Special cases:
7836 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
7837 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
7838 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
7839 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
7840 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
7841 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
7842 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
7843 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
7844 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
7845 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
7846 /// [`Rational`] counting as positive.
7847 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
7848 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
7849 ///
7850 /// Overflow and underflow:
7851 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
7852 /// returned instead.
7853 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
7854 /// is returned instead, where `p` is the precision of the output.
7855 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
7856 /// returned instead.
7857 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
7858 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
7859 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
7860 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
7861 /// instead.
7862 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
7863 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
7864 /// instead.
7865 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
7866 /// instead.
7867 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
7868 /// instead.
7869 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
7870 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
7871 /// returned instead.
7872 ///
7873 /// If you want to specify an output precision, consider using
7874 /// [`Float::add_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
7875 /// rounding mode, consider using
7876 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
7877 ///
7878 /// # Worst-case complexity
7879 /// $T(n, m) = O(n \log n \log\log n + m)$
7880 ///
7881 /// $M(n, m) = O(n \log n + m)$
7882 ///
7883 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7884 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
7885 ///
7886 /// # Panics
7887 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
7888 /// enough to represent the output.
7889 ///
7890 /// # Examples
7891 /// ```
7892 /// use core::f64::consts::{E, PI};
7893 /// use malachite_base::rounding_modes::RoundingMode::*;
7894 /// use malachite_float::Float;
7895 /// use malachite_q::Rational;
7896 /// use std::cmp::Ordering::*;
7897 ///
7898 /// let x = Float::from(PI);
7899 /// let y = Float::from(E);
7900 /// let z = Rational::from_signeds(1, 3);
7901 ///
7902 /// let (sum, o) = x.add_mul_rational_round_ref_val_val(y.clone(), z.clone(), Floor);
7903 /// assert_eq!(sum.to_string(), "4.0476865964094744");
7904 /// assert_eq!(o, Less);
7905 ///
7906 /// let (sum, o) = x.add_mul_rational_round_ref_val_val(y.clone(), z.clone(), Ceiling);
7907 /// assert_eq!(sum.to_string(), "4.0476865964094753");
7908 /// assert_eq!(o, Greater);
7909 ///
7910 /// let (sum, o) = x.add_mul_rational_round_ref_val_val(y.clone(), z.clone(), Nearest);
7911 /// assert_eq!(sum.to_string(), "4.0476865964094753");
7912 /// assert_eq!(o, Greater);
7913 /// ```
7914 #[allow(clippy::needless_pass_by_value)]
7915 #[inline]
7916 pub fn add_mul_rational_round_ref_val_val(
7917 &self,
7918 y: Self,
7919 z: Rational,
7920 rm: RoundingMode,
7921 ) -> (Self, Ordering) {
7922 let prec = max(self.significant_bits(), y.significant_bits());
7923 self.add_mul_rational_prec_round_ref_val_val(y, z, prec, rm)
7924 }
7925
7926 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
7927 /// result with the specified rounding mode. The second [`Float`] is taken by value and the
7928 /// first [`Float`] and the [`Rational`] by reference. An [`Ordering`] is also returned,
7929 /// indicating whether the rounded sum is less than, equal to, or greater than the exact sum.
7930 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
7931 /// it also returns `Equal`.
7932 ///
7933 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7934 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
7935 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7936 ///
7937 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
7938 /// [`RoundingMode`] for a description of the possible rounding modes.
7939 ///
7940 /// $$
7941 /// f(x,y,z,m) = x+yz+\varepsilon.
7942 /// $$
7943 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7944 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7945 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
7946 /// [`Float`]s.
7947 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7948 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input
7949 /// [`Float`]s.
7950 ///
7951 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
7952 ///
7953 /// Special cases:
7954 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
7955 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
7956 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
7957 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
7958 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
7959 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
7960 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
7961 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
7962 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
7963 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
7964 /// [`Rational`] counting as positive.
7965 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
7966 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
7967 ///
7968 /// Overflow and underflow:
7969 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
7970 /// returned instead.
7971 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
7972 /// is returned instead, where `p` is the precision of the output.
7973 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
7974 /// returned instead.
7975 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
7976 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
7977 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
7978 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
7979 /// instead.
7980 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
7981 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
7982 /// instead.
7983 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
7984 /// instead.
7985 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
7986 /// instead.
7987 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
7988 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
7989 /// returned instead.
7990 ///
7991 /// If you want to specify an output precision, consider using
7992 /// [`Float::add_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
7993 /// rounding mode, consider using
7994 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
7995 ///
7996 /// # Worst-case complexity
7997 /// $T(n, m) = O(n \log n \log\log n + m)$
7998 ///
7999 /// $M(n, m) = O(n \log n + m)$
8000 ///
8001 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8002 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8003 ///
8004 /// # Panics
8005 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
8006 /// enough to represent the output.
8007 ///
8008 /// # Examples
8009 /// ```
8010 /// use core::f64::consts::{E, PI};
8011 /// use malachite_base::rounding_modes::RoundingMode::*;
8012 /// use malachite_float::Float;
8013 /// use malachite_q::Rational;
8014 /// use std::cmp::Ordering::*;
8015 ///
8016 /// let x = Float::from(PI);
8017 /// let y = Float::from(E);
8018 /// let z = Rational::from_signeds(1, 3);
8019 ///
8020 /// let (sum, o) = x.add_mul_rational_round_ref_val_ref(y.clone(), &z, Floor);
8021 /// assert_eq!(sum.to_string(), "4.0476865964094744");
8022 /// assert_eq!(o, Less);
8023 ///
8024 /// let (sum, o) = x.add_mul_rational_round_ref_val_ref(y.clone(), &z, Ceiling);
8025 /// assert_eq!(sum.to_string(), "4.0476865964094753");
8026 /// assert_eq!(o, Greater);
8027 ///
8028 /// let (sum, o) = x.add_mul_rational_round_ref_val_ref(y.clone(), &z, Nearest);
8029 /// assert_eq!(sum.to_string(), "4.0476865964094753");
8030 /// assert_eq!(o, Greater);
8031 /// ```
8032 #[allow(clippy::needless_pass_by_value)]
8033 #[inline]
8034 pub fn add_mul_rational_round_ref_val_ref(
8035 &self,
8036 y: Self,
8037 z: &Rational,
8038 rm: RoundingMode,
8039 ) -> (Self, Ordering) {
8040 let prec = max(self.significant_bits(), y.significant_bits());
8041 self.add_mul_rational_prec_round_ref_val_ref(y, z, prec, rm)
8042 }
8043
8044 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
8045 /// result with the specified rounding mode. The [`Float`]s are taken by reference and the
8046 /// [`Rational`] by value. An [`Ordering`] is also returned, indicating whether the rounded sum
8047 /// is less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
8048 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
8049 ///
8050 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8051 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
8052 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8053 ///
8054 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
8055 /// [`RoundingMode`] for a description of the possible rounding modes.
8056 ///
8057 /// $$
8058 /// f(x,y,z,m) = x+yz+\varepsilon.
8059 /// $$
8060 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8061 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
8062 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
8063 /// [`Float`]s.
8064 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
8065 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input
8066 /// [`Float`]s.
8067 ///
8068 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8069 ///
8070 /// Special cases:
8071 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
8072 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
8073 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
8074 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
8075 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
8076 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
8077 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
8078 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
8079 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
8080 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
8081 /// [`Rational`] counting as positive.
8082 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
8083 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
8084 ///
8085 /// Overflow and underflow:
8086 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
8087 /// returned instead.
8088 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
8089 /// is returned instead, where `p` is the precision of the output.
8090 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
8091 /// returned instead.
8092 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
8093 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
8094 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
8095 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
8096 /// instead.
8097 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
8098 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
8099 /// instead.
8100 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
8101 /// instead.
8102 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
8103 /// instead.
8104 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
8105 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
8106 /// returned instead.
8107 ///
8108 /// If you want to specify an output precision, consider using
8109 /// [`Float::add_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
8110 /// rounding mode, consider using
8111 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
8112 ///
8113 /// # Worst-case complexity
8114 /// $T(n, m) = O(n \log n \log\log n + m)$
8115 ///
8116 /// $M(n, m) = O(n \log n + m)$
8117 ///
8118 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8119 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8120 ///
8121 /// # Panics
8122 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
8123 /// enough to represent the output.
8124 ///
8125 /// # Examples
8126 /// ```
8127 /// use core::f64::consts::{E, PI};
8128 /// use malachite_base::rounding_modes::RoundingMode::*;
8129 /// use malachite_float::Float;
8130 /// use malachite_q::Rational;
8131 /// use std::cmp::Ordering::*;
8132 ///
8133 /// let x = Float::from(PI);
8134 /// let y = Float::from(E);
8135 /// let z = Rational::from_signeds(1, 3);
8136 ///
8137 /// let (sum, o) = x.add_mul_rational_round_ref_ref_val(&y, z.clone(), Floor);
8138 /// assert_eq!(sum.to_string(), "4.0476865964094744");
8139 /// assert_eq!(o, Less);
8140 ///
8141 /// let (sum, o) = x.add_mul_rational_round_ref_ref_val(&y, z.clone(), Ceiling);
8142 /// assert_eq!(sum.to_string(), "4.0476865964094753");
8143 /// assert_eq!(o, Greater);
8144 ///
8145 /// let (sum, o) = x.add_mul_rational_round_ref_ref_val(&y, z.clone(), Nearest);
8146 /// assert_eq!(sum.to_string(), "4.0476865964094753");
8147 /// assert_eq!(o, Greater);
8148 /// ```
8149 #[allow(clippy::needless_pass_by_value)]
8150 #[inline]
8151 pub fn add_mul_rational_round_ref_ref_val(
8152 &self,
8153 y: &Self,
8154 z: Rational,
8155 rm: RoundingMode,
8156 ) -> (Self, Ordering) {
8157 let prec = max(self.significant_bits(), y.significant_bits());
8158 self.add_mul_rational_prec_round_ref_ref_val(y, z, prec, rm)
8159 }
8160
8161 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], rounding the
8162 /// result with the specified rounding mode. The [`Float`]s and the [`Rational`] are all taken
8163 /// by reference. An [`Ordering`] is also returned, indicating whether the rounded sum is less
8164 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
8165 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
8166 ///
8167 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8168 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
8169 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8170 ///
8171 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
8172 /// [`RoundingMode`] for a description of the possible rounding modes.
8173 ///
8174 /// $$
8175 /// f(x,y,z,m) = x+yz+\varepsilon.
8176 /// $$
8177 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8178 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
8179 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
8180 /// [`Float`]s.
8181 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
8182 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input
8183 /// [`Float`]s.
8184 ///
8185 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8186 ///
8187 /// Special cases:
8188 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
8189 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
8190 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
8191 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
8192 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
8193 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
8194 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=\infty$
8195 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=-\infty$
8196 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
8197 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
8198 /// [`Rational`] counting as positive.
8199 /// - $f(x,y,z,m)=0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
8200 /// - $f(x,y,z,m)=-0.0$ if $x=-yz$, $x$ is finite and nonzero, and $m$ is `Floor`
8201 ///
8202 /// Overflow and underflow:
8203 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
8204 /// returned instead.
8205 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
8206 /// is returned instead, where `p` is the precision of the output.
8207 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
8208 /// returned instead.
8209 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
8210 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
8211 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
8212 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
8213 /// instead.
8214 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
8215 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
8216 /// instead.
8217 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
8218 /// instead.
8219 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
8220 /// instead.
8221 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
8222 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
8223 /// returned instead.
8224 ///
8225 /// If you want to specify an output precision, consider using
8226 /// [`Float::add_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
8227 /// rounding mode, consider using
8228 /// [`add_mul`](malachite_base::num::arithmetic::traits::AddMul::add_mul) instead.
8229 ///
8230 /// # Worst-case complexity
8231 /// $T(n, m) = O(n \log n \log\log n + m)$
8232 ///
8233 /// $M(n, m) = O(n \log n + m)$
8234 ///
8235 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8236 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8237 ///
8238 /// # Panics
8239 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
8240 /// enough to represent the output.
8241 ///
8242 /// # Examples
8243 /// ```
8244 /// use core::f64::consts::{E, PI};
8245 /// use malachite_base::rounding_modes::RoundingMode::*;
8246 /// use malachite_float::Float;
8247 /// use malachite_q::Rational;
8248 /// use std::cmp::Ordering::*;
8249 ///
8250 /// let x = Float::from(PI);
8251 /// let y = Float::from(E);
8252 /// let z = Rational::from_signeds(1, 3);
8253 ///
8254 /// let (sum, o) = x.add_mul_rational_round_ref_ref_ref(&y, &z, Floor);
8255 /// assert_eq!(sum.to_string(), "4.0476865964094744");
8256 /// assert_eq!(o, Less);
8257 ///
8258 /// let (sum, o) = x.add_mul_rational_round_ref_ref_ref(&y, &z, Ceiling);
8259 /// assert_eq!(sum.to_string(), "4.0476865964094753");
8260 /// assert_eq!(o, Greater);
8261 ///
8262 /// let (sum, o) = x.add_mul_rational_round_ref_ref_ref(&y, &z, Nearest);
8263 /// assert_eq!(sum.to_string(), "4.0476865964094753");
8264 /// assert_eq!(o, Greater);
8265 /// ```
8266 #[inline]
8267 pub fn add_mul_rational_round_ref_ref_ref(
8268 &self,
8269 y: &Self,
8270 z: &Rational,
8271 rm: RoundingMode,
8272 ) -> (Self, Ordering) {
8273 let prec = max(self.significant_bits(), y.significant_bits());
8274 self.add_mul_rational_prec_round_ref_ref_ref(y, z, prec, rm)
8275 }
8276
8277 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place, rounding the
8278 /// result with the specified rounding mode. The [`Float`] and the [`Rational`] on the
8279 /// right-hand side are both taken by value. An [`Ordering`] is returned, indicating whether the
8280 /// rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
8281 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
8282 ///
8283 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8284 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
8285 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8286 ///
8287 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
8288 /// [`RoundingMode`] for a description of the possible rounding modes.
8289 ///
8290 /// $$
8291 /// x \gets x+yz+\varepsilon.
8292 /// $$
8293 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8294 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
8295 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
8296 /// [`Float`]s.
8297 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
8298 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input
8299 /// [`Float`]s.
8300 ///
8301 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
8302 /// cases, overflow, and underflow.
8303 ///
8304 /// If you want to specify an output precision, consider using
8305 /// [`Float::add_mul_rational_prec_round_assign`] instead. If you know you'll be using the
8306 /// `Nearest` rounding mode, consider using
8307 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
8308 /// instead.
8309 ///
8310 /// # Worst-case complexity
8311 /// $T(n, m) = O(n \log n \log\log n + m)$
8312 ///
8313 /// $M(n, m) = O(n \log n + m)$
8314 ///
8315 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8316 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8317 ///
8318 /// # Panics
8319 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
8320 /// enough to represent the output.
8321 ///
8322 /// # Examples
8323 /// ```
8324 /// use core::f64::consts::{E, PI};
8325 /// use malachite_base::rounding_modes::RoundingMode::*;
8326 /// use malachite_float::Float;
8327 /// use malachite_q::Rational;
8328 /// use std::cmp::Ordering::*;
8329 ///
8330 /// let y = Float::from(E);
8331 /// let z = Rational::from_signeds(1, 3);
8332 ///
8333 /// let mut x = Float::from(PI);
8334 /// assert_eq!(
8335 /// x.add_mul_rational_round_assign(y.clone(), z.clone(), Floor),
8336 /// Less
8337 /// );
8338 /// assert_eq!(x.to_string(), "4.0476865964094744");
8339 ///
8340 /// let mut x = Float::from(PI);
8341 /// assert_eq!(
8342 /// x.add_mul_rational_round_assign(y.clone(), z.clone(), Ceiling),
8343 /// Greater
8344 /// );
8345 /// assert_eq!(x.to_string(), "4.0476865964094753");
8346 ///
8347 /// let mut x = Float::from(PI);
8348 /// assert_eq!(
8349 /// x.add_mul_rational_round_assign(y.clone(), z.clone(), Nearest),
8350 /// Greater
8351 /// );
8352 /// assert_eq!(x.to_string(), "4.0476865964094753");
8353 /// ```
8354 #[allow(clippy::needless_pass_by_value)]
8355 #[inline]
8356 pub fn add_mul_rational_round_assign(
8357 &mut self,
8358 y: Self,
8359 z: Rational,
8360 rm: RoundingMode,
8361 ) -> Ordering {
8362 let prec = max(self.significant_bits(), y.significant_bits());
8363 self.add_mul_rational_prec_round_assign(y, z, prec, rm)
8364 }
8365
8366 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place, rounding the
8367 /// result with the specified rounding mode. The [`Float`] on the right-hand side is taken by
8368 /// value and the [`Rational`] by reference. An [`Ordering`] is returned, indicating whether the
8369 /// rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
8370 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
8371 ///
8372 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8373 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
8374 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8375 ///
8376 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
8377 /// [`RoundingMode`] for a description of the possible rounding modes.
8378 ///
8379 /// $$
8380 /// x \gets x+yz+\varepsilon.
8381 /// $$
8382 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8383 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
8384 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
8385 /// [`Float`]s.
8386 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
8387 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input
8388 /// [`Float`]s.
8389 ///
8390 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
8391 /// cases, overflow, and underflow.
8392 ///
8393 /// If you want to specify an output precision, consider using
8394 /// [`Float::add_mul_rational_prec_round_assign`] instead. If you know you'll be using the
8395 /// `Nearest` rounding mode, consider using
8396 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
8397 /// instead.
8398 ///
8399 /// # Worst-case complexity
8400 /// $T(n, m) = O(n \log n \log\log n + m)$
8401 ///
8402 /// $M(n, m) = O(n \log n + m)$
8403 ///
8404 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8405 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8406 ///
8407 /// # Panics
8408 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
8409 /// enough to represent the output.
8410 ///
8411 /// # Examples
8412 /// ```
8413 /// use core::f64::consts::{E, PI};
8414 /// use malachite_base::rounding_modes::RoundingMode::*;
8415 /// use malachite_float::Float;
8416 /// use malachite_q::Rational;
8417 /// use std::cmp::Ordering::*;
8418 ///
8419 /// let y = Float::from(E);
8420 /// let z = Rational::from_signeds(1, 3);
8421 ///
8422 /// let mut x = Float::from(PI);
8423 /// assert_eq!(
8424 /// x.add_mul_rational_round_assign_val_ref(y.clone(), &z, Floor),
8425 /// Less
8426 /// );
8427 /// assert_eq!(x.to_string(), "4.0476865964094744");
8428 ///
8429 /// let mut x = Float::from(PI);
8430 /// assert_eq!(
8431 /// x.add_mul_rational_round_assign_val_ref(y.clone(), &z, Ceiling),
8432 /// Greater
8433 /// );
8434 /// assert_eq!(x.to_string(), "4.0476865964094753");
8435 ///
8436 /// let mut x = Float::from(PI);
8437 /// assert_eq!(
8438 /// x.add_mul_rational_round_assign_val_ref(y.clone(), &z, Nearest),
8439 /// Greater
8440 /// );
8441 /// assert_eq!(x.to_string(), "4.0476865964094753");
8442 /// ```
8443 #[allow(clippy::needless_pass_by_value)]
8444 #[inline]
8445 pub fn add_mul_rational_round_assign_val_ref(
8446 &mut self,
8447 y: Self,
8448 z: &Rational,
8449 rm: RoundingMode,
8450 ) -> Ordering {
8451 let prec = max(self.significant_bits(), y.significant_bits());
8452 self.add_mul_rational_prec_round_assign_val_ref(y, z, prec, rm)
8453 }
8454
8455 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place, rounding the
8456 /// result with the specified rounding mode. The [`Float`] on the right-hand side is taken by
8457 /// reference and the [`Rational`] by value. An [`Ordering`] is returned, indicating whether the
8458 /// rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
8459 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
8460 ///
8461 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8462 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
8463 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8464 ///
8465 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
8466 /// [`RoundingMode`] for a description of the possible rounding modes.
8467 ///
8468 /// $$
8469 /// x \gets x+yz+\varepsilon.
8470 /// $$
8471 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8472 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
8473 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
8474 /// [`Float`]s.
8475 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
8476 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input
8477 /// [`Float`]s.
8478 ///
8479 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
8480 /// cases, overflow, and underflow.
8481 ///
8482 /// If you want to specify an output precision, consider using
8483 /// [`Float::add_mul_rational_prec_round_assign`] instead. If you know you'll be using the
8484 /// `Nearest` rounding mode, consider using
8485 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
8486 /// instead.
8487 ///
8488 /// # Worst-case complexity
8489 /// $T(n, m) = O(n \log n \log\log n + m)$
8490 ///
8491 /// $M(n, m) = O(n \log n + m)$
8492 ///
8493 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8494 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8495 ///
8496 /// # Panics
8497 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
8498 /// enough to represent the output.
8499 ///
8500 /// # Examples
8501 /// ```
8502 /// use core::f64::consts::{E, PI};
8503 /// use malachite_base::rounding_modes::RoundingMode::*;
8504 /// use malachite_float::Float;
8505 /// use malachite_q::Rational;
8506 /// use std::cmp::Ordering::*;
8507 ///
8508 /// let y = Float::from(E);
8509 /// let z = Rational::from_signeds(1, 3);
8510 ///
8511 /// let mut x = Float::from(PI);
8512 /// assert_eq!(
8513 /// x.add_mul_rational_round_assign_ref_val(&y, z.clone(), Floor),
8514 /// Less
8515 /// );
8516 /// assert_eq!(x.to_string(), "4.0476865964094744");
8517 ///
8518 /// let mut x = Float::from(PI);
8519 /// assert_eq!(
8520 /// x.add_mul_rational_round_assign_ref_val(&y, z.clone(), Ceiling),
8521 /// Greater
8522 /// );
8523 /// assert_eq!(x.to_string(), "4.0476865964094753");
8524 ///
8525 /// let mut x = Float::from(PI);
8526 /// assert_eq!(
8527 /// x.add_mul_rational_round_assign_ref_val(&y, z.clone(), Nearest),
8528 /// Greater
8529 /// );
8530 /// assert_eq!(x.to_string(), "4.0476865964094753");
8531 /// ```
8532 #[allow(clippy::needless_pass_by_value)]
8533 #[inline]
8534 pub fn add_mul_rational_round_assign_ref_val(
8535 &mut self,
8536 y: &Self,
8537 z: Rational,
8538 rm: RoundingMode,
8539 ) -> Ordering {
8540 let prec = max(self.significant_bits(), y.significant_bits());
8541 self.add_mul_rational_prec_round_assign_ref_val(y, z, prec, rm)
8542 }
8543
8544 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place, rounding the
8545 /// result with the specified rounding mode. The [`Float`] and the [`Rational`] on the
8546 /// right-hand side are both taken by reference. An [`Ordering`] is returned, indicating whether
8547 /// the rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are
8548 /// not comparable to any [`Float`], whenever this function assigns a `NaN` it also returns
8549 /// `Equal`.
8550 ///
8551 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8552 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
8553 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8554 ///
8555 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
8556 /// [`RoundingMode`] for a description of the possible rounding modes.
8557 ///
8558 /// $$
8559 /// x \gets x+yz+\varepsilon.
8560 /// $$
8561 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8562 /// - If $x+yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
8563 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
8564 /// [`Float`]s.
8565 /// - If $x+yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
8566 /// 2^{\lfloor\log_2 |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input
8567 /// [`Float`]s.
8568 ///
8569 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
8570 /// cases, overflow, and underflow.
8571 ///
8572 /// If you want to specify an output precision, consider using
8573 /// [`Float::add_mul_rational_prec_round_assign`] instead. If you know you'll be using the
8574 /// `Nearest` rounding mode, consider using
8575 /// [`add_mul_assign`](malachite_base::num::arithmetic::traits::AddMulAssign::add_mul_assign)
8576 /// instead.
8577 ///
8578 /// # Worst-case complexity
8579 /// $T(n, m) = O(n \log n \log\log n + m)$
8580 ///
8581 /// $M(n, m) = O(n \log n + m)$
8582 ///
8583 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8584 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8585 ///
8586 /// # Panics
8587 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
8588 /// enough to represent the output.
8589 ///
8590 /// # Examples
8591 /// ```
8592 /// use core::f64::consts::{E, PI};
8593 /// use malachite_base::rounding_modes::RoundingMode::*;
8594 /// use malachite_float::Float;
8595 /// use malachite_q::Rational;
8596 /// use std::cmp::Ordering::*;
8597 ///
8598 /// let y = Float::from(E);
8599 /// let z = Rational::from_signeds(1, 3);
8600 ///
8601 /// let mut x = Float::from(PI);
8602 /// assert_eq!(x.add_mul_rational_round_assign_ref_ref(&y, &z, Floor), Less);
8603 /// assert_eq!(x.to_string(), "4.0476865964094744");
8604 ///
8605 /// let mut x = Float::from(PI);
8606 /// assert_eq!(
8607 /// x.add_mul_rational_round_assign_ref_ref(&y, &z, Ceiling),
8608 /// Greater
8609 /// );
8610 /// assert_eq!(x.to_string(), "4.0476865964094753");
8611 ///
8612 /// let mut x = Float::from(PI);
8613 /// assert_eq!(
8614 /// x.add_mul_rational_round_assign_ref_ref(&y, &z, Nearest),
8615 /// Greater
8616 /// );
8617 /// assert_eq!(x.to_string(), "4.0476865964094753");
8618 /// ```
8619 #[inline]
8620 pub fn add_mul_rational_round_assign_ref_ref(
8621 &mut self,
8622 y: &Self,
8623 z: &Rational,
8624 rm: RoundingMode,
8625 ) -> Ordering {
8626 let prec = max(self.significant_bits(), y.significant_bits());
8627 self.add_mul_rational_prec_round_assign_ref_ref(y, z, prec, rm)
8628 }
8629}
8630
8631impl AddMul<Self, Rational> for Float {
8632 type Output = Self;
8633 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], taking all three
8634 /// by value.
8635 ///
8636 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8637 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
8638 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8639 ///
8640 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8641 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8642 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8643 /// the `Nearest` rounding mode.
8644 ///
8645 /// $$
8646 /// f(x,y,z) = x+yz+\varepsilon.
8647 /// $$
8648 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8649 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8650 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8651 ///
8652 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8653 ///
8654 /// Special cases:
8655 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
8656 /// - $f(x,\pm\infty,0)=\text{NaN}$
8657 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
8658 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
8659 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
8660 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
8661 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
8662 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
8663 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
8664 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
8665 /// [`Rational`] counting as positive.
8666 /// - $f(x,y,z)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
8667 ///
8668 /// Overflow and underflow:
8669 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8670 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8671 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8672 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8673 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
8674 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8675 ///
8676 /// If you want to use a rounding mode other than `Nearest`, consider using
8677 /// [`Float::add_mul_rational_round`]. If you want to specify the output precision, consider
8678 /// using [`Float::add_mul_rational_prec`]. If you want both of these things, consider using
8679 /// [`Float::add_mul_rational_prec_round`].
8680 ///
8681 /// # Worst-case complexity
8682 /// $T(n, m) = O(n \log n \log\log n + m)$
8683 ///
8684 /// $M(n, m) = O(n \log n + m)$
8685 ///
8686 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8687 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8688 ///
8689 /// # Examples
8690 /// ```
8691 /// use core::f64::consts::{E, PI};
8692 /// use malachite_base::num::arithmetic::traits::AddMul;
8693 /// use malachite_float::Float;
8694 /// use malachite_q::Rational;
8695 ///
8696 /// let x = Float::from(PI);
8697 /// let y = Float::from(E);
8698 /// let z = Rational::from_signeds(1, 3);
8699 /// assert_eq!(x.add_mul(y, z).to_string(), "4.0476865964094753");
8700 /// ```
8701 #[inline]
8702 fn add_mul(self, y: Self, z: Rational) -> Self {
8703 let prec = max(self.significant_bits(), y.significant_bits());
8704 self.add_mul_rational_prec(y, z, prec).0
8705 }
8706}
8707
8708impl AddMul<Self, &Rational> for Float {
8709 type Output = Self;
8710 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], taking the
8711 /// [`Float`]s by value and the [`Rational`] by reference.
8712 ///
8713 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8714 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
8715 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8716 ///
8717 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8718 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8719 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8720 /// the `Nearest` rounding mode.
8721 ///
8722 /// $$
8723 /// f(x,y,z) = x+yz+\varepsilon.
8724 /// $$
8725 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8726 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8727 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8728 ///
8729 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8730 ///
8731 /// Special cases:
8732 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
8733 /// - $f(x,\pm\infty,0)=\text{NaN}$
8734 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
8735 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
8736 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
8737 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
8738 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
8739 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
8740 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
8741 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
8742 /// [`Rational`] counting as positive.
8743 /// - $f(x,y,z)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
8744 ///
8745 /// Overflow and underflow:
8746 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8747 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8748 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8749 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8750 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
8751 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8752 ///
8753 /// If you want to use a rounding mode other than `Nearest`, consider using
8754 /// [`Float::add_mul_rational_round`]. If you want to specify the output precision, consider
8755 /// using [`Float::add_mul_rational_prec`]. If you want both of these things, consider using
8756 /// [`Float::add_mul_rational_prec_round`].
8757 ///
8758 /// # Worst-case complexity
8759 /// $T(n, m) = O(n \log n \log\log n + m)$
8760 ///
8761 /// $M(n, m) = O(n \log n + m)$
8762 ///
8763 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8764 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8765 ///
8766 /// # Examples
8767 /// ```
8768 /// use core::f64::consts::{E, PI};
8769 /// use malachite_base::num::arithmetic::traits::AddMul;
8770 /// use malachite_float::Float;
8771 /// use malachite_q::Rational;
8772 ///
8773 /// let x = Float::from(PI);
8774 /// let y = Float::from(E);
8775 /// let z = Rational::from_signeds(1, 3);
8776 /// assert_eq!(x.add_mul(y, &z).to_string(), "4.0476865964094753");
8777 /// ```
8778 #[inline]
8779 fn add_mul(self, y: Self, z: &Rational) -> Self {
8780 let prec = max(self.significant_bits(), y.significant_bits());
8781 self.add_mul_rational_prec_val_val_ref(y, z, prec).0
8782 }
8783}
8784
8785impl AddMul<&Self, Rational> for Float {
8786 type Output = Self;
8787 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], taking the first
8788 /// [`Float`] and the [`Rational`] by value and the second [`Float`] by reference.
8789 ///
8790 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8791 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
8792 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8793 ///
8794 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8795 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8796 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8797 /// the `Nearest` rounding mode.
8798 ///
8799 /// $$
8800 /// f(x,y,z) = x+yz+\varepsilon.
8801 /// $$
8802 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8803 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8804 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8805 ///
8806 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8807 ///
8808 /// Special cases:
8809 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
8810 /// - $f(x,\pm\infty,0)=\text{NaN}$
8811 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
8812 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
8813 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
8814 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
8815 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
8816 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
8817 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
8818 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
8819 /// [`Rational`] counting as positive.
8820 /// - $f(x,y,z)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
8821 ///
8822 /// Overflow and underflow:
8823 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8824 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8825 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8826 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8827 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
8828 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8829 ///
8830 /// If you want to use a rounding mode other than `Nearest`, consider using
8831 /// [`Float::add_mul_rational_round`]. If you want to specify the output precision, consider
8832 /// using [`Float::add_mul_rational_prec`]. If you want both of these things, consider using
8833 /// [`Float::add_mul_rational_prec_round`].
8834 ///
8835 /// # Worst-case complexity
8836 /// $T(n, m) = O(n \log n \log\log n + m)$
8837 ///
8838 /// $M(n, m) = O(n \log n + m)$
8839 ///
8840 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8841 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8842 ///
8843 /// # Examples
8844 /// ```
8845 /// use core::f64::consts::{E, PI};
8846 /// use malachite_base::num::arithmetic::traits::AddMul;
8847 /// use malachite_float::Float;
8848 /// use malachite_q::Rational;
8849 ///
8850 /// let x = Float::from(PI);
8851 /// let y = Float::from(E);
8852 /// let z = Rational::from_signeds(1, 3);
8853 /// assert_eq!(x.add_mul(&y, z).to_string(), "4.0476865964094753");
8854 /// ```
8855 #[inline]
8856 fn add_mul(self, y: &Self, z: Rational) -> Self {
8857 let prec = max(self.significant_bits(), y.significant_bits());
8858 self.add_mul_rational_prec_val_ref_val(y, z, prec).0
8859 }
8860}
8861
8862impl AddMul<&Self, &Rational> for Float {
8863 type Output = Self;
8864 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], taking the first
8865 /// [`Float`] by value and the second [`Float`] and the [`Rational`] by reference.
8866 ///
8867 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8868 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
8869 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8870 ///
8871 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8872 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8873 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8874 /// the `Nearest` rounding mode.
8875 ///
8876 /// $$
8877 /// f(x,y,z) = x+yz+\varepsilon.
8878 /// $$
8879 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8880 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8881 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8882 ///
8883 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8884 ///
8885 /// Special cases:
8886 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
8887 /// - $f(x,\pm\infty,0)=\text{NaN}$
8888 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
8889 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
8890 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
8891 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
8892 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
8893 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
8894 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
8895 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
8896 /// [`Rational`] counting as positive.
8897 /// - $f(x,y,z)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
8898 ///
8899 /// Overflow and underflow:
8900 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8901 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8902 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8903 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8904 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
8905 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8906 ///
8907 /// If you want to use a rounding mode other than `Nearest`, consider using
8908 /// [`Float::add_mul_rational_round`]. If you want to specify the output precision, consider
8909 /// using [`Float::add_mul_rational_prec`]. If you want both of these things, consider using
8910 /// [`Float::add_mul_rational_prec_round`].
8911 ///
8912 /// # Worst-case complexity
8913 /// $T(n, m) = O(n \log n \log\log n + m)$
8914 ///
8915 /// $M(n, m) = O(n \log n + m)$
8916 ///
8917 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8918 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8919 ///
8920 /// # Examples
8921 /// ```
8922 /// use core::f64::consts::{E, PI};
8923 /// use malachite_base::num::arithmetic::traits::AddMul;
8924 /// use malachite_float::Float;
8925 /// use malachite_q::Rational;
8926 ///
8927 /// let x = Float::from(PI);
8928 /// let y = Float::from(E);
8929 /// let z = Rational::from_signeds(1, 3);
8930 /// assert_eq!(x.add_mul(&y, &z).to_string(), "4.0476865964094753");
8931 /// ```
8932 #[inline]
8933 fn add_mul(self, y: &Self, z: &Rational) -> Self {
8934 let prec = max(self.significant_bits(), y.significant_bits());
8935 self.add_mul_rational_prec_val_ref_ref(y, z, prec).0
8936 }
8937}
8938
8939impl AddMul<Float, Rational> for &Float {
8940 type Output = Float;
8941 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], taking the first
8942 /// [`Float`] by reference and the second [`Float`] and the [`Rational`] by value.
8943 ///
8944 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8945 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
8946 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8947 ///
8948 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8949 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8950 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8951 /// the `Nearest` rounding mode.
8952 ///
8953 /// $$
8954 /// f(x,y,z) = x+yz+\varepsilon.
8955 /// $$
8956 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8957 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8958 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8959 ///
8960 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8961 ///
8962 /// Special cases:
8963 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
8964 /// - $f(x,\pm\infty,0)=\text{NaN}$
8965 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
8966 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
8967 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
8968 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
8969 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
8970 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
8971 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
8972 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
8973 /// [`Rational`] counting as positive.
8974 /// - $f(x,y,z)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
8975 ///
8976 /// Overflow and underflow:
8977 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8978 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8979 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8980 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8981 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
8982 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8983 ///
8984 /// If you want to use a rounding mode other than `Nearest`, consider using
8985 /// [`Float::add_mul_rational_round`]. If you want to specify the output precision, consider
8986 /// using [`Float::add_mul_rational_prec`]. If you want both of these things, consider using
8987 /// [`Float::add_mul_rational_prec_round`].
8988 ///
8989 /// # Worst-case complexity
8990 /// $T(n, m) = O(n \log n \log\log n + m)$
8991 ///
8992 /// $M(n, m) = O(n \log n + m)$
8993 ///
8994 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8995 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8996 ///
8997 /// # Examples
8998 /// ```
8999 /// use core::f64::consts::{E, PI};
9000 /// use malachite_base::num::arithmetic::traits::AddMul;
9001 /// use malachite_float::Float;
9002 /// use malachite_q::Rational;
9003 ///
9004 /// let x = Float::from(PI);
9005 /// let y = Float::from(E);
9006 /// let z = Rational::from_signeds(1, 3);
9007 /// assert_eq!(&x.add_mul(y, z).to_string(), "4.0476865964094753");
9008 /// ```
9009 #[inline]
9010 fn add_mul(self, y: Float, z: Rational) -> Float {
9011 let prec = max(self.significant_bits(), y.significant_bits());
9012 self.add_mul_rational_prec_ref_val_val(y, z, prec).0
9013 }
9014}
9015
9016impl AddMul<Float, &Rational> for &Float {
9017 type Output = Float;
9018 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], taking the second
9019 /// [`Float`] by value and the first [`Float`] and the [`Rational`] by reference.
9020 ///
9021 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
9022 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
9023 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
9024 ///
9025 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9026 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
9027 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
9028 /// the `Nearest` rounding mode.
9029 ///
9030 /// $$
9031 /// f(x,y,z) = x+yz+\varepsilon.
9032 /// $$
9033 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9034 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
9035 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
9036 ///
9037 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9038 ///
9039 /// Special cases:
9040 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
9041 /// - $f(x,\pm\infty,0)=\text{NaN}$
9042 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
9043 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
9044 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
9045 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
9046 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
9047 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
9048 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
9049 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
9050 /// [`Rational`] counting as positive.
9051 /// - $f(x,y,z)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
9052 ///
9053 /// Overflow and underflow:
9054 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
9055 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
9056 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
9057 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
9058 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
9059 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
9060 ///
9061 /// If you want to use a rounding mode other than `Nearest`, consider using
9062 /// [`Float::add_mul_rational_round`]. If you want to specify the output precision, consider
9063 /// using [`Float::add_mul_rational_prec`]. If you want both of these things, consider using
9064 /// [`Float::add_mul_rational_prec_round`].
9065 ///
9066 /// # Worst-case complexity
9067 /// $T(n, m) = O(n \log n \log\log n + m)$
9068 ///
9069 /// $M(n, m) = O(n \log n + m)$
9070 ///
9071 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9072 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
9073 ///
9074 /// # Examples
9075 /// ```
9076 /// use core::f64::consts::{E, PI};
9077 /// use malachite_base::num::arithmetic::traits::AddMul;
9078 /// use malachite_float::Float;
9079 /// use malachite_q::Rational;
9080 ///
9081 /// let x = Float::from(PI);
9082 /// let y = Float::from(E);
9083 /// let z = Rational::from_signeds(1, 3);
9084 /// assert_eq!(&x.add_mul(y, &z).to_string(), "4.0476865964094753");
9085 /// ```
9086 #[inline]
9087 fn add_mul(self, y: Float, z: &Rational) -> Float {
9088 let prec = max(self.significant_bits(), y.significant_bits());
9089 self.add_mul_rational_prec_ref_val_ref(y, z, prec).0
9090 }
9091}
9092
9093impl AddMul<&Float, Rational> for &Float {
9094 type Output = Float;
9095 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], taking the
9096 /// [`Float`]s by reference and the [`Rational`] by value.
9097 ///
9098 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
9099 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
9100 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
9101 ///
9102 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9103 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
9104 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
9105 /// the `Nearest` rounding mode.
9106 ///
9107 /// $$
9108 /// f(x,y,z) = x+yz+\varepsilon.
9109 /// $$
9110 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9111 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
9112 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
9113 ///
9114 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9115 ///
9116 /// Special cases:
9117 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
9118 /// - $f(x,\pm\infty,0)=\text{NaN}$
9119 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
9120 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
9121 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
9122 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
9123 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
9124 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
9125 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
9126 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
9127 /// [`Rational`] counting as positive.
9128 /// - $f(x,y,z)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
9129 ///
9130 /// Overflow and underflow:
9131 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
9132 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
9133 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
9134 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
9135 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
9136 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
9137 ///
9138 /// If you want to use a rounding mode other than `Nearest`, consider using
9139 /// [`Float::add_mul_rational_round`]. If you want to specify the output precision, consider
9140 /// using [`Float::add_mul_rational_prec`]. If you want both of these things, consider using
9141 /// [`Float::add_mul_rational_prec_round`].
9142 ///
9143 /// # Worst-case complexity
9144 /// $T(n, m) = O(n \log n \log\log n + m)$
9145 ///
9146 /// $M(n, m) = O(n \log n + m)$
9147 ///
9148 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9149 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
9150 ///
9151 /// # Examples
9152 /// ```
9153 /// use core::f64::consts::{E, PI};
9154 /// use malachite_base::num::arithmetic::traits::AddMul;
9155 /// use malachite_float::Float;
9156 /// use malachite_q::Rational;
9157 ///
9158 /// let x = Float::from(PI);
9159 /// let y = Float::from(E);
9160 /// let z = Rational::from_signeds(1, 3);
9161 /// assert_eq!(&x.add_mul(&y, z).to_string(), "4.0476865964094753");
9162 /// ```
9163 #[inline]
9164 fn add_mul(self, y: &Float, z: Rational) -> Float {
9165 let prec = max(self.significant_bits(), y.significant_bits());
9166 self.add_mul_rational_prec_ref_ref_val(y, z, prec).0
9167 }
9168}
9169
9170impl AddMul<&Float, &Rational> for &Float {
9171 type Output = Float;
9172 /// Adds a [`Float`] and the product of another [`Float`] and a [`Rational`], taking all three
9173 /// by reference.
9174 ///
9175 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
9176 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
9177 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
9178 ///
9179 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9180 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
9181 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
9182 /// the `Nearest` rounding mode.
9183 ///
9184 /// $$
9185 /// f(x,y,z) = x+yz+\varepsilon.
9186 /// $$
9187 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9188 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
9189 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
9190 ///
9191 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9192 ///
9193 /// Special cases:
9194 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
9195 /// - $f(x,\pm\infty,0)=\text{NaN}$
9196 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=-\infty$
9197 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=\infty$
9198 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
9199 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq\infty$
9200 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=\infty$
9201 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=-\infty$
9202 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply;
9203 /// the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a zero
9204 /// [`Rational`] counting as positive.
9205 /// - $f(x,y,z)=0.0$ if $x=-yz$ and $x$ is finite and nonzero
9206 ///
9207 /// Overflow and underflow:
9208 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
9209 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
9210 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
9211 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
9212 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
9213 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
9214 ///
9215 /// If you want to use a rounding mode other than `Nearest`, consider using
9216 /// [`Float::add_mul_rational_round`]. If you want to specify the output precision, consider
9217 /// using [`Float::add_mul_rational_prec`]. If you want both of these things, consider using
9218 /// [`Float::add_mul_rational_prec_round`].
9219 ///
9220 /// # Worst-case complexity
9221 /// $T(n, m) = O(n \log n \log\log n + m)$
9222 ///
9223 /// $M(n, m) = O(n \log n + m)$
9224 ///
9225 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9226 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
9227 ///
9228 /// # Examples
9229 /// ```
9230 /// use core::f64::consts::{E, PI};
9231 /// use malachite_base::num::arithmetic::traits::AddMul;
9232 /// use malachite_float::Float;
9233 /// use malachite_q::Rational;
9234 ///
9235 /// let x = Float::from(PI);
9236 /// let y = Float::from(E);
9237 /// let z = Rational::from_signeds(1, 3);
9238 /// assert_eq!(&x.add_mul(&y, &z).to_string(), "4.0476865964094753");
9239 /// ```
9240 #[inline]
9241 fn add_mul(self, y: &Float, z: &Rational) -> Float {
9242 let prec = max(self.significant_bits(), y.significant_bits());
9243 self.add_mul_rational_prec_ref_ref_ref(y, z, prec).0
9244 }
9245}
9246
9247impl AddMulAssign<Self, Rational> for Float {
9248 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place. The [`Float`]
9249 /// and the [`Rational`] on the right-hand side are both taken by value.
9250 ///
9251 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
9252 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
9253 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
9254 ///
9255 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9256 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
9257 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
9258 /// the `Nearest` rounding mode.
9259 ///
9260 /// $$
9261 /// x \gets x+yz+\varepsilon.
9262 /// $$
9263 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9264 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
9265 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
9266 ///
9267 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
9268 /// cases, overflow, and underflow.
9269 ///
9270 /// If you want to use a rounding mode other than `Nearest`, consider using
9271 /// [`Float::add_mul_rational_round_assign`]. If you want to specify the output precision,
9272 /// consider using [`Float::add_mul_rational_prec_assign`]. If you want both of these things,
9273 /// consider using [`Float::add_mul_rational_prec_round_assign`].
9274 ///
9275 /// # Worst-case complexity
9276 /// $T(n, m) = O(n \log n \log\log n + m)$
9277 ///
9278 /// $M(n, m) = O(n \log n + m)$
9279 ///
9280 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9281 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
9282 ///
9283 /// # Examples
9284 /// ```
9285 /// use core::f64::consts::{E, PI};
9286 /// use malachite_base::num::arithmetic::traits::AddMulAssign;
9287 /// use malachite_float::Float;
9288 /// use malachite_q::Rational;
9289 ///
9290 /// let mut x = Float::from(PI);
9291 /// let y = Float::from(E);
9292 /// let z = Rational::from_signeds(1, 3);
9293 /// x.add_mul_assign(y, z);
9294 /// assert_eq!(x.to_string(), "4.0476865964094753");
9295 /// ```
9296 #[inline]
9297 fn add_mul_assign(&mut self, y: Self, z: Rational) {
9298 let prec = max(self.significant_bits(), y.significant_bits());
9299 self.add_mul_rational_prec_assign(y, z, prec);
9300 }
9301}
9302
9303impl AddMulAssign<Self, &Rational> for Float {
9304 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place. The [`Float`] on
9305 /// the right-hand side is taken by value and the [`Rational`] by reference.
9306 ///
9307 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
9308 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
9309 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
9310 ///
9311 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9312 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
9313 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
9314 /// the `Nearest` rounding mode.
9315 ///
9316 /// $$
9317 /// x \gets x+yz+\varepsilon.
9318 /// $$
9319 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9320 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
9321 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
9322 ///
9323 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
9324 /// cases, overflow, and underflow.
9325 ///
9326 /// If you want to use a rounding mode other than `Nearest`, consider using
9327 /// [`Float::add_mul_rational_round_assign`]. If you want to specify the output precision,
9328 /// consider using [`Float::add_mul_rational_prec_assign`]. If you want both of these things,
9329 /// consider using [`Float::add_mul_rational_prec_round_assign`].
9330 ///
9331 /// # Worst-case complexity
9332 /// $T(n, m) = O(n \log n \log\log n + m)$
9333 ///
9334 /// $M(n, m) = O(n \log n + m)$
9335 ///
9336 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9337 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
9338 ///
9339 /// # Examples
9340 /// ```
9341 /// use core::f64::consts::{E, PI};
9342 /// use malachite_base::num::arithmetic::traits::AddMulAssign;
9343 /// use malachite_float::Float;
9344 /// use malachite_q::Rational;
9345 ///
9346 /// let mut x = Float::from(PI);
9347 /// let y = Float::from(E);
9348 /// let z = Rational::from_signeds(1, 3);
9349 /// x.add_mul_assign(y, &z);
9350 /// assert_eq!(x.to_string(), "4.0476865964094753");
9351 /// ```
9352 #[inline]
9353 fn add_mul_assign(&mut self, y: Self, z: &Rational) {
9354 let prec = max(self.significant_bits(), y.significant_bits());
9355 self.add_mul_rational_prec_assign_val_ref(y, z, prec);
9356 }
9357}
9358
9359impl AddMulAssign<&Self, Rational> for Float {
9360 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place. The [`Float`] on
9361 /// the right-hand side is taken by reference and the [`Rational`] by value.
9362 ///
9363 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
9364 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
9365 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
9366 ///
9367 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9368 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
9369 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
9370 /// the `Nearest` rounding mode.
9371 ///
9372 /// $$
9373 /// x \gets x+yz+\varepsilon.
9374 /// $$
9375 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9376 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
9377 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
9378 ///
9379 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
9380 /// cases, overflow, and underflow.
9381 ///
9382 /// If you want to use a rounding mode other than `Nearest`, consider using
9383 /// [`Float::add_mul_rational_round_assign`]. If you want to specify the output precision,
9384 /// consider using [`Float::add_mul_rational_prec_assign`]. If you want both of these things,
9385 /// consider using [`Float::add_mul_rational_prec_round_assign`].
9386 ///
9387 /// # Worst-case complexity
9388 /// $T(n, m) = O(n \log n \log\log n + m)$
9389 ///
9390 /// $M(n, m) = O(n \log n + m)$
9391 ///
9392 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9393 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
9394 ///
9395 /// # Examples
9396 /// ```
9397 /// use core::f64::consts::{E, PI};
9398 /// use malachite_base::num::arithmetic::traits::AddMulAssign;
9399 /// use malachite_float::Float;
9400 /// use malachite_q::Rational;
9401 ///
9402 /// let mut x = Float::from(PI);
9403 /// let y = Float::from(E);
9404 /// let z = Rational::from_signeds(1, 3);
9405 /// x.add_mul_assign(&y, z);
9406 /// assert_eq!(x.to_string(), "4.0476865964094753");
9407 /// ```
9408 #[inline]
9409 fn add_mul_assign(&mut self, y: &Self, z: Rational) {
9410 let prec = max(self.significant_bits(), y.significant_bits());
9411 self.add_mul_rational_prec_assign_ref_val(y, z, prec);
9412 }
9413}
9414
9415impl AddMulAssign<&Self, &Rational> for Float {
9416 /// Adds the product of a [`Float`] and a [`Rational`] to a [`Float`] in place. The [`Float`]
9417 /// and the [`Rational`] on the right-hand side are both taken by reference.
9418 ///
9419 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
9420 /// first, so the result is the true value of $x+yz$ with a single rounding at the end. Rounding
9421 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
9422 ///
9423 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9424 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
9425 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
9426 /// the `Nearest` rounding mode.
9427 ///
9428 /// $$
9429 /// x \gets x+yz+\varepsilon.
9430 /// $$
9431 /// - If $x+yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9432 /// - If $x+yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
9433 /// |x+yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
9434 ///
9435 /// See the [`Float::add_mul_rational_prec_round`] documentation for information on special
9436 /// cases, overflow, and underflow.
9437 ///
9438 /// If you want to use a rounding mode other than `Nearest`, consider using
9439 /// [`Float::add_mul_rational_round_assign`]. If you want to specify the output precision,
9440 /// consider using [`Float::add_mul_rational_prec_assign`]. If you want both of these things,
9441 /// consider using [`Float::add_mul_rational_prec_round_assign`].
9442 ///
9443 /// # Worst-case complexity
9444 /// $T(n, m) = O(n \log n \log\log n + m)$
9445 ///
9446 /// $M(n, m) = O(n \log n + m)$
9447 ///
9448 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9449 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
9450 ///
9451 /// # Examples
9452 /// ```
9453 /// use core::f64::consts::{E, PI};
9454 /// use malachite_base::num::arithmetic::traits::AddMulAssign;
9455 /// use malachite_float::Float;
9456 /// use malachite_q::Rational;
9457 ///
9458 /// let mut x = Float::from(PI);
9459 /// let y = Float::from(E);
9460 /// let z = Rational::from_signeds(1, 3);
9461 /// x.add_mul_assign(&y, &z);
9462 /// assert_eq!(x.to_string(), "4.0476865964094753");
9463 /// ```
9464 #[inline]
9465 fn add_mul_assign(&mut self, y: &Self, z: &Rational) {
9466 let prec = max(self.significant_bits(), y.significant_bits());
9467 self.add_mul_rational_prec_assign_ref_ref(y, z, prec);
9468 }
9469}
9470
9471/// Adds a primitive float and the product of two other primitive floats with a single rounding,
9472/// using emulated [`Float`] arithmetic.
9473///
9474/// This is a correctly-rounded fused multiply-add: the product is not rounded before the addition,
9475/// so the result is the true value of $x+yz$ rounded once to the nearest representable value. It
9476/// agrees with the standard library's hardware-backed `mul_add`, up to argument order.
9477///
9478/// # Worst-case complexity
9479/// Constant time and additional memory.
9480///
9481/// # Examples
9482/// ```
9483/// use core::f64::consts::{E, PI, SQRT_2};
9484/// use malachite_base::num::float::NiceFloat;
9485/// use malachite_float::float::arithmetic::add_mul::*;
9486///
9487/// assert_eq!(
9488/// NiceFloat(primitive_float_add_mul(PI, E, SQRT_2)),
9489/// NiceFloat(6.98582368174891)
9490/// );
9491/// ```
9492#[allow(clippy::type_repetition_in_bounds)]
9493#[inline]
9494pub fn primitive_float_add_mul<T: PrimitiveFloat>(x: T, y: T, z: T) -> T
9495where
9496 Float: From<T> + PartialOrd<T>,
9497 for<'a> T: ExactFrom<&'a Float>,
9498{
9499 emulate_float_float_float_to_float_fn(Float::add_mul_prec, x, y, z)
9500}
9501
9502/// Adds a primitive float and the product of another primitive float and a [`Rational`], with a
9503/// single rounding, using emulated [`Float`] arithmetic.
9504///
9505/// The [`Rational`] multiplicand enters the product exactly, and the result is the true value of
9506/// $x+yz$ rounded once to the nearest representable value.
9507///
9508/// # Worst-case complexity
9509/// $T(n) = O(n \log n \log\log n)$
9510///
9511/// $M(n) = O(n \log n)$
9512///
9513/// where $T$ is time, $M$ is additional memory, and $n$ is `z.significant_bits()`.
9514///
9515/// # Examples
9516/// ```
9517/// use core::f64::consts::{E, PI};
9518/// use malachite_base::num::float::NiceFloat;
9519/// use malachite_float::float::arithmetic::add_mul::*;
9520/// use malachite_q::Rational;
9521///
9522/// assert_eq!(
9523/// NiceFloat(primitive_float_add_mul_rational(
9524/// PI,
9525/// E,
9526/// &Rational::from_signeds(1, 3)
9527/// )),
9528/// NiceFloat(4.047686596409475)
9529/// );
9530/// ```
9531#[allow(clippy::type_repetition_in_bounds)]
9532#[inline]
9533pub fn primitive_float_add_mul_rational<T: PrimitiveFloat>(x: T, y: T, z: &Rational) -> T
9534where
9535 Float: From<T> + PartialOrd<T>,
9536 for<'a> T: ExactFrom<&'a Float>,
9537{
9538 emulate_float_float_to_float_fn(
9539 |x, y, prec| x.add_mul_rational_prec_val_val_ref(y, z, prec),
9540 x,
9541 y,
9542 )
9543}