malachite_float/float/arithmetic/mul_add_mul.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MPFR Library.
4//
5// Copyright © 2016-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::float::arithmetic::add_mul::{add_scaled_round, float_sign};
15use crate::{
16 Float, emulate_float_float_float_float_to_float_fn, emulate_float_float_float_to_float_fn,
17 float_either_infinity, float_either_zero, float_infinity, float_nan, float_negative_infinity,
18 significand_bits,
19};
20use core::cmp::Ordering::{self, Equal};
21use malachite_base::max;
22use malachite_base::num::arithmetic::traits::{MulAddMul, MulAddMulAssign};
23use malachite_base::num::basic::floats::PrimitiveFloat;
24use malachite_base::num::basic::traits::{NegativeZero, One, Zero as ZeroTrait};
25use malachite_base::num::conversion::traits::ExactFrom;
26use malachite_base::num::logic::traits::SignificantBits;
27use malachite_base::rounding_modes::RoundingMode::{self, Floor, Nearest};
28use malachite_nz::natural::Natural;
29use malachite_q::Rational;
30
31// This is mpfr_fmma and mpfr_fmms from fmma.c, MPFR 4.2.2, with the result's precision passed
32// explicitly; `neg` distinguishes the two, as in the C code's mpfr_fmma_aux. The result is a * b +
33// c * d (or a * b - c * d if `neg` is true), rounded to `prec` bits with rounding mode `rm`.
34//
35// Where the C code computes both products exactly as UBFs (unbounded floats) and lets an
36// unbounded-exponent mpfr_add resolve every case, here the products are computed at prec(a) +
37// prec(b) and prec(c) + prec(d) bits, which is exact unless a product's exponent leaves the
38// representable range; the sum is then a single rounded addition. When a product does leave the
39// range, both products are formed at the integer level and `add_scaled_round` performs the single
40// rounding, standing in for the UBF machinery as in `add_mul_helper`. The C code's equal-precision
41// shortcut through mpfr_set_1_2 is a performance spelling of the same computation and is omitted.
42// The singular cases, which the C code delegates to the UBF product and addition rules, are spelled
43// out explicitly and follow those rules: any NaN operand or any infinity-times-zero product is NaN,
44// infinite products dominate (with opposite infinite products giving NaN), and the sign rules for
45// zero products are those of Float addition.
46pub(crate) fn mul_add_mul_helper(
47 a: &Float,
48 b: &Float,
49 c: &Float,
50 d: &Float,
51 neg: bool,
52 prec: u64,
53 rm: RoundingMode,
54) -> (Float, Ordering) {
55 assert_ne!(prec, 0);
56 if a.is_nan() || b.is_nan() || c.is_nan() || d.is_nan() {
57 return (float_nan!(), Equal);
58 }
59 let inf_zero = |x: &Float, y: &Float| {
60 matches!(x, float_either_infinity!()) && matches!(y, float_either_zero!())
61 };
62 if inf_zero(a, b) || inf_zero(b, a) || inf_zero(c, d) || inf_zero(d, c) {
63 return (float_nan!(), Equal);
64 }
65 let s1 = float_sign(a) == float_sign(b);
66 let s2 = (float_sign(c) == float_sign(d)) != neg;
67 let p1_inf = a.is_infinite() || b.is_infinite();
68 let p2_inf = c.is_infinite() || d.is_infinite();
69 if p1_inf || p2_inf {
70 return if p1_inf && p2_inf && s1 != s2 {
71 (float_nan!(), Equal)
72 } else {
73 let sp = if p1_inf { s1 } else { s2 };
74 (
75 if sp {
76 float_infinity!()
77 } else {
78 float_negative_infinity!()
79 },
80 Equal,
81 )
82 };
83 }
84 let p1_zero = matches!(a, float_either_zero!()) || matches!(b, float_either_zero!());
85 let p2_zero = matches!(c, float_either_zero!()) || matches!(d, float_either_zero!());
86 if p1_zero && p2_zero {
87 // two zero products: positive unless both are negative, except under Floor, where it is
88 // negative unless both are positive (the sign rules of Float addition)
89 let sign = if rm == Floor { s1 && s2 } else { s1 || s2 };
90 return (
91 if sign {
92 Float::ZERO
93 } else {
94 Float::NEGATIVE_ZERO
95 },
96 Equal,
97 );
98 }
99 if p1_zero {
100 // the result is the rounded second product; a negated product is computed via the negation
101 // identity
102 return if neg {
103 let (p, o) = c.mul_prec_round_ref_ref(d, prec, -rm);
104 (-p, o.reverse())
105 } else {
106 c.mul_prec_round_ref_ref(d, prec, rm)
107 };
108 }
109 if p2_zero {
110 return a.mul_prec_round_ref_ref(b, prec, rm);
111 }
112 // At precisions prec(a) + prec(b) and prec(c) + prec(d) the products are exact unless their
113 // exponents leave the representable range.
114 let (
115 Float(Finite {
116 precision: a_prec, ..
117 }),
118 Float(Finite {
119 precision: b_prec, ..
120 }),
121 Float(Finite {
122 precision: c_prec, ..
123 }),
124 Float(Finite {
125 precision: d_prec, ..
126 }),
127 ) = (a, b, c, d)
128 else {
129 unreachable!()
130 };
131 let (u1, o1) = a.mul_prec_ref_ref(b, a_prec + b_prec);
132 let (u2, o2) = c.mul_prec_ref_ref(d, c_prec + d_prec);
133 if o1 == Equal && o2 == Equal {
134 let u2 = if neg { -u2 } else { u2 };
135 return u1.add_prec_round(u2, prec, rm);
136 }
137 // a product's exponent left the range: form both products at the integer level
138 let scaled = |x: &Float, y: &Float| {
139 let (
140 Float(Finite {
141 exponent: x_exponent,
142 significand: x_significand,
143 ..
144 }),
145 Float(Finite {
146 exponent: y_exponent,
147 significand: y_significand,
148 ..
149 }),
150 ) = (x, y)
151 else {
152 unreachable!()
153 };
154 (
155 x_significand * y_significand,
156 i64::from(*x_exponent) - i64::exact_from(significand_bits(x_significand))
157 + i64::from(*y_exponent)
158 - i64::exact_from(significand_bits(y_significand)),
159 )
160 };
161 let (m1, e1) = scaled(a, b);
162 let (m2, e2) = scaled(c, d);
163 add_scaled_round(s1, &m1, e1, s2, &m2, e2, &Natural::ONE, prec, rm)
164}
165
166// The mixed Float-Rational counterpart of `mul_add_mul_helper`: the result is x * y + z * w (or x *
167// y - z * w if `neg` is true) with the `Rational` w entering its product exactly, rounded to `prec`
168// bits with rounding mode `rm`. Pre-rounding w to a `Float` would perturb the result by z times the
169// conversion error; the identity xy + z(n/d) = (xyd + zn)/d keeps the whole computation exact until
170// the single rounding at the end, in `add_scaled_round`. Since a nonzero `Rational` is generally
171// not a dyadic, there is no exact-product fast path for the second product, and the first product
172// is formed at the integer level along with it.
173//
174// A `Rational` zero has no sign and is treated as a positive zero in the product's sign rules.
175pub(crate) fn mul_add_mul_rational_helper(
176 x: &Float,
177 y: &Float,
178 z: &Float,
179 w: &Rational,
180 neg: bool,
181 prec: u64,
182 rm: RoundingMode,
183) -> (Float, Ordering) {
184 assert_ne!(prec, 0);
185 if x.is_nan() || y.is_nan() || z.is_nan() {
186 return (float_nan!(), Equal);
187 }
188 let inf_zero = |u: &Float, v: &Float| {
189 matches!(u, float_either_infinity!()) && matches!(v, float_either_zero!())
190 };
191 if inf_zero(x, y) || inf_zero(y, x) || matches!(z, float_either_infinity!()) && *w == 0u32 {
192 return (float_nan!(), Equal);
193 }
194 let s1 = float_sign(x) == float_sign(y);
195 // a zero Rational counts as positive, so >= rather than > (for a nonzero w the two comparisons
196 // agree)
197 let s2 = (float_sign(z) == (*w >= 0u32)) != neg;
198 let p1_inf = x.is_infinite() || y.is_infinite();
199 let p2_inf = z.is_infinite();
200 if p1_inf || p2_inf {
201 return if p1_inf && p2_inf && s1 != s2 {
202 (float_nan!(), Equal)
203 } else {
204 let sp = if p1_inf { s1 } else { s2 };
205 (
206 if sp {
207 float_infinity!()
208 } else {
209 float_negative_infinity!()
210 },
211 Equal,
212 )
213 };
214 }
215 let p1_zero = matches!(x, float_either_zero!()) || matches!(y, float_either_zero!());
216 let p2_zero = matches!(z, float_either_zero!()) || *w == 0u32;
217 if p1_zero && p2_zero {
218 // two zero products: the sign rules of Float addition, a zero Rational counting as positive
219 let sign = if rm == Floor { s1 && s2 } else { s1 || s2 };
220 return (
221 if sign {
222 Float::ZERO
223 } else {
224 Float::NEGATIVE_ZERO
225 },
226 Equal,
227 );
228 }
229 if p1_zero {
230 // the result is the rounded second product; a negated product is computed via the negation
231 // identity
232 return if neg {
233 let (p, o) = z.mul_rational_prec_round_ref_ref(w, prec, -rm);
234 (-p, o.reverse())
235 } else {
236 z.mul_rational_prec_round_ref_ref(w, prec, rm)
237 };
238 }
239 if p2_zero {
240 return x.mul_prec_round_ref_ref(y, prec, rm);
241 }
242 // all operands are finite and nonzero: xy + z(n/d) = (xyd + zn)/d, formed exactly
243 let (
244 Float(Finite {
245 exponent: x_exponent,
246 significand: x_significand,
247 ..
248 }),
249 Float(Finite {
250 exponent: y_exponent,
251 significand: y_significand,
252 ..
253 }),
254 Float(Finite {
255 exponent: z_exponent,
256 significand: z_significand,
257 ..
258 }),
259 ) = (x, y, z)
260 else {
261 unreachable!()
262 };
263 let d = w.denominator_ref();
264 add_scaled_round(
265 s1,
266 &(x_significand * y_significand * d),
267 i64::from(*x_exponent) - i64::exact_from(significand_bits(x_significand))
268 + i64::from(*y_exponent)
269 - i64::exact_from(significand_bits(y_significand)),
270 s2,
271 &(z_significand * w.numerator_ref()),
272 i64::from(*z_exponent) - i64::exact_from(significand_bits(z_significand)),
273 d,
274 prec,
275 rm,
276 )
277}
278
279impl Float {
280 /// Adds the products of two pairs of [`Float`]s, rounding the result to the specified precision
281 /// and with the specified rounding mode; the products are not rounded before the final
282 /// addition, so there is a single rounding. All four [`Float`]s are taken by value. An
283 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
284 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
285 /// this function returns a `NaN` it also returns `Equal`.
286 ///
287 /// See [`RoundingMode`] for a description of the possible rounding modes.
288 ///
289 /// $$
290 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
291 /// $$
292 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
293 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
294 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
295 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
296 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
297 ///
298 /// If the output has a precision, it is `prec`.
299 ///
300 /// Special cases:
301 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
302 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
303 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
304 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
305 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
306 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
307 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
308 /// - If exactly one product is infinite, the result is that product's infinity.
309 /// - If both products are infinite, the result is their common infinity if their signs agree,
310 /// and `NaN` otherwise.
311 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
312 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
313 /// `Floor`
314 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
315 ///
316 /// Overflow and underflow:
317 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
318 /// returned instead.
319 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
320 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
321 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
322 /// returned instead.
323 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
324 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
325 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
326 /// instead.
327 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
328 /// instead.
329 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
330 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
331 /// returned instead.
332 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
333 /// instead.
334 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
335 /// instead.
336 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
337 /// instead.
338 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
339 /// returned instead.
340 ///
341 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec`] instead.
342 /// If you know that your target precision is the maximum of the precisions of the inputs,
343 /// consider using [`Float::mul_add_mul_round`] instead. If both of these things are true,
344 /// consider using
345 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
346 ///
347 /// # Worst-case complexity
348 /// $T(n, m) = O(n \log n \log\log n + m)$
349 ///
350 /// $M(n, m) = O(n \log n + m)$
351 ///
352 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
353 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
354 /// `max(self.significant_bits(), prec)`.
355 ///
356 /// # Panics
357 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
358 /// representable with `prec` bits.
359 ///
360 /// # Examples
361 /// ```
362 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
363 /// use malachite_base::rounding_modes::RoundingMode::*;
364 /// use malachite_float::Float;
365 /// use std::cmp::Ordering::*;
366 ///
367 /// let x = Float::from(PI);
368 /// let y = Float::from(E);
369 /// let z = Float::from(SQRT_2);
370 /// let w = Float::from(LN_2);
371 ///
372 /// let (sum, o) = x
373 /// .clone()
374 /// .mul_add_mul_prec_round(y.clone(), z.clone(), w.clone(), 5, Floor);
375 /// assert_eq!(sum.to_string(), "9.50");
376 /// assert_eq!(o, Less);
377 ///
378 /// let (sum, o) =
379 /// x.clone()
380 /// .mul_add_mul_prec_round(y.clone(), z.clone(), w.clone(), 5, Ceiling);
381 /// assert_eq!(sum.to_string(), "10.0");
382 /// assert_eq!(o, Greater);
383 ///
384 /// let (sum, o) =
385 /// x.clone()
386 /// .mul_add_mul_prec_round(y.clone(), z.clone(), w.clone(), 5, Nearest);
387 /// assert_eq!(sum.to_string(), "9.50");
388 /// assert_eq!(o, Less);
389 ///
390 /// let (sum, o) = x
391 /// .clone()
392 /// .mul_add_mul_prec_round(y.clone(), z.clone(), w.clone(), 20, Floor);
393 /// assert_eq!(sum.to_string(), "9.5199890");
394 /// assert_eq!(o, Less);
395 ///
396 /// let (sum, o) =
397 /// x.clone()
398 /// .mul_add_mul_prec_round(y.clone(), z.clone(), w.clone(), 20, Ceiling);
399 /// assert_eq!(sum.to_string(), "9.5200043");
400 /// assert_eq!(o, Greater);
401 ///
402 /// let (sum, o) =
403 /// x.clone()
404 /// .mul_add_mul_prec_round(y.clone(), z.clone(), w.clone(), 20, Nearest);
405 /// assert_eq!(sum.to_string(), "9.5199890");
406 /// assert_eq!(o, Less);
407 /// ```
408 #[allow(clippy::needless_pass_by_value)]
409 #[inline]
410 pub fn mul_add_mul_prec_round(
411 self,
412 y: Self,
413 z: Self,
414 w: Self,
415 prec: u64,
416 rm: RoundingMode,
417 ) -> (Self, Ordering) {
418 mul_add_mul_helper(&self, &y, &z, &w, false, prec, rm)
419 }
420
421 /// Adds the products of two pairs of [`Float`]s, rounding the result to the specified precision
422 /// and with the specified rounding mode; the products are not rounded before the final
423 /// addition, so there is a single rounding. The first three [`Float`]s are taken by value and
424 /// the fourth by reference. An [`Ordering`] is also returned, indicating whether the rounded
425 /// sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
426 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
427 ///
428 /// See [`RoundingMode`] for a description of the possible rounding modes.
429 ///
430 /// $$
431 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
432 /// $$
433 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
434 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
435 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
436 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
437 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
438 ///
439 /// If the output has a precision, it is `prec`.
440 ///
441 /// Special cases:
442 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
443 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
444 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
445 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
446 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
447 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
448 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
449 /// - If exactly one product is infinite, the result is that product's infinity.
450 /// - If both products are infinite, the result is their common infinity if their signs agree,
451 /// and `NaN` otherwise.
452 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
453 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
454 /// `Floor`
455 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
456 ///
457 /// Overflow and underflow:
458 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
459 /// returned instead.
460 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
461 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
462 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
463 /// returned instead.
464 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
465 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
466 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
467 /// instead.
468 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
469 /// instead.
470 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
471 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
472 /// returned instead.
473 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
474 /// instead.
475 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
476 /// instead.
477 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
478 /// instead.
479 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
480 /// returned instead.
481 ///
482 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec`] instead.
483 /// If you know that your target precision is the maximum of the precisions of the inputs,
484 /// consider using [`Float::mul_add_mul_round`] instead. If both of these things are true,
485 /// consider using
486 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
487 ///
488 /// # Worst-case complexity
489 /// $T(n, m) = O(n \log n \log\log n + m)$
490 ///
491 /// $M(n, m) = O(n \log n + m)$
492 ///
493 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
494 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
495 /// `max(self.significant_bits(), prec)`.
496 ///
497 /// # Panics
498 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
499 /// representable with `prec` bits.
500 ///
501 /// # Examples
502 /// ```
503 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
504 /// use malachite_base::rounding_modes::RoundingMode::*;
505 /// use malachite_float::Float;
506 /// use std::cmp::Ordering::*;
507 ///
508 /// let x = Float::from(PI);
509 /// let y = Float::from(E);
510 /// let z = Float::from(SQRT_2);
511 /// let w = Float::from(LN_2);
512 ///
513 /// let (sum, o) =
514 /// x.clone()
515 /// .mul_add_mul_prec_round_val_val_val_ref(y.clone(), z.clone(), &w, 5, Floor);
516 /// assert_eq!(sum.to_string(), "9.50");
517 /// assert_eq!(o, Less);
518 ///
519 /// let (sum, o) =
520 /// x.clone()
521 /// .mul_add_mul_prec_round_val_val_val_ref(y.clone(), z.clone(), &w, 5, Ceiling);
522 /// assert_eq!(sum.to_string(), "10.0");
523 /// assert_eq!(o, Greater);
524 ///
525 /// let (sum, o) =
526 /// x.clone()
527 /// .mul_add_mul_prec_round_val_val_val_ref(y.clone(), z.clone(), &w, 5, Nearest);
528 /// assert_eq!(sum.to_string(), "9.50");
529 /// assert_eq!(o, Less);
530 ///
531 /// let (sum, o) =
532 /// x.clone()
533 /// .mul_add_mul_prec_round_val_val_val_ref(y.clone(), z.clone(), &w, 20, Floor);
534 /// assert_eq!(sum.to_string(), "9.5199890");
535 /// assert_eq!(o, Less);
536 ///
537 /// let (sum, o) =
538 /// x.clone()
539 /// .mul_add_mul_prec_round_val_val_val_ref(y.clone(), z.clone(), &w, 20, Ceiling);
540 /// assert_eq!(sum.to_string(), "9.5200043");
541 /// assert_eq!(o, Greater);
542 ///
543 /// let (sum, o) =
544 /// x.clone()
545 /// .mul_add_mul_prec_round_val_val_val_ref(y.clone(), z.clone(), &w, 20, Nearest);
546 /// assert_eq!(sum.to_string(), "9.5199890");
547 /// assert_eq!(o, Less);
548 /// ```
549 #[allow(clippy::needless_pass_by_value)]
550 #[inline]
551 pub fn mul_add_mul_prec_round_val_val_val_ref(
552 self,
553 y: Self,
554 z: Self,
555 w: &Self,
556 prec: u64,
557 rm: RoundingMode,
558 ) -> (Self, Ordering) {
559 mul_add_mul_helper(&self, &y, &z, w, false, prec, rm)
560 }
561
562 /// Adds the products of two pairs of [`Float`]s, rounding the result to the specified precision
563 /// and with the specified rounding mode; the products are not rounded before the final
564 /// addition, so there is a single rounding. The third [`Float`] is taken by reference and the
565 /// others by value. An [`Ordering`] is also returned, indicating whether the rounded sum is
566 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
567 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
568 ///
569 /// See [`RoundingMode`] for a description of the possible rounding modes.
570 ///
571 /// $$
572 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
573 /// $$
574 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
575 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
576 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
577 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
578 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
579 ///
580 /// If the output has a precision, it is `prec`.
581 ///
582 /// Special cases:
583 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
584 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
585 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
586 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
587 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
588 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
589 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
590 /// - If exactly one product is infinite, the result is that product's infinity.
591 /// - If both products are infinite, the result is their common infinity if their signs agree,
592 /// and `NaN` otherwise.
593 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
594 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
595 /// `Floor`
596 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
597 ///
598 /// Overflow and underflow:
599 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
600 /// returned instead.
601 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
602 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
603 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
604 /// returned instead.
605 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
606 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
607 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
608 /// instead.
609 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
610 /// instead.
611 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
612 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
613 /// returned instead.
614 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
615 /// instead.
616 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
617 /// instead.
618 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
619 /// instead.
620 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
621 /// returned instead.
622 ///
623 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec`] instead.
624 /// If you know that your target precision is the maximum of the precisions of the inputs,
625 /// consider using [`Float::mul_add_mul_round`] instead. If both of these things are true,
626 /// consider using
627 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
628 ///
629 /// # Worst-case complexity
630 /// $T(n, m) = O(n \log n \log\log n + m)$
631 ///
632 /// $M(n, m) = O(n \log n + m)$
633 ///
634 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
635 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
636 /// `max(self.significant_bits(), prec)`.
637 ///
638 /// # Panics
639 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
640 /// representable with `prec` bits.
641 ///
642 /// # Examples
643 /// ```
644 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
645 /// use malachite_base::rounding_modes::RoundingMode::*;
646 /// use malachite_float::Float;
647 /// use std::cmp::Ordering::*;
648 ///
649 /// let x = Float::from(PI);
650 /// let y = Float::from(E);
651 /// let z = Float::from(SQRT_2);
652 /// let w = Float::from(LN_2);
653 ///
654 /// let (sum, o) =
655 /// x.clone()
656 /// .mul_add_mul_prec_round_val_val_ref_val(y.clone(), &z, w.clone(), 5, Floor);
657 /// assert_eq!(sum.to_string(), "9.50");
658 /// assert_eq!(o, Less);
659 ///
660 /// let (sum, o) =
661 /// x.clone()
662 /// .mul_add_mul_prec_round_val_val_ref_val(y.clone(), &z, w.clone(), 5, Ceiling);
663 /// assert_eq!(sum.to_string(), "10.0");
664 /// assert_eq!(o, Greater);
665 ///
666 /// let (sum, o) =
667 /// x.clone()
668 /// .mul_add_mul_prec_round_val_val_ref_val(y.clone(), &z, w.clone(), 5, Nearest);
669 /// assert_eq!(sum.to_string(), "9.50");
670 /// assert_eq!(o, Less);
671 ///
672 /// let (sum, o) =
673 /// x.clone()
674 /// .mul_add_mul_prec_round_val_val_ref_val(y.clone(), &z, w.clone(), 20, Floor);
675 /// assert_eq!(sum.to_string(), "9.5199890");
676 /// assert_eq!(o, Less);
677 ///
678 /// let (sum, o) =
679 /// x.clone()
680 /// .mul_add_mul_prec_round_val_val_ref_val(y.clone(), &z, w.clone(), 20, Ceiling);
681 /// assert_eq!(sum.to_string(), "9.5200043");
682 /// assert_eq!(o, Greater);
683 ///
684 /// let (sum, o) =
685 /// x.clone()
686 /// .mul_add_mul_prec_round_val_val_ref_val(y.clone(), &z, w.clone(), 20, Nearest);
687 /// assert_eq!(sum.to_string(), "9.5199890");
688 /// assert_eq!(o, Less);
689 /// ```
690 #[allow(clippy::needless_pass_by_value)]
691 #[inline]
692 pub fn mul_add_mul_prec_round_val_val_ref_val(
693 self,
694 y: Self,
695 z: &Self,
696 w: Self,
697 prec: u64,
698 rm: RoundingMode,
699 ) -> (Self, Ordering) {
700 mul_add_mul_helper(&self, &y, z, &w, false, prec, rm)
701 }
702
703 /// Adds the products of two pairs of [`Float`]s, rounding the result to the specified precision
704 /// and with the specified rounding mode; the products are not rounded before the final
705 /// addition, so there is a single rounding. The first two [`Float`]s are taken by value and the
706 /// last two by reference. An [`Ordering`] is also returned, indicating whether the rounded sum
707 /// is less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
708 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
709 ///
710 /// See [`RoundingMode`] for a description of the possible rounding modes.
711 ///
712 /// $$
713 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
714 /// $$
715 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
716 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
717 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
718 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
719 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
720 ///
721 /// If the output has a precision, it is `prec`.
722 ///
723 /// Special cases:
724 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
725 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
726 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
727 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
728 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
729 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
730 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
731 /// - If exactly one product is infinite, the result is that product's infinity.
732 /// - If both products are infinite, the result is their common infinity if their signs agree,
733 /// and `NaN` otherwise.
734 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
735 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
736 /// `Floor`
737 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
738 ///
739 /// Overflow and underflow:
740 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
741 /// returned instead.
742 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
743 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
744 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
745 /// returned instead.
746 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
747 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
748 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
749 /// instead.
750 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
751 /// instead.
752 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
753 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
754 /// returned instead.
755 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
756 /// instead.
757 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
758 /// instead.
759 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
760 /// instead.
761 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
762 /// returned instead.
763 ///
764 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec`] instead.
765 /// If you know that your target precision is the maximum of the precisions of the inputs,
766 /// consider using [`Float::mul_add_mul_round`] instead. If both of these things are true,
767 /// consider using
768 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
769 ///
770 /// # Worst-case complexity
771 /// $T(n, m) = O(n \log n \log\log n + m)$
772 ///
773 /// $M(n, m) = O(n \log n + m)$
774 ///
775 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
776 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
777 /// `max(self.significant_bits(), prec)`.
778 ///
779 /// # Panics
780 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
781 /// representable with `prec` bits.
782 ///
783 /// # Examples
784 /// ```
785 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
786 /// use malachite_base::rounding_modes::RoundingMode::*;
787 /// use malachite_float::Float;
788 /// use std::cmp::Ordering::*;
789 ///
790 /// let x = Float::from(PI);
791 /// let y = Float::from(E);
792 /// let z = Float::from(SQRT_2);
793 /// let w = Float::from(LN_2);
794 ///
795 /// let (sum, o) =
796 /// x.clone()
797 /// .mul_add_mul_prec_round_val_val_ref_ref(y.clone(), &z, &w, 5, Floor);
798 /// assert_eq!(sum.to_string(), "9.50");
799 /// assert_eq!(o, Less);
800 ///
801 /// let (sum, o) =
802 /// x.clone()
803 /// .mul_add_mul_prec_round_val_val_ref_ref(y.clone(), &z, &w, 5, Ceiling);
804 /// assert_eq!(sum.to_string(), "10.0");
805 /// assert_eq!(o, Greater);
806 ///
807 /// let (sum, o) =
808 /// x.clone()
809 /// .mul_add_mul_prec_round_val_val_ref_ref(y.clone(), &z, &w, 5, Nearest);
810 /// assert_eq!(sum.to_string(), "9.50");
811 /// assert_eq!(o, Less);
812 ///
813 /// let (sum, o) =
814 /// x.clone()
815 /// .mul_add_mul_prec_round_val_val_ref_ref(y.clone(), &z, &w, 20, Floor);
816 /// assert_eq!(sum.to_string(), "9.5199890");
817 /// assert_eq!(o, Less);
818 ///
819 /// let (sum, o) =
820 /// x.clone()
821 /// .mul_add_mul_prec_round_val_val_ref_ref(y.clone(), &z, &w, 20, Ceiling);
822 /// assert_eq!(sum.to_string(), "9.5200043");
823 /// assert_eq!(o, Greater);
824 ///
825 /// let (sum, o) =
826 /// x.clone()
827 /// .mul_add_mul_prec_round_val_val_ref_ref(y.clone(), &z, &w, 20, Nearest);
828 /// assert_eq!(sum.to_string(), "9.5199890");
829 /// assert_eq!(o, Less);
830 /// ```
831 #[allow(clippy::needless_pass_by_value)]
832 #[inline]
833 pub fn mul_add_mul_prec_round_val_val_ref_ref(
834 self,
835 y: Self,
836 z: &Self,
837 w: &Self,
838 prec: u64,
839 rm: RoundingMode,
840 ) -> (Self, Ordering) {
841 mul_add_mul_helper(&self, &y, z, w, false, prec, rm)
842 }
843
844 /// Adds the products of two pairs of [`Float`]s, rounding the result to the specified precision
845 /// and with the specified rounding mode; the products are not rounded before the final
846 /// addition, so there is a single rounding. The second [`Float`] is taken by reference and the
847 /// others by value. An [`Ordering`] is also returned, indicating whether the rounded sum is
848 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
849 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
850 ///
851 /// See [`RoundingMode`] for a description of the possible rounding modes.
852 ///
853 /// $$
854 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
855 /// $$
856 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
857 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
858 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
859 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
860 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
861 ///
862 /// If the output has a precision, it is `prec`.
863 ///
864 /// Special cases:
865 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
866 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
867 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
868 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
869 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
870 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
871 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
872 /// - If exactly one product is infinite, the result is that product's infinity.
873 /// - If both products are infinite, the result is their common infinity if their signs agree,
874 /// and `NaN` otherwise.
875 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
876 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
877 /// `Floor`
878 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
879 ///
880 /// Overflow and underflow:
881 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
882 /// returned instead.
883 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
884 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
885 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
886 /// returned instead.
887 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
888 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
889 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
890 /// instead.
891 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
892 /// instead.
893 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
894 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
895 /// returned instead.
896 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
897 /// instead.
898 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
899 /// instead.
900 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
901 /// instead.
902 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
903 /// returned instead.
904 ///
905 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec`] instead.
906 /// If you know that your target precision is the maximum of the precisions of the inputs,
907 /// consider using [`Float::mul_add_mul_round`] instead. If both of these things are true,
908 /// consider using
909 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
910 ///
911 /// # Worst-case complexity
912 /// $T(n, m) = O(n \log n \log\log n + m)$
913 ///
914 /// $M(n, m) = O(n \log n + m)$
915 ///
916 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
917 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
918 /// `max(self.significant_bits(), prec)`.
919 ///
920 /// # Panics
921 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
922 /// representable with `prec` bits.
923 ///
924 /// # Examples
925 /// ```
926 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
927 /// use malachite_base::rounding_modes::RoundingMode::*;
928 /// use malachite_float::Float;
929 /// use std::cmp::Ordering::*;
930 ///
931 /// let x = Float::from(PI);
932 /// let y = Float::from(E);
933 /// let z = Float::from(SQRT_2);
934 /// let w = Float::from(LN_2);
935 ///
936 /// let (sum, o) =
937 /// x.clone()
938 /// .mul_add_mul_prec_round_val_ref_val_val(&y, z.clone(), w.clone(), 5, Floor);
939 /// assert_eq!(sum.to_string(), "9.50");
940 /// assert_eq!(o, Less);
941 ///
942 /// let (sum, o) =
943 /// x.clone()
944 /// .mul_add_mul_prec_round_val_ref_val_val(&y, z.clone(), w.clone(), 5, Ceiling);
945 /// assert_eq!(sum.to_string(), "10.0");
946 /// assert_eq!(o, Greater);
947 ///
948 /// let (sum, o) =
949 /// x.clone()
950 /// .mul_add_mul_prec_round_val_ref_val_val(&y, z.clone(), w.clone(), 5, Nearest);
951 /// assert_eq!(sum.to_string(), "9.50");
952 /// assert_eq!(o, Less);
953 ///
954 /// let (sum, o) =
955 /// x.clone()
956 /// .mul_add_mul_prec_round_val_ref_val_val(&y, z.clone(), w.clone(), 20, Floor);
957 /// assert_eq!(sum.to_string(), "9.5199890");
958 /// assert_eq!(o, Less);
959 ///
960 /// let (sum, o) =
961 /// x.clone()
962 /// .mul_add_mul_prec_round_val_ref_val_val(&y, z.clone(), w.clone(), 20, Ceiling);
963 /// assert_eq!(sum.to_string(), "9.5200043");
964 /// assert_eq!(o, Greater);
965 ///
966 /// let (sum, o) =
967 /// x.clone()
968 /// .mul_add_mul_prec_round_val_ref_val_val(&y, z.clone(), w.clone(), 20, Nearest);
969 /// assert_eq!(sum.to_string(), "9.5199890");
970 /// assert_eq!(o, Less);
971 /// ```
972 #[allow(clippy::needless_pass_by_value)]
973 #[inline]
974 pub fn mul_add_mul_prec_round_val_ref_val_val(
975 self,
976 y: &Self,
977 z: Self,
978 w: Self,
979 prec: u64,
980 rm: RoundingMode,
981 ) -> (Self, Ordering) {
982 mul_add_mul_helper(&self, y, &z, &w, false, prec, rm)
983 }
984
985 /// Adds the products of two pairs of [`Float`]s, rounding the result to the specified precision
986 /// and with the specified rounding mode; the products are not rounded before the final
987 /// addition, so there is a single rounding. The second and fourth [`Float`]s are taken by
988 /// reference and the others by value. An [`Ordering`] is also returned, indicating whether the
989 /// rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
990 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
991 ///
992 /// See [`RoundingMode`] for a description of the possible rounding modes.
993 ///
994 /// $$
995 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
996 /// $$
997 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
998 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
999 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
1000 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1001 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
1002 ///
1003 /// If the output has a precision, it is `prec`.
1004 ///
1005 /// Special cases:
1006 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1007 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1008 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1009 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1010 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1011 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1012 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
1013 /// - If exactly one product is infinite, the result is that product's infinity.
1014 /// - If both products are infinite, the result is their common infinity if their signs agree,
1015 /// and `NaN` otherwise.
1016 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
1017 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
1018 /// `Floor`
1019 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
1020 ///
1021 /// Overflow and underflow:
1022 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1023 /// returned instead.
1024 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
1025 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1026 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1027 /// returned instead.
1028 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
1029 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1030 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
1031 /// instead.
1032 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1033 /// instead.
1034 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1035 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
1036 /// returned instead.
1037 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
1038 /// instead.
1039 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1040 /// instead.
1041 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
1042 /// instead.
1043 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1044 /// returned instead.
1045 ///
1046 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec`] instead.
1047 /// If you know that your target precision is the maximum of the precisions of the inputs,
1048 /// consider using [`Float::mul_add_mul_round`] instead. If both of these things are true,
1049 /// consider using
1050 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
1051 ///
1052 /// # Worst-case complexity
1053 /// $T(n, m) = O(n \log n \log\log n + m)$
1054 ///
1055 /// $M(n, m) = O(n \log n + m)$
1056 ///
1057 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1058 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1059 /// `max(self.significant_bits(), prec)`.
1060 ///
1061 /// # Panics
1062 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1063 /// representable with `prec` bits.
1064 ///
1065 /// # Examples
1066 /// ```
1067 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1068 /// use malachite_base::rounding_modes::RoundingMode::*;
1069 /// use malachite_float::Float;
1070 /// use std::cmp::Ordering::*;
1071 ///
1072 /// let x = Float::from(PI);
1073 /// let y = Float::from(E);
1074 /// let z = Float::from(SQRT_2);
1075 /// let w = Float::from(LN_2);
1076 ///
1077 /// let (sum, o) =
1078 /// x.clone()
1079 /// .mul_add_mul_prec_round_val_ref_val_ref(&y, z.clone(), &w, 5, Floor);
1080 /// assert_eq!(sum.to_string(), "9.50");
1081 /// assert_eq!(o, Less);
1082 ///
1083 /// let (sum, o) =
1084 /// x.clone()
1085 /// .mul_add_mul_prec_round_val_ref_val_ref(&y, z.clone(), &w, 5, Ceiling);
1086 /// assert_eq!(sum.to_string(), "10.0");
1087 /// assert_eq!(o, Greater);
1088 ///
1089 /// let (sum, o) =
1090 /// x.clone()
1091 /// .mul_add_mul_prec_round_val_ref_val_ref(&y, z.clone(), &w, 5, Nearest);
1092 /// assert_eq!(sum.to_string(), "9.50");
1093 /// assert_eq!(o, Less);
1094 ///
1095 /// let (sum, o) =
1096 /// x.clone()
1097 /// .mul_add_mul_prec_round_val_ref_val_ref(&y, z.clone(), &w, 20, Floor);
1098 /// assert_eq!(sum.to_string(), "9.5199890");
1099 /// assert_eq!(o, Less);
1100 ///
1101 /// let (sum, o) =
1102 /// x.clone()
1103 /// .mul_add_mul_prec_round_val_ref_val_ref(&y, z.clone(), &w, 20, Ceiling);
1104 /// assert_eq!(sum.to_string(), "9.5200043");
1105 /// assert_eq!(o, Greater);
1106 ///
1107 /// let (sum, o) =
1108 /// x.clone()
1109 /// .mul_add_mul_prec_round_val_ref_val_ref(&y, z.clone(), &w, 20, Nearest);
1110 /// assert_eq!(sum.to_string(), "9.5199890");
1111 /// assert_eq!(o, Less);
1112 /// ```
1113 #[allow(clippy::needless_pass_by_value)]
1114 #[inline]
1115 pub fn mul_add_mul_prec_round_val_ref_val_ref(
1116 self,
1117 y: &Self,
1118 z: Self,
1119 w: &Self,
1120 prec: u64,
1121 rm: RoundingMode,
1122 ) -> (Self, Ordering) {
1123 mul_add_mul_helper(&self, y, &z, w, false, prec, rm)
1124 }
1125
1126 /// Adds the products of two pairs of [`Float`]s, rounding the result to the specified precision
1127 /// and with the specified rounding mode; the products are not rounded before the final
1128 /// addition, so there is a single rounding. The second and third [`Float`]s are taken by
1129 /// reference and the others by value. An [`Ordering`] is also returned, indicating whether the
1130 /// rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
1131 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1132 ///
1133 /// See [`RoundingMode`] for a description of the possible rounding modes.
1134 ///
1135 /// $$
1136 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
1137 /// $$
1138 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1139 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1140 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
1141 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1142 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
1143 ///
1144 /// If the output has a precision, it is `prec`.
1145 ///
1146 /// Special cases:
1147 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1148 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1149 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1150 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1151 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1152 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1153 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
1154 /// - If exactly one product is infinite, the result is that product's infinity.
1155 /// - If both products are infinite, the result is their common infinity if their signs agree,
1156 /// and `NaN` otherwise.
1157 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
1158 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
1159 /// `Floor`
1160 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
1161 ///
1162 /// Overflow and underflow:
1163 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1164 /// returned instead.
1165 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
1166 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1167 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1168 /// returned instead.
1169 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
1170 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1171 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
1172 /// instead.
1173 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1174 /// instead.
1175 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1176 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
1177 /// returned instead.
1178 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
1179 /// instead.
1180 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1181 /// instead.
1182 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
1183 /// instead.
1184 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1185 /// returned instead.
1186 ///
1187 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec`] instead.
1188 /// If you know that your target precision is the maximum of the precisions of the inputs,
1189 /// consider using [`Float::mul_add_mul_round`] instead. If both of these things are true,
1190 /// consider using
1191 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
1192 ///
1193 /// # Worst-case complexity
1194 /// $T(n, m) = O(n \log n \log\log n + m)$
1195 ///
1196 /// $M(n, m) = O(n \log n + m)$
1197 ///
1198 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1199 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1200 /// `max(self.significant_bits(), prec)`.
1201 ///
1202 /// # Panics
1203 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1204 /// representable with `prec` bits.
1205 ///
1206 /// # Examples
1207 /// ```
1208 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1209 /// use malachite_base::rounding_modes::RoundingMode::*;
1210 /// use malachite_float::Float;
1211 /// use std::cmp::Ordering::*;
1212 ///
1213 /// let x = Float::from(PI);
1214 /// let y = Float::from(E);
1215 /// let z = Float::from(SQRT_2);
1216 /// let w = Float::from(LN_2);
1217 ///
1218 /// let (sum, o) =
1219 /// x.clone()
1220 /// .mul_add_mul_prec_round_val_ref_ref_val(&y, &z, w.clone(), 5, Floor);
1221 /// assert_eq!(sum.to_string(), "9.50");
1222 /// assert_eq!(o, Less);
1223 ///
1224 /// let (sum, o) =
1225 /// x.clone()
1226 /// .mul_add_mul_prec_round_val_ref_ref_val(&y, &z, w.clone(), 5, Ceiling);
1227 /// assert_eq!(sum.to_string(), "10.0");
1228 /// assert_eq!(o, Greater);
1229 ///
1230 /// let (sum, o) =
1231 /// x.clone()
1232 /// .mul_add_mul_prec_round_val_ref_ref_val(&y, &z, w.clone(), 5, Nearest);
1233 /// assert_eq!(sum.to_string(), "9.50");
1234 /// assert_eq!(o, Less);
1235 ///
1236 /// let (sum, o) =
1237 /// x.clone()
1238 /// .mul_add_mul_prec_round_val_ref_ref_val(&y, &z, w.clone(), 20, Floor);
1239 /// assert_eq!(sum.to_string(), "9.5199890");
1240 /// assert_eq!(o, Less);
1241 ///
1242 /// let (sum, o) =
1243 /// x.clone()
1244 /// .mul_add_mul_prec_round_val_ref_ref_val(&y, &z, w.clone(), 20, Ceiling);
1245 /// assert_eq!(sum.to_string(), "9.5200043");
1246 /// assert_eq!(o, Greater);
1247 ///
1248 /// let (sum, o) =
1249 /// x.clone()
1250 /// .mul_add_mul_prec_round_val_ref_ref_val(&y, &z, w.clone(), 20, Nearest);
1251 /// assert_eq!(sum.to_string(), "9.5199890");
1252 /// assert_eq!(o, Less);
1253 /// ```
1254 #[allow(clippy::needless_pass_by_value)]
1255 #[inline]
1256 pub fn mul_add_mul_prec_round_val_ref_ref_val(
1257 self,
1258 y: &Self,
1259 z: &Self,
1260 w: Self,
1261 prec: u64,
1262 rm: RoundingMode,
1263 ) -> (Self, Ordering) {
1264 mul_add_mul_helper(&self, y, z, &w, false, prec, rm)
1265 }
1266
1267 /// Adds the products of two pairs of [`Float`]s, rounding the result to the specified precision
1268 /// and with the specified rounding mode; the products are not rounded before the final
1269 /// addition, so there is a single rounding. The first [`Float`] is taken by value and the
1270 /// others by reference. An [`Ordering`] is also returned, indicating whether the rounded sum is
1271 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
1272 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1273 ///
1274 /// See [`RoundingMode`] for a description of the possible rounding modes.
1275 ///
1276 /// $$
1277 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
1278 /// $$
1279 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1280 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1281 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
1282 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1283 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
1284 ///
1285 /// If the output has a precision, it is `prec`.
1286 ///
1287 /// Special cases:
1288 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1289 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1290 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1291 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1292 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1293 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1294 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
1295 /// - If exactly one product is infinite, the result is that product's infinity.
1296 /// - If both products are infinite, the result is their common infinity if their signs agree,
1297 /// and `NaN` otherwise.
1298 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
1299 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
1300 /// `Floor`
1301 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
1302 ///
1303 /// Overflow and underflow:
1304 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1305 /// returned instead.
1306 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
1307 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1308 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1309 /// returned instead.
1310 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
1311 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1312 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
1313 /// instead.
1314 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1315 /// instead.
1316 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1317 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
1318 /// returned instead.
1319 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
1320 /// instead.
1321 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1322 /// instead.
1323 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
1324 /// instead.
1325 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1326 /// returned instead.
1327 ///
1328 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec`] instead.
1329 /// If you know that your target precision is the maximum of the precisions of the inputs,
1330 /// consider using [`Float::mul_add_mul_round`] instead. If both of these things are true,
1331 /// consider using
1332 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
1333 ///
1334 /// # Worst-case complexity
1335 /// $T(n, m) = O(n \log n \log\log n + m)$
1336 ///
1337 /// $M(n, m) = O(n \log n + m)$
1338 ///
1339 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1340 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1341 /// `max(self.significant_bits(), prec)`.
1342 ///
1343 /// # Panics
1344 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1345 /// representable with `prec` bits.
1346 ///
1347 /// # Examples
1348 /// ```
1349 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1350 /// use malachite_base::rounding_modes::RoundingMode::*;
1351 /// use malachite_float::Float;
1352 /// use std::cmp::Ordering::*;
1353 ///
1354 /// let x = Float::from(PI);
1355 /// let y = Float::from(E);
1356 /// let z = Float::from(SQRT_2);
1357 /// let w = Float::from(LN_2);
1358 ///
1359 /// let (sum, o) = x
1360 /// .clone()
1361 /// .mul_add_mul_prec_round_val_ref_ref_ref(&y, &z, &w, 5, Floor);
1362 /// assert_eq!(sum.to_string(), "9.50");
1363 /// assert_eq!(o, Less);
1364 ///
1365 /// let (sum, o) = x
1366 /// .clone()
1367 /// .mul_add_mul_prec_round_val_ref_ref_ref(&y, &z, &w, 5, Ceiling);
1368 /// assert_eq!(sum.to_string(), "10.0");
1369 /// assert_eq!(o, Greater);
1370 ///
1371 /// let (sum, o) = x
1372 /// .clone()
1373 /// .mul_add_mul_prec_round_val_ref_ref_ref(&y, &z, &w, 5, Nearest);
1374 /// assert_eq!(sum.to_string(), "9.50");
1375 /// assert_eq!(o, Less);
1376 ///
1377 /// let (sum, o) = x
1378 /// .clone()
1379 /// .mul_add_mul_prec_round_val_ref_ref_ref(&y, &z, &w, 20, Floor);
1380 /// assert_eq!(sum.to_string(), "9.5199890");
1381 /// assert_eq!(o, Less);
1382 ///
1383 /// let (sum, o) = x
1384 /// .clone()
1385 /// .mul_add_mul_prec_round_val_ref_ref_ref(&y, &z, &w, 20, Ceiling);
1386 /// assert_eq!(sum.to_string(), "9.5200043");
1387 /// assert_eq!(o, Greater);
1388 ///
1389 /// let (sum, o) = x
1390 /// .clone()
1391 /// .mul_add_mul_prec_round_val_ref_ref_ref(&y, &z, &w, 20, Nearest);
1392 /// assert_eq!(sum.to_string(), "9.5199890");
1393 /// assert_eq!(o, Less);
1394 /// ```
1395 #[allow(clippy::needless_pass_by_value)]
1396 #[inline]
1397 pub fn mul_add_mul_prec_round_val_ref_ref_ref(
1398 self,
1399 y: &Self,
1400 z: &Self,
1401 w: &Self,
1402 prec: u64,
1403 rm: RoundingMode,
1404 ) -> (Self, Ordering) {
1405 mul_add_mul_helper(&self, y, z, w, false, prec, rm)
1406 }
1407
1408 /// Adds the products of two pairs of [`Float`]s, rounding the result to the specified precision
1409 /// and with the specified rounding mode; the products are not rounded before the final
1410 /// addition, so there is a single rounding. All four [`Float`]s are taken by reference. An
1411 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
1412 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
1413 /// this function returns a `NaN` it also returns `Equal`.
1414 ///
1415 /// See [`RoundingMode`] for a description of the possible rounding modes.
1416 ///
1417 /// $$
1418 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
1419 /// $$
1420 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1421 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1422 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
1423 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1424 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
1425 ///
1426 /// If the output has a precision, it is `prec`.
1427 ///
1428 /// Special cases:
1429 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1430 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1431 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1432 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1433 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1434 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1435 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
1436 /// - If exactly one product is infinite, the result is that product's infinity.
1437 /// - If both products are infinite, the result is their common infinity if their signs agree,
1438 /// and `NaN` otherwise.
1439 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
1440 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
1441 /// `Floor`
1442 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
1443 ///
1444 /// Overflow and underflow:
1445 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1446 /// returned instead.
1447 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
1448 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1449 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1450 /// returned instead.
1451 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
1452 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1453 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
1454 /// instead.
1455 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1456 /// instead.
1457 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1458 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
1459 /// returned instead.
1460 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
1461 /// instead.
1462 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1463 /// instead.
1464 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
1465 /// instead.
1466 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1467 /// returned instead.
1468 ///
1469 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec`] instead.
1470 /// If you know that your target precision is the maximum of the precisions of the inputs,
1471 /// consider using [`Float::mul_add_mul_round`] instead. If both of these things are true,
1472 /// consider using
1473 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
1474 ///
1475 /// # Worst-case complexity
1476 /// $T(n, m) = O(n \log n \log\log n + m)$
1477 ///
1478 /// $M(n, m) = O(n \log n + m)$
1479 ///
1480 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1481 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1482 /// `max(self.significant_bits(), prec)`.
1483 ///
1484 /// # Panics
1485 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1486 /// representable with `prec` bits.
1487 ///
1488 /// # Examples
1489 /// ```
1490 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1491 /// use malachite_base::rounding_modes::RoundingMode::*;
1492 /// use malachite_float::Float;
1493 /// use std::cmp::Ordering::*;
1494 ///
1495 /// let x = Float::from(PI);
1496 /// let y = Float::from(E);
1497 /// let z = Float::from(SQRT_2);
1498 /// let w = Float::from(LN_2);
1499 ///
1500 /// let (sum, o) = x.mul_add_mul_prec_round_ref_ref_ref_ref(&y, &z, &w, 5, Floor);
1501 /// assert_eq!(sum.to_string(), "9.50");
1502 /// assert_eq!(o, Less);
1503 ///
1504 /// let (sum, o) = x.mul_add_mul_prec_round_ref_ref_ref_ref(&y, &z, &w, 5, Ceiling);
1505 /// assert_eq!(sum.to_string(), "10.0");
1506 /// assert_eq!(o, Greater);
1507 ///
1508 /// let (sum, o) = x.mul_add_mul_prec_round_ref_ref_ref_ref(&y, &z, &w, 5, Nearest);
1509 /// assert_eq!(sum.to_string(), "9.50");
1510 /// assert_eq!(o, Less);
1511 ///
1512 /// let (sum, o) = x.mul_add_mul_prec_round_ref_ref_ref_ref(&y, &z, &w, 20, Floor);
1513 /// assert_eq!(sum.to_string(), "9.5199890");
1514 /// assert_eq!(o, Less);
1515 ///
1516 /// let (sum, o) = x.mul_add_mul_prec_round_ref_ref_ref_ref(&y, &z, &w, 20, Ceiling);
1517 /// assert_eq!(sum.to_string(), "9.5200043");
1518 /// assert_eq!(o, Greater);
1519 ///
1520 /// let (sum, o) = x.mul_add_mul_prec_round_ref_ref_ref_ref(&y, &z, &w, 20, Nearest);
1521 /// assert_eq!(sum.to_string(), "9.5199890");
1522 /// assert_eq!(o, Less);
1523 /// ```
1524 #[allow(clippy::needless_pass_by_value)]
1525 #[inline]
1526 pub fn mul_add_mul_prec_round_ref_ref_ref_ref(
1527 &self,
1528 y: &Self,
1529 z: &Self,
1530 w: &Self,
1531 prec: u64,
1532 rm: RoundingMode,
1533 ) -> (Self, Ordering) {
1534 mul_add_mul_helper(self, y, z, w, false, prec, rm)
1535 }
1536
1537 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
1538 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
1539 /// the specified rounding mode. The [`Float`]s on the right-hand side are all taken by value.
1540 /// An [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
1541 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
1542 /// this function assigns a `NaN` it also returns `Equal`.
1543 ///
1544 /// See [`RoundingMode`] for a description of the possible rounding modes.
1545 ///
1546 /// $$
1547 /// x \gets xy+zw+\varepsilon.
1548 /// $$
1549 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1550 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1551 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
1552 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1553 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
1554 ///
1555 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
1556 /// overflow, and underflow.
1557 ///
1558 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec_assign`]
1559 /// instead. If you know that your target precision is the maximum of the precisions of the
1560 /// inputs, consider using [`Float::mul_add_mul_round_assign`] instead. If both of these things
1561 /// are true, consider using
1562 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
1563 ///
1564 /// # Worst-case complexity
1565 /// $T(n, m) = O(n \log n \log\log n + m)$
1566 ///
1567 /// $M(n, m) = O(n \log n + m)$
1568 ///
1569 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1570 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1571 /// `max(self.significant_bits(), prec)`.
1572 ///
1573 /// # Panics
1574 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1575 /// representable with `prec` bits.
1576 ///
1577 /// # Examples
1578 /// ```
1579 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1580 /// use malachite_base::rounding_modes::RoundingMode::*;
1581 /// use malachite_float::Float;
1582 /// use std::cmp::Ordering::*;
1583 ///
1584 /// let y = Float::from(E);
1585 /// let z = Float::from(SQRT_2);
1586 /// let w = Float::from(LN_2);
1587 ///
1588 /// let mut x = Float::from(PI);
1589 /// assert_eq!(
1590 /// x.mul_add_mul_prec_round_assign(y.clone(), z.clone(), w.clone(), 5, Floor),
1591 /// Less
1592 /// );
1593 /// assert_eq!(x.to_string(), "9.50");
1594 ///
1595 /// let mut x = Float::from(PI);
1596 /// assert_eq!(
1597 /// x.mul_add_mul_prec_round_assign(y.clone(), z.clone(), w.clone(), 5, Ceiling),
1598 /// Greater
1599 /// );
1600 /// assert_eq!(x.to_string(), "10.0");
1601 ///
1602 /// let mut x = Float::from(PI);
1603 /// assert_eq!(
1604 /// x.mul_add_mul_prec_round_assign(y.clone(), z.clone(), w.clone(), 5, Nearest),
1605 /// Less
1606 /// );
1607 /// assert_eq!(x.to_string(), "9.50");
1608 /// ```
1609 #[allow(clippy::needless_pass_by_value)]
1610 #[inline]
1611 pub fn mul_add_mul_prec_round_assign(
1612 &mut self,
1613 y: Self,
1614 z: Self,
1615 w: Self,
1616 prec: u64,
1617 rm: RoundingMode,
1618 ) -> Ordering {
1619 let (s, o) = mul_add_mul_helper(self, &y, &z, &w, false, prec, rm);
1620 *self = s;
1621 o
1622 }
1623
1624 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
1625 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
1626 /// the specified rounding mode. The last [`Float`] on the right-hand side is taken by reference
1627 /// and the others by value. An [`Ordering`] is returned, indicating whether the rounded sum is
1628 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
1629 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1630 ///
1631 /// See [`RoundingMode`] for a description of the possible rounding modes.
1632 ///
1633 /// $$
1634 /// x \gets xy+zw+\varepsilon.
1635 /// $$
1636 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1637 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1638 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
1639 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1640 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
1641 ///
1642 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
1643 /// overflow, and underflow.
1644 ///
1645 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec_assign`]
1646 /// instead. If you know that your target precision is the maximum of the precisions of the
1647 /// inputs, consider using [`Float::mul_add_mul_round_assign`] instead. If both of these things
1648 /// are true, consider using
1649 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
1650 ///
1651 /// # Worst-case complexity
1652 /// $T(n, m) = O(n \log n \log\log n + m)$
1653 ///
1654 /// $M(n, m) = O(n \log n + m)$
1655 ///
1656 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1657 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1658 /// `max(self.significant_bits(), prec)`.
1659 ///
1660 /// # Panics
1661 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1662 /// representable with `prec` bits.
1663 ///
1664 /// # Examples
1665 /// ```
1666 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1667 /// use malachite_base::rounding_modes::RoundingMode::*;
1668 /// use malachite_float::Float;
1669 /// use std::cmp::Ordering::*;
1670 ///
1671 /// let y = Float::from(E);
1672 /// let z = Float::from(SQRT_2);
1673 /// let w = Float::from(LN_2);
1674 ///
1675 /// let mut x = Float::from(PI);
1676 /// assert_eq!(
1677 /// x.mul_add_mul_prec_round_assign_val_val_ref(y.clone(), z.clone(), &w, 5, Floor),
1678 /// Less
1679 /// );
1680 /// assert_eq!(x.to_string(), "9.50");
1681 ///
1682 /// let mut x = Float::from(PI);
1683 /// assert_eq!(
1684 /// x.mul_add_mul_prec_round_assign_val_val_ref(y.clone(), z.clone(), &w, 5, Ceiling),
1685 /// Greater
1686 /// );
1687 /// assert_eq!(x.to_string(), "10.0");
1688 ///
1689 /// let mut x = Float::from(PI);
1690 /// assert_eq!(
1691 /// x.mul_add_mul_prec_round_assign_val_val_ref(y.clone(), z.clone(), &w, 5, Nearest),
1692 /// Less
1693 /// );
1694 /// assert_eq!(x.to_string(), "9.50");
1695 /// ```
1696 #[allow(clippy::needless_pass_by_value)]
1697 #[inline]
1698 pub fn mul_add_mul_prec_round_assign_val_val_ref(
1699 &mut self,
1700 y: Self,
1701 z: Self,
1702 w: &Self,
1703 prec: u64,
1704 rm: RoundingMode,
1705 ) -> Ordering {
1706 let (s, o) = mul_add_mul_helper(self, &y, &z, w, false, prec, rm);
1707 *self = s;
1708 o
1709 }
1710
1711 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
1712 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
1713 /// the specified rounding mode. The middle [`Float`] on the right-hand side is taken by
1714 /// reference and the others by value. An [`Ordering`] is returned, indicating whether the
1715 /// rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
1716 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1717 ///
1718 /// See [`RoundingMode`] for a description of the possible rounding modes.
1719 ///
1720 /// $$
1721 /// x \gets xy+zw+\varepsilon.
1722 /// $$
1723 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1724 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1725 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
1726 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1727 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
1728 ///
1729 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
1730 /// overflow, and underflow.
1731 ///
1732 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec_assign`]
1733 /// instead. If you know that your target precision is the maximum of the precisions of the
1734 /// inputs, consider using [`Float::mul_add_mul_round_assign`] instead. If both of these things
1735 /// are true, consider using
1736 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
1737 ///
1738 /// # Worst-case complexity
1739 /// $T(n, m) = O(n \log n \log\log n + m)$
1740 ///
1741 /// $M(n, m) = O(n \log n + m)$
1742 ///
1743 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1744 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1745 /// `max(self.significant_bits(), prec)`.
1746 ///
1747 /// # Panics
1748 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1749 /// representable with `prec` bits.
1750 ///
1751 /// # Examples
1752 /// ```
1753 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1754 /// use malachite_base::rounding_modes::RoundingMode::*;
1755 /// use malachite_float::Float;
1756 /// use std::cmp::Ordering::*;
1757 ///
1758 /// let y = Float::from(E);
1759 /// let z = Float::from(SQRT_2);
1760 /// let w = Float::from(LN_2);
1761 ///
1762 /// let mut x = Float::from(PI);
1763 /// assert_eq!(
1764 /// x.mul_add_mul_prec_round_assign_val_ref_val(y.clone(), &z, w.clone(), 5, Floor),
1765 /// Less
1766 /// );
1767 /// assert_eq!(x.to_string(), "9.50");
1768 ///
1769 /// let mut x = Float::from(PI);
1770 /// assert_eq!(
1771 /// x.mul_add_mul_prec_round_assign_val_ref_val(y.clone(), &z, w.clone(), 5, Ceiling),
1772 /// Greater
1773 /// );
1774 /// assert_eq!(x.to_string(), "10.0");
1775 ///
1776 /// let mut x = Float::from(PI);
1777 /// assert_eq!(
1778 /// x.mul_add_mul_prec_round_assign_val_ref_val(y.clone(), &z, w.clone(), 5, Nearest),
1779 /// Less
1780 /// );
1781 /// assert_eq!(x.to_string(), "9.50");
1782 /// ```
1783 #[allow(clippy::needless_pass_by_value)]
1784 #[inline]
1785 pub fn mul_add_mul_prec_round_assign_val_ref_val(
1786 &mut self,
1787 y: Self,
1788 z: &Self,
1789 w: Self,
1790 prec: u64,
1791 rm: RoundingMode,
1792 ) -> Ordering {
1793 let (s, o) = mul_add_mul_helper(self, &y, z, &w, false, prec, rm);
1794 *self = s;
1795 o
1796 }
1797
1798 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
1799 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
1800 /// the specified rounding mode. The first [`Float`] on the right-hand side is taken by value
1801 /// and the others by reference. An [`Ordering`] is returned, indicating whether the rounded sum
1802 /// is less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
1803 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1804 ///
1805 /// See [`RoundingMode`] for a description of the possible rounding modes.
1806 ///
1807 /// $$
1808 /// x \gets xy+zw+\varepsilon.
1809 /// $$
1810 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1811 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1812 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
1813 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1814 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
1815 ///
1816 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
1817 /// overflow, and underflow.
1818 ///
1819 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec_assign`]
1820 /// instead. If you know that your target precision is the maximum of the precisions of the
1821 /// inputs, consider using [`Float::mul_add_mul_round_assign`] instead. If both of these things
1822 /// are true, consider using
1823 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
1824 ///
1825 /// # Worst-case complexity
1826 /// $T(n, m) = O(n \log n \log\log n + m)$
1827 ///
1828 /// $M(n, m) = O(n \log n + m)$
1829 ///
1830 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1831 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1832 /// `max(self.significant_bits(), prec)`.
1833 ///
1834 /// # Panics
1835 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1836 /// representable with `prec` bits.
1837 ///
1838 /// # Examples
1839 /// ```
1840 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1841 /// use malachite_base::rounding_modes::RoundingMode::*;
1842 /// use malachite_float::Float;
1843 /// use std::cmp::Ordering::*;
1844 ///
1845 /// let y = Float::from(E);
1846 /// let z = Float::from(SQRT_2);
1847 /// let w = Float::from(LN_2);
1848 ///
1849 /// let mut x = Float::from(PI);
1850 /// assert_eq!(
1851 /// x.mul_add_mul_prec_round_assign_val_ref_ref(y.clone(), &z, &w, 5, Floor),
1852 /// Less
1853 /// );
1854 /// assert_eq!(x.to_string(), "9.50");
1855 ///
1856 /// let mut x = Float::from(PI);
1857 /// assert_eq!(
1858 /// x.mul_add_mul_prec_round_assign_val_ref_ref(y.clone(), &z, &w, 5, Ceiling),
1859 /// Greater
1860 /// );
1861 /// assert_eq!(x.to_string(), "10.0");
1862 ///
1863 /// let mut x = Float::from(PI);
1864 /// assert_eq!(
1865 /// x.mul_add_mul_prec_round_assign_val_ref_ref(y.clone(), &z, &w, 5, Nearest),
1866 /// Less
1867 /// );
1868 /// assert_eq!(x.to_string(), "9.50");
1869 /// ```
1870 #[allow(clippy::needless_pass_by_value)]
1871 #[inline]
1872 pub fn mul_add_mul_prec_round_assign_val_ref_ref(
1873 &mut self,
1874 y: Self,
1875 z: &Self,
1876 w: &Self,
1877 prec: u64,
1878 rm: RoundingMode,
1879 ) -> Ordering {
1880 let (s, o) = mul_add_mul_helper(self, &y, z, w, false, prec, rm);
1881 *self = s;
1882 o
1883 }
1884
1885 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
1886 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
1887 /// the specified rounding mode. The first [`Float`] on the right-hand side is taken by
1888 /// reference and the others by value. An [`Ordering`] is returned, indicating whether the
1889 /// rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
1890 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1891 ///
1892 /// See [`RoundingMode`] for a description of the possible rounding modes.
1893 ///
1894 /// $$
1895 /// x \gets xy+zw+\varepsilon.
1896 /// $$
1897 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1898 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1899 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
1900 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1901 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
1902 ///
1903 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
1904 /// overflow, and underflow.
1905 ///
1906 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec_assign`]
1907 /// instead. If you know that your target precision is the maximum of the precisions of the
1908 /// inputs, consider using [`Float::mul_add_mul_round_assign`] instead. If both of these things
1909 /// are true, consider using
1910 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
1911 ///
1912 /// # Worst-case complexity
1913 /// $T(n, m) = O(n \log n \log\log n + m)$
1914 ///
1915 /// $M(n, m) = O(n \log n + m)$
1916 ///
1917 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1918 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1919 /// `max(self.significant_bits(), prec)`.
1920 ///
1921 /// # Panics
1922 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1923 /// representable with `prec` bits.
1924 ///
1925 /// # Examples
1926 /// ```
1927 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1928 /// use malachite_base::rounding_modes::RoundingMode::*;
1929 /// use malachite_float::Float;
1930 /// use std::cmp::Ordering::*;
1931 ///
1932 /// let y = Float::from(E);
1933 /// let z = Float::from(SQRT_2);
1934 /// let w = Float::from(LN_2);
1935 ///
1936 /// let mut x = Float::from(PI);
1937 /// assert_eq!(
1938 /// x.mul_add_mul_prec_round_assign_ref_val_val(&y, z.clone(), w.clone(), 5, Floor),
1939 /// Less
1940 /// );
1941 /// assert_eq!(x.to_string(), "9.50");
1942 ///
1943 /// let mut x = Float::from(PI);
1944 /// assert_eq!(
1945 /// x.mul_add_mul_prec_round_assign_ref_val_val(&y, z.clone(), w.clone(), 5, Ceiling),
1946 /// Greater
1947 /// );
1948 /// assert_eq!(x.to_string(), "10.0");
1949 ///
1950 /// let mut x = Float::from(PI);
1951 /// assert_eq!(
1952 /// x.mul_add_mul_prec_round_assign_ref_val_val(&y, z.clone(), w.clone(), 5, Nearest),
1953 /// Less
1954 /// );
1955 /// assert_eq!(x.to_string(), "9.50");
1956 /// ```
1957 #[allow(clippy::needless_pass_by_value)]
1958 #[inline]
1959 pub fn mul_add_mul_prec_round_assign_ref_val_val(
1960 &mut self,
1961 y: &Self,
1962 z: Self,
1963 w: Self,
1964 prec: u64,
1965 rm: RoundingMode,
1966 ) -> Ordering {
1967 let (s, o) = mul_add_mul_helper(self, y, &z, &w, false, prec, rm);
1968 *self = s;
1969 o
1970 }
1971
1972 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
1973 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
1974 /// the specified rounding mode. The middle [`Float`] on the right-hand side is taken by value
1975 /// and the others by reference. An [`Ordering`] is returned, indicating whether the rounded sum
1976 /// is less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
1977 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1978 ///
1979 /// See [`RoundingMode`] for a description of the possible rounding modes.
1980 ///
1981 /// $$
1982 /// x \gets xy+zw+\varepsilon.
1983 /// $$
1984 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1985 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1986 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
1987 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1988 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
1989 ///
1990 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
1991 /// overflow, and underflow.
1992 ///
1993 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec_assign`]
1994 /// instead. If you know that your target precision is the maximum of the precisions of the
1995 /// inputs, consider using [`Float::mul_add_mul_round_assign`] instead. If both of these things
1996 /// are true, consider using
1997 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
1998 ///
1999 /// # Worst-case complexity
2000 /// $T(n, m) = O(n \log n \log\log n + m)$
2001 ///
2002 /// $M(n, m) = O(n \log n + m)$
2003 ///
2004 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2005 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2006 /// `max(self.significant_bits(), prec)`.
2007 ///
2008 /// # Panics
2009 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
2010 /// representable with `prec` bits.
2011 ///
2012 /// # Examples
2013 /// ```
2014 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2015 /// use malachite_base::rounding_modes::RoundingMode::*;
2016 /// use malachite_float::Float;
2017 /// use std::cmp::Ordering::*;
2018 ///
2019 /// let y = Float::from(E);
2020 /// let z = Float::from(SQRT_2);
2021 /// let w = Float::from(LN_2);
2022 ///
2023 /// let mut x = Float::from(PI);
2024 /// assert_eq!(
2025 /// x.mul_add_mul_prec_round_assign_ref_val_ref(&y, z.clone(), &w, 5, Floor),
2026 /// Less
2027 /// );
2028 /// assert_eq!(x.to_string(), "9.50");
2029 ///
2030 /// let mut x = Float::from(PI);
2031 /// assert_eq!(
2032 /// x.mul_add_mul_prec_round_assign_ref_val_ref(&y, z.clone(), &w, 5, Ceiling),
2033 /// Greater
2034 /// );
2035 /// assert_eq!(x.to_string(), "10.0");
2036 ///
2037 /// let mut x = Float::from(PI);
2038 /// assert_eq!(
2039 /// x.mul_add_mul_prec_round_assign_ref_val_ref(&y, z.clone(), &w, 5, Nearest),
2040 /// Less
2041 /// );
2042 /// assert_eq!(x.to_string(), "9.50");
2043 /// ```
2044 #[allow(clippy::needless_pass_by_value)]
2045 #[inline]
2046 pub fn mul_add_mul_prec_round_assign_ref_val_ref(
2047 &mut self,
2048 y: &Self,
2049 z: Self,
2050 w: &Self,
2051 prec: u64,
2052 rm: RoundingMode,
2053 ) -> Ordering {
2054 let (s, o) = mul_add_mul_helper(self, y, &z, w, false, prec, rm);
2055 *self = s;
2056 o
2057 }
2058
2059 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
2060 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
2061 /// the specified rounding mode. The last [`Float`] on the right-hand side is taken by value and
2062 /// the others by reference. An [`Ordering`] is returned, indicating whether the rounded sum is
2063 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
2064 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
2065 ///
2066 /// See [`RoundingMode`] for a description of the possible rounding modes.
2067 ///
2068 /// $$
2069 /// x \gets xy+zw+\varepsilon.
2070 /// $$
2071 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2072 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2073 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
2074 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
2075 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
2076 ///
2077 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
2078 /// overflow, and underflow.
2079 ///
2080 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec_assign`]
2081 /// instead. If you know that your target precision is the maximum of the precisions of the
2082 /// inputs, consider using [`Float::mul_add_mul_round_assign`] instead. If both of these things
2083 /// are true, consider using
2084 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
2085 ///
2086 /// # Worst-case complexity
2087 /// $T(n, m) = O(n \log n \log\log n + m)$
2088 ///
2089 /// $M(n, m) = O(n \log n + m)$
2090 ///
2091 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2092 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2093 /// `max(self.significant_bits(), prec)`.
2094 ///
2095 /// # Panics
2096 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
2097 /// representable with `prec` bits.
2098 ///
2099 /// # Examples
2100 /// ```
2101 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2102 /// use malachite_base::rounding_modes::RoundingMode::*;
2103 /// use malachite_float::Float;
2104 /// use std::cmp::Ordering::*;
2105 ///
2106 /// let y = Float::from(E);
2107 /// let z = Float::from(SQRT_2);
2108 /// let w = Float::from(LN_2);
2109 ///
2110 /// let mut x = Float::from(PI);
2111 /// assert_eq!(
2112 /// x.mul_add_mul_prec_round_assign_ref_ref_val(&y, &z, w.clone(), 5, Floor),
2113 /// Less
2114 /// );
2115 /// assert_eq!(x.to_string(), "9.50");
2116 ///
2117 /// let mut x = Float::from(PI);
2118 /// assert_eq!(
2119 /// x.mul_add_mul_prec_round_assign_ref_ref_val(&y, &z, w.clone(), 5, Ceiling),
2120 /// Greater
2121 /// );
2122 /// assert_eq!(x.to_string(), "10.0");
2123 ///
2124 /// let mut x = Float::from(PI);
2125 /// assert_eq!(
2126 /// x.mul_add_mul_prec_round_assign_ref_ref_val(&y, &z, w.clone(), 5, Nearest),
2127 /// Less
2128 /// );
2129 /// assert_eq!(x.to_string(), "9.50");
2130 /// ```
2131 #[allow(clippy::needless_pass_by_value)]
2132 #[inline]
2133 pub fn mul_add_mul_prec_round_assign_ref_ref_val(
2134 &mut self,
2135 y: &Self,
2136 z: &Self,
2137 w: Self,
2138 prec: u64,
2139 rm: RoundingMode,
2140 ) -> Ordering {
2141 let (s, o) = mul_add_mul_helper(self, y, z, &w, false, prec, rm);
2142 *self = s;
2143 o
2144 }
2145
2146 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
2147 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
2148 /// the specified rounding mode. The [`Float`]s on the right-hand side are all taken by
2149 /// reference. An [`Ordering`] is returned, indicating whether the rounded sum is less than,
2150 /// equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
2151 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
2152 ///
2153 /// See [`RoundingMode`] for a description of the possible rounding modes.
2154 ///
2155 /// $$
2156 /// x \gets xy+zw+\varepsilon.
2157 /// $$
2158 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2159 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2160 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
2161 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
2162 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
2163 ///
2164 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
2165 /// overflow, and underflow.
2166 ///
2167 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_prec_assign`]
2168 /// instead. If you know that your target precision is the maximum of the precisions of the
2169 /// inputs, consider using [`Float::mul_add_mul_round_assign`] instead. If both of these things
2170 /// are true, consider using
2171 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
2172 ///
2173 /// # Worst-case complexity
2174 /// $T(n, m) = O(n \log n \log\log n + m)$
2175 ///
2176 /// $M(n, m) = O(n \log n + m)$
2177 ///
2178 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2179 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2180 /// `max(self.significant_bits(), prec)`.
2181 ///
2182 /// # Panics
2183 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
2184 /// representable with `prec` bits.
2185 ///
2186 /// # Examples
2187 /// ```
2188 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2189 /// use malachite_base::rounding_modes::RoundingMode::*;
2190 /// use malachite_float::Float;
2191 /// use std::cmp::Ordering::*;
2192 ///
2193 /// let y = Float::from(E);
2194 /// let z = Float::from(SQRT_2);
2195 /// let w = Float::from(LN_2);
2196 ///
2197 /// let mut x = Float::from(PI);
2198 /// assert_eq!(
2199 /// x.mul_add_mul_prec_round_assign_ref_ref_ref(&y, &z, &w, 5, Floor),
2200 /// Less
2201 /// );
2202 /// assert_eq!(x.to_string(), "9.50");
2203 ///
2204 /// let mut x = Float::from(PI);
2205 /// assert_eq!(
2206 /// x.mul_add_mul_prec_round_assign_ref_ref_ref(&y, &z, &w, 5, Ceiling),
2207 /// Greater
2208 /// );
2209 /// assert_eq!(x.to_string(), "10.0");
2210 ///
2211 /// let mut x = Float::from(PI);
2212 /// assert_eq!(
2213 /// x.mul_add_mul_prec_round_assign_ref_ref_ref(&y, &z, &w, 5, Nearest),
2214 /// Less
2215 /// );
2216 /// assert_eq!(x.to_string(), "9.50");
2217 /// ```
2218 #[allow(clippy::needless_pass_by_value)]
2219 #[inline]
2220 pub fn mul_add_mul_prec_round_assign_ref_ref_ref(
2221 &mut self,
2222 y: &Self,
2223 z: &Self,
2224 w: &Self,
2225 prec: u64,
2226 rm: RoundingMode,
2227 ) -> Ordering {
2228 let (s, o) = mul_add_mul_helper(self, y, z, w, false, prec, rm);
2229 *self = s;
2230 o
2231 }
2232
2233 /// Adds the products of two pairs of [`Float`]s, rounding the result to the nearest value of
2234 /// the specified precision; the products are not rounded before the final addition, so there is
2235 /// a single rounding. All four [`Float`]s are taken by value. An [`Ordering`] is also returned,
2236 /// indicating whether the rounded sum is less than, equal to, or greater than the exact sum.
2237 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
2238 /// it also returns `Equal`.
2239 ///
2240 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2241 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2242 /// the `Nearest` rounding mode.
2243 ///
2244 /// $$
2245 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
2246 /// $$
2247 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2248 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2249 /// |xy+zw|\rfloor-p}$.
2250 ///
2251 /// If the output has a precision, it is `prec`.
2252 ///
2253 /// Special cases:
2254 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2255 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2256 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2257 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2258 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2259 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2260 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2261 /// - If exactly one product is infinite, the result is that product's infinity.
2262 /// - If both products are infinite, the result is their common infinity if their signs agree,
2263 /// and `NaN` otherwise.
2264 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
2265 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
2266 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
2267 ///
2268 /// Overflow and underflow:
2269 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2270 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2271 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2272 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2273 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2274 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2275 ///
2276 /// If you want to use a rounding mode other than `Nearest`, consider using
2277 /// [`Float::mul_add_mul_prec_round`] instead. If you know that your target precision is the
2278 /// maximum of the precisions of the inputs, consider using
2279 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
2280 ///
2281 /// # Worst-case complexity
2282 /// $T(n, m) = O(n \log n \log\log n + m)$
2283 ///
2284 /// $M(n, m) = O(n \log n + m)$
2285 ///
2286 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2287 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2288 /// `max(self.significant_bits(), prec)`.
2289 ///
2290 /// # Panics
2291 /// Panics if `prec` is zero.
2292 ///
2293 /// # Examples
2294 /// ```
2295 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2296 /// use malachite_float::Float;
2297 /// use std::cmp::Ordering::*;
2298 ///
2299 /// let x = Float::from(PI);
2300 /// let y = Float::from(E);
2301 /// let z = Float::from(SQRT_2);
2302 /// let w = Float::from(LN_2);
2303 ///
2304 /// let (sum, o) = x
2305 /// .clone()
2306 /// .mul_add_mul_prec(y.clone(), z.clone(), w.clone(), 5);
2307 /// assert_eq!(sum.to_string(), "9.50");
2308 /// assert_eq!(o, Less);
2309 ///
2310 /// let (sum, o) = x
2311 /// .clone()
2312 /// .mul_add_mul_prec(y.clone(), z.clone(), w.clone(), 20);
2313 /// assert_eq!(sum.to_string(), "9.5199890");
2314 /// assert_eq!(o, Less);
2315 /// ```
2316 #[allow(clippy::needless_pass_by_value)]
2317 #[inline]
2318 pub fn mul_add_mul_prec(self, y: Self, z: Self, w: Self, prec: u64) -> (Self, Ordering) {
2319 self.mul_add_mul_prec_round(y, z, w, prec, Nearest)
2320 }
2321
2322 /// Adds the products of two pairs of [`Float`]s, rounding the result to the nearest value of
2323 /// the specified precision; the products are not rounded before the final addition, so there is
2324 /// a single rounding. The first three [`Float`]s are taken by value and the fourth by
2325 /// reference. An [`Ordering`] is also returned, indicating whether the rounded sum is less
2326 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
2327 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2328 ///
2329 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2330 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2331 /// the `Nearest` rounding mode.
2332 ///
2333 /// $$
2334 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
2335 /// $$
2336 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2337 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2338 /// |xy+zw|\rfloor-p}$.
2339 ///
2340 /// If the output has a precision, it is `prec`.
2341 ///
2342 /// Special cases:
2343 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2344 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2345 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2346 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2347 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2348 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2349 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2350 /// - If exactly one product is infinite, the result is that product's infinity.
2351 /// - If both products are infinite, the result is their common infinity if their signs agree,
2352 /// and `NaN` otherwise.
2353 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
2354 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
2355 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
2356 ///
2357 /// Overflow and underflow:
2358 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2359 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2360 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2361 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2362 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2363 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2364 ///
2365 /// If you want to use a rounding mode other than `Nearest`, consider using
2366 /// [`Float::mul_add_mul_prec_round`] instead. If you know that your target precision is the
2367 /// maximum of the precisions of the inputs, consider using
2368 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
2369 ///
2370 /// # Worst-case complexity
2371 /// $T(n, m) = O(n \log n \log\log n + m)$
2372 ///
2373 /// $M(n, m) = O(n \log n + m)$
2374 ///
2375 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2376 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2377 /// `max(self.significant_bits(), prec)`.
2378 ///
2379 /// # Panics
2380 /// Panics if `prec` is zero.
2381 ///
2382 /// # Examples
2383 /// ```
2384 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2385 /// use malachite_float::Float;
2386 /// use std::cmp::Ordering::*;
2387 ///
2388 /// let x = Float::from(PI);
2389 /// let y = Float::from(E);
2390 /// let z = Float::from(SQRT_2);
2391 /// let w = Float::from(LN_2);
2392 ///
2393 /// let (sum, o) = x
2394 /// .clone()
2395 /// .mul_add_mul_prec_val_val_val_ref(y.clone(), z.clone(), &w, 5);
2396 /// assert_eq!(sum.to_string(), "9.50");
2397 /// assert_eq!(o, Less);
2398 ///
2399 /// let (sum, o) = x
2400 /// .clone()
2401 /// .mul_add_mul_prec_val_val_val_ref(y.clone(), z.clone(), &w, 20);
2402 /// assert_eq!(sum.to_string(), "9.5199890");
2403 /// assert_eq!(o, Less);
2404 /// ```
2405 #[allow(clippy::needless_pass_by_value)]
2406 #[inline]
2407 pub fn mul_add_mul_prec_val_val_val_ref(
2408 self,
2409 y: Self,
2410 z: Self,
2411 w: &Self,
2412 prec: u64,
2413 ) -> (Self, Ordering) {
2414 self.mul_add_mul_prec_round_val_val_val_ref(y, z, w, prec, Nearest)
2415 }
2416
2417 /// Adds the products of two pairs of [`Float`]s, rounding the result to the nearest value of
2418 /// the specified precision; the products are not rounded before the final addition, so there is
2419 /// a single rounding. The third [`Float`] is taken by reference and the others by value. An
2420 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
2421 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
2422 /// this function returns a `NaN` it also returns `Equal`.
2423 ///
2424 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2425 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2426 /// the `Nearest` rounding mode.
2427 ///
2428 /// $$
2429 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
2430 /// $$
2431 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2432 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2433 /// |xy+zw|\rfloor-p}$.
2434 ///
2435 /// If the output has a precision, it is `prec`.
2436 ///
2437 /// Special cases:
2438 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2439 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2440 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2441 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2442 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2443 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2444 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2445 /// - If exactly one product is infinite, the result is that product's infinity.
2446 /// - If both products are infinite, the result is their common infinity if their signs agree,
2447 /// and `NaN` otherwise.
2448 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
2449 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
2450 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
2451 ///
2452 /// Overflow and underflow:
2453 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2454 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2455 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2456 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2457 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2458 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2459 ///
2460 /// If you want to use a rounding mode other than `Nearest`, consider using
2461 /// [`Float::mul_add_mul_prec_round`] instead. If you know that your target precision is the
2462 /// maximum of the precisions of the inputs, consider using
2463 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
2464 ///
2465 /// # Worst-case complexity
2466 /// $T(n, m) = O(n \log n \log\log n + m)$
2467 ///
2468 /// $M(n, m) = O(n \log n + m)$
2469 ///
2470 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2471 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2472 /// `max(self.significant_bits(), prec)`.
2473 ///
2474 /// # Panics
2475 /// Panics if `prec` is zero.
2476 ///
2477 /// # Examples
2478 /// ```
2479 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2480 /// use malachite_float::Float;
2481 /// use std::cmp::Ordering::*;
2482 ///
2483 /// let x = Float::from(PI);
2484 /// let y = Float::from(E);
2485 /// let z = Float::from(SQRT_2);
2486 /// let w = Float::from(LN_2);
2487 ///
2488 /// let (sum, o) = x
2489 /// .clone()
2490 /// .mul_add_mul_prec_val_val_ref_val(y.clone(), &z, w.clone(), 5);
2491 /// assert_eq!(sum.to_string(), "9.50");
2492 /// assert_eq!(o, Less);
2493 ///
2494 /// let (sum, o) = x
2495 /// .clone()
2496 /// .mul_add_mul_prec_val_val_ref_val(y.clone(), &z, w.clone(), 20);
2497 /// assert_eq!(sum.to_string(), "9.5199890");
2498 /// assert_eq!(o, Less);
2499 /// ```
2500 #[allow(clippy::needless_pass_by_value)]
2501 #[inline]
2502 pub fn mul_add_mul_prec_val_val_ref_val(
2503 self,
2504 y: Self,
2505 z: &Self,
2506 w: Self,
2507 prec: u64,
2508 ) -> (Self, Ordering) {
2509 self.mul_add_mul_prec_round_val_val_ref_val(y, z, w, prec, Nearest)
2510 }
2511
2512 /// Adds the products of two pairs of [`Float`]s, rounding the result to the nearest value of
2513 /// the specified precision; the products are not rounded before the final addition, so there is
2514 /// a single rounding. The first two [`Float`]s are taken by value and the last two by
2515 /// reference. An [`Ordering`] is also returned, indicating whether the rounded sum is less
2516 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
2517 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2518 ///
2519 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2520 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2521 /// the `Nearest` rounding mode.
2522 ///
2523 /// $$
2524 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
2525 /// $$
2526 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2527 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2528 /// |xy+zw|\rfloor-p}$.
2529 ///
2530 /// If the output has a precision, it is `prec`.
2531 ///
2532 /// Special cases:
2533 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2534 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2535 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2536 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2537 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2538 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2539 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2540 /// - If exactly one product is infinite, the result is that product's infinity.
2541 /// - If both products are infinite, the result is their common infinity if their signs agree,
2542 /// and `NaN` otherwise.
2543 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
2544 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
2545 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
2546 ///
2547 /// Overflow and underflow:
2548 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2549 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2550 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2551 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2552 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2553 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2554 ///
2555 /// If you want to use a rounding mode other than `Nearest`, consider using
2556 /// [`Float::mul_add_mul_prec_round`] instead. If you know that your target precision is the
2557 /// maximum of the precisions of the inputs, consider using
2558 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
2559 ///
2560 /// # Worst-case complexity
2561 /// $T(n, m) = O(n \log n \log\log n + m)$
2562 ///
2563 /// $M(n, m) = O(n \log n + m)$
2564 ///
2565 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2566 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2567 /// `max(self.significant_bits(), prec)`.
2568 ///
2569 /// # Panics
2570 /// Panics if `prec` is zero.
2571 ///
2572 /// # Examples
2573 /// ```
2574 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2575 /// use malachite_float::Float;
2576 /// use std::cmp::Ordering::*;
2577 ///
2578 /// let x = Float::from(PI);
2579 /// let y = Float::from(E);
2580 /// let z = Float::from(SQRT_2);
2581 /// let w = Float::from(LN_2);
2582 ///
2583 /// let (sum, o) = x
2584 /// .clone()
2585 /// .mul_add_mul_prec_val_val_ref_ref(y.clone(), &z, &w, 5);
2586 /// assert_eq!(sum.to_string(), "9.50");
2587 /// assert_eq!(o, Less);
2588 ///
2589 /// let (sum, o) = x
2590 /// .clone()
2591 /// .mul_add_mul_prec_val_val_ref_ref(y.clone(), &z, &w, 20);
2592 /// assert_eq!(sum.to_string(), "9.5199890");
2593 /// assert_eq!(o, Less);
2594 /// ```
2595 #[allow(clippy::needless_pass_by_value)]
2596 #[inline]
2597 pub fn mul_add_mul_prec_val_val_ref_ref(
2598 self,
2599 y: Self,
2600 z: &Self,
2601 w: &Self,
2602 prec: u64,
2603 ) -> (Self, Ordering) {
2604 self.mul_add_mul_prec_round_val_val_ref_ref(y, z, w, prec, Nearest)
2605 }
2606
2607 /// Adds the products of two pairs of [`Float`]s, rounding the result to the nearest value of
2608 /// the specified precision; the products are not rounded before the final addition, so there is
2609 /// a single rounding. The second [`Float`] is taken by reference and the others by value. An
2610 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
2611 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
2612 /// this function returns a `NaN` it also returns `Equal`.
2613 ///
2614 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2615 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2616 /// the `Nearest` rounding mode.
2617 ///
2618 /// $$
2619 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
2620 /// $$
2621 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2622 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2623 /// |xy+zw|\rfloor-p}$.
2624 ///
2625 /// If the output has a precision, it is `prec`.
2626 ///
2627 /// Special cases:
2628 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2629 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2630 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2631 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2632 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2633 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2634 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2635 /// - If exactly one product is infinite, the result is that product's infinity.
2636 /// - If both products are infinite, the result is their common infinity if their signs agree,
2637 /// and `NaN` otherwise.
2638 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
2639 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
2640 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
2641 ///
2642 /// Overflow and underflow:
2643 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2644 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2645 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2646 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2647 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2648 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2649 ///
2650 /// If you want to use a rounding mode other than `Nearest`, consider using
2651 /// [`Float::mul_add_mul_prec_round`] instead. If you know that your target precision is the
2652 /// maximum of the precisions of the inputs, consider using
2653 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
2654 ///
2655 /// # Worst-case complexity
2656 /// $T(n, m) = O(n \log n \log\log n + m)$
2657 ///
2658 /// $M(n, m) = O(n \log n + m)$
2659 ///
2660 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2661 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2662 /// `max(self.significant_bits(), prec)`.
2663 ///
2664 /// # Panics
2665 /// Panics if `prec` is zero.
2666 ///
2667 /// # Examples
2668 /// ```
2669 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2670 /// use malachite_float::Float;
2671 /// use std::cmp::Ordering::*;
2672 ///
2673 /// let x = Float::from(PI);
2674 /// let y = Float::from(E);
2675 /// let z = Float::from(SQRT_2);
2676 /// let w = Float::from(LN_2);
2677 ///
2678 /// let (sum, o) = x
2679 /// .clone()
2680 /// .mul_add_mul_prec_val_ref_val_val(&y, z.clone(), w.clone(), 5);
2681 /// assert_eq!(sum.to_string(), "9.50");
2682 /// assert_eq!(o, Less);
2683 ///
2684 /// let (sum, o) = x
2685 /// .clone()
2686 /// .mul_add_mul_prec_val_ref_val_val(&y, z.clone(), w.clone(), 20);
2687 /// assert_eq!(sum.to_string(), "9.5199890");
2688 /// assert_eq!(o, Less);
2689 /// ```
2690 #[allow(clippy::needless_pass_by_value)]
2691 #[inline]
2692 pub fn mul_add_mul_prec_val_ref_val_val(
2693 self,
2694 y: &Self,
2695 z: Self,
2696 w: Self,
2697 prec: u64,
2698 ) -> (Self, Ordering) {
2699 self.mul_add_mul_prec_round_val_ref_val_val(y, z, w, prec, Nearest)
2700 }
2701
2702 /// Adds the products of two pairs of [`Float`]s, rounding the result to the nearest value of
2703 /// the specified precision; the products are not rounded before the final addition, so there is
2704 /// a single rounding. The second and fourth [`Float`]s are taken by reference and the others by
2705 /// value. An [`Ordering`] is also returned, indicating whether the rounded sum is less than,
2706 /// equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
2707 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2708 ///
2709 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2710 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2711 /// the `Nearest` rounding mode.
2712 ///
2713 /// $$
2714 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
2715 /// $$
2716 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2717 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2718 /// |xy+zw|\rfloor-p}$.
2719 ///
2720 /// If the output has a precision, it is `prec`.
2721 ///
2722 /// Special cases:
2723 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2724 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2725 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2726 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2727 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2728 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2729 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2730 /// - If exactly one product is infinite, the result is that product's infinity.
2731 /// - If both products are infinite, the result is their common infinity if their signs agree,
2732 /// and `NaN` otherwise.
2733 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
2734 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
2735 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
2736 ///
2737 /// Overflow and underflow:
2738 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2739 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2740 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2741 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2742 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2743 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2744 ///
2745 /// If you want to use a rounding mode other than `Nearest`, consider using
2746 /// [`Float::mul_add_mul_prec_round`] instead. If you know that your target precision is the
2747 /// maximum of the precisions of the inputs, consider using
2748 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) 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 `self.significant_bits() +
2756 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2757 /// `max(self.significant_bits(), prec)`.
2758 ///
2759 /// # Panics
2760 /// Panics if `prec` is zero.
2761 ///
2762 /// # Examples
2763 /// ```
2764 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2765 /// use malachite_float::Float;
2766 /// use std::cmp::Ordering::*;
2767 ///
2768 /// let x = Float::from(PI);
2769 /// let y = Float::from(E);
2770 /// let z = Float::from(SQRT_2);
2771 /// let w = Float::from(LN_2);
2772 ///
2773 /// let (sum, o) = x
2774 /// .clone()
2775 /// .mul_add_mul_prec_val_ref_val_ref(&y, z.clone(), &w, 5);
2776 /// assert_eq!(sum.to_string(), "9.50");
2777 /// assert_eq!(o, Less);
2778 ///
2779 /// let (sum, o) = x
2780 /// .clone()
2781 /// .mul_add_mul_prec_val_ref_val_ref(&y, z.clone(), &w, 20);
2782 /// assert_eq!(sum.to_string(), "9.5199890");
2783 /// assert_eq!(o, Less);
2784 /// ```
2785 #[allow(clippy::needless_pass_by_value)]
2786 #[inline]
2787 pub fn mul_add_mul_prec_val_ref_val_ref(
2788 self,
2789 y: &Self,
2790 z: Self,
2791 w: &Self,
2792 prec: u64,
2793 ) -> (Self, Ordering) {
2794 self.mul_add_mul_prec_round_val_ref_val_ref(y, z, w, prec, Nearest)
2795 }
2796
2797 /// Adds the products of two pairs of [`Float`]s, rounding the result to the nearest value of
2798 /// the specified precision; the products are not rounded before the final addition, so there is
2799 /// a single rounding. The second and third [`Float`]s are taken by reference and the others by
2800 /// value. An [`Ordering`] is also returned, indicating whether the rounded sum is less than,
2801 /// equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
2802 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2803 ///
2804 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2805 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2806 /// the `Nearest` rounding mode.
2807 ///
2808 /// $$
2809 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
2810 /// $$
2811 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2812 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2813 /// |xy+zw|\rfloor-p}$.
2814 ///
2815 /// If the output has a precision, it is `prec`.
2816 ///
2817 /// Special cases:
2818 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2819 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2820 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2821 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2822 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2823 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2824 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2825 /// - If exactly one product is infinite, the result is that product's infinity.
2826 /// - If both products are infinite, the result is their common infinity if their signs agree,
2827 /// and `NaN` otherwise.
2828 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
2829 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
2830 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
2831 ///
2832 /// Overflow and underflow:
2833 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2834 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2835 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2836 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2837 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2838 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2839 ///
2840 /// If you want to use a rounding mode other than `Nearest`, consider using
2841 /// [`Float::mul_add_mul_prec_round`] instead. If you know that your target precision is the
2842 /// maximum of the precisions of the inputs, consider using
2843 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
2844 ///
2845 /// # Worst-case complexity
2846 /// $T(n, m) = O(n \log n \log\log n + m)$
2847 ///
2848 /// $M(n, m) = O(n \log n + m)$
2849 ///
2850 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2851 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2852 /// `max(self.significant_bits(), prec)`.
2853 ///
2854 /// # Panics
2855 /// Panics if `prec` is zero.
2856 ///
2857 /// # Examples
2858 /// ```
2859 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2860 /// use malachite_float::Float;
2861 /// use std::cmp::Ordering::*;
2862 ///
2863 /// let x = Float::from(PI);
2864 /// let y = Float::from(E);
2865 /// let z = Float::from(SQRT_2);
2866 /// let w = Float::from(LN_2);
2867 ///
2868 /// let (sum, o) = x
2869 /// .clone()
2870 /// .mul_add_mul_prec_val_ref_ref_val(&y, &z, w.clone(), 5);
2871 /// assert_eq!(sum.to_string(), "9.50");
2872 /// assert_eq!(o, Less);
2873 ///
2874 /// let (sum, o) = x
2875 /// .clone()
2876 /// .mul_add_mul_prec_val_ref_ref_val(&y, &z, w.clone(), 20);
2877 /// assert_eq!(sum.to_string(), "9.5199890");
2878 /// assert_eq!(o, Less);
2879 /// ```
2880 #[allow(clippy::needless_pass_by_value)]
2881 #[inline]
2882 pub fn mul_add_mul_prec_val_ref_ref_val(
2883 self,
2884 y: &Self,
2885 z: &Self,
2886 w: Self,
2887 prec: u64,
2888 ) -> (Self, Ordering) {
2889 self.mul_add_mul_prec_round_val_ref_ref_val(y, z, w, prec, Nearest)
2890 }
2891
2892 /// Adds the products of two pairs of [`Float`]s, rounding the result to the nearest value of
2893 /// the specified precision; the products are not rounded before the final addition, so there is
2894 /// a single rounding. The first [`Float`] is taken by value and the others by reference. An
2895 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
2896 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
2897 /// this function returns a `NaN` it also returns `Equal`.
2898 ///
2899 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2900 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2901 /// the `Nearest` rounding mode.
2902 ///
2903 /// $$
2904 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
2905 /// $$
2906 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2907 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2908 /// |xy+zw|\rfloor-p}$.
2909 ///
2910 /// If the output has a precision, it is `prec`.
2911 ///
2912 /// Special cases:
2913 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2914 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2915 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2916 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2917 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2918 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2919 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2920 /// - If exactly one product is infinite, the result is that product's infinity.
2921 /// - If both products are infinite, the result is their common infinity if their signs agree,
2922 /// and `NaN` otherwise.
2923 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
2924 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
2925 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
2926 ///
2927 /// Overflow and underflow:
2928 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2929 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2930 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2931 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2932 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2933 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2934 ///
2935 /// If you want to use a rounding mode other than `Nearest`, consider using
2936 /// [`Float::mul_add_mul_prec_round`] instead. If you know that your target precision is the
2937 /// maximum of the precisions of the inputs, consider using
2938 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
2939 ///
2940 /// # Worst-case complexity
2941 /// $T(n, m) = O(n \log n \log\log n + m)$
2942 ///
2943 /// $M(n, m) = O(n \log n + m)$
2944 ///
2945 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2946 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2947 /// `max(self.significant_bits(), prec)`.
2948 ///
2949 /// # Panics
2950 /// Panics if `prec` is zero.
2951 ///
2952 /// # Examples
2953 /// ```
2954 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2955 /// use malachite_float::Float;
2956 /// use std::cmp::Ordering::*;
2957 ///
2958 /// let x = Float::from(PI);
2959 /// let y = Float::from(E);
2960 /// let z = Float::from(SQRT_2);
2961 /// let w = Float::from(LN_2);
2962 ///
2963 /// let (sum, o) = x.clone().mul_add_mul_prec_val_ref_ref_ref(&y, &z, &w, 5);
2964 /// assert_eq!(sum.to_string(), "9.50");
2965 /// assert_eq!(o, Less);
2966 ///
2967 /// let (sum, o) = x.clone().mul_add_mul_prec_val_ref_ref_ref(&y, &z, &w, 20);
2968 /// assert_eq!(sum.to_string(), "9.5199890");
2969 /// assert_eq!(o, Less);
2970 /// ```
2971 #[allow(clippy::needless_pass_by_value)]
2972 #[inline]
2973 pub fn mul_add_mul_prec_val_ref_ref_ref(
2974 self,
2975 y: &Self,
2976 z: &Self,
2977 w: &Self,
2978 prec: u64,
2979 ) -> (Self, Ordering) {
2980 self.mul_add_mul_prec_round_val_ref_ref_ref(y, z, w, prec, Nearest)
2981 }
2982
2983 /// Adds the products of two pairs of [`Float`]s, rounding the result to the nearest value of
2984 /// the specified precision; the products are not rounded before the final addition, so there is
2985 /// a single rounding. All four [`Float`]s are taken by reference. An [`Ordering`] is also
2986 /// returned, indicating whether the rounded sum is less than, equal to, or greater than the
2987 /// exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
2988 /// returns a `NaN` it also returns `Equal`.
2989 ///
2990 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2991 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2992 /// the `Nearest` rounding mode.
2993 ///
2994 /// $$
2995 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
2996 /// $$
2997 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2998 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2999 /// |xy+zw|\rfloor-p}$.
3000 ///
3001 /// If the output has a precision, it is `prec`.
3002 ///
3003 /// Special cases:
3004 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
3005 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
3006 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
3007 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
3008 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
3009 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
3010 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
3011 /// - If exactly one product is infinite, the result is that product's infinity.
3012 /// - If both products are infinite, the result is their common infinity if their signs agree,
3013 /// and `NaN` otherwise.
3014 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
3015 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
3016 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
3017 ///
3018 /// Overflow and underflow:
3019 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
3020 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
3021 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
3022 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
3023 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
3024 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
3025 ///
3026 /// If you want to use a rounding mode other than `Nearest`, consider using
3027 /// [`Float::mul_add_mul_prec_round`] instead. If you know that your target precision is the
3028 /// maximum of the precisions of the inputs, consider using
3029 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
3030 ///
3031 /// # Worst-case complexity
3032 /// $T(n, m) = O(n \log n \log\log n + m)$
3033 ///
3034 /// $M(n, m) = O(n \log n + m)$
3035 ///
3036 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3037 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3038 /// `max(self.significant_bits(), prec)`.
3039 ///
3040 /// # Panics
3041 /// Panics if `prec` is zero.
3042 ///
3043 /// # Examples
3044 /// ```
3045 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3046 /// use malachite_float::Float;
3047 /// use std::cmp::Ordering::*;
3048 ///
3049 /// let x = Float::from(PI);
3050 /// let y = Float::from(E);
3051 /// let z = Float::from(SQRT_2);
3052 /// let w = Float::from(LN_2);
3053 ///
3054 /// let (sum, o) = x.mul_add_mul_prec_ref_ref_ref_ref(&y, &z, &w, 5);
3055 /// assert_eq!(sum.to_string(), "9.50");
3056 /// assert_eq!(o, Less);
3057 ///
3058 /// let (sum, o) = x.mul_add_mul_prec_ref_ref_ref_ref(&y, &z, &w, 20);
3059 /// assert_eq!(sum.to_string(), "9.5199890");
3060 /// assert_eq!(o, Less);
3061 /// ```
3062 #[allow(clippy::needless_pass_by_value)]
3063 #[inline]
3064 pub fn mul_add_mul_prec_ref_ref_ref_ref(
3065 &self,
3066 y: &Self,
3067 z: &Self,
3068 w: &Self,
3069 prec: u64,
3070 ) -> (Self, Ordering) {
3071 self.mul_add_mul_prec_round_ref_ref_ref_ref(y, z, w, prec, Nearest)
3072 }
3073
3074 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
3075 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
3076 /// specified precision. The [`Float`]s on the right-hand side are all taken by value. An
3077 /// [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
3078 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
3079 /// this function assigns a `NaN` it also returns `Equal`.
3080 ///
3081 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3082 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3083 /// the `Nearest` rounding mode.
3084 ///
3085 /// $$
3086 /// x \gets xy+zw+\varepsilon.
3087 /// $$
3088 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3089 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3090 /// |xy+zw|\rfloor-p}$.
3091 ///
3092 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
3093 /// overflow, and underflow.
3094 ///
3095 /// If you want to use a rounding mode other than `Nearest`, consider using
3096 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know that your target precision is
3097 /// the maximum of the precisions of the inputs, consider using
3098 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
3099 ///
3100 /// # Worst-case complexity
3101 /// $T(n, m) = O(n \log n \log\log n + m)$
3102 ///
3103 /// $M(n, m) = O(n \log n + m)$
3104 ///
3105 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3106 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3107 /// `max(self.significant_bits(), prec)`.
3108 ///
3109 /// # Panics
3110 /// Panics if `prec` is zero.
3111 ///
3112 /// # Examples
3113 /// ```
3114 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3115 /// use malachite_float::Float;
3116 /// use std::cmp::Ordering::*;
3117 ///
3118 /// let y = Float::from(E);
3119 /// let z = Float::from(SQRT_2);
3120 /// let w = Float::from(LN_2);
3121 ///
3122 /// let mut x = Float::from(PI);
3123 /// assert_eq!(
3124 /// x.mul_add_mul_prec_assign(y.clone(), z.clone(), w.clone(), 5),
3125 /// Less
3126 /// );
3127 /// assert_eq!(x.to_string(), "9.50");
3128 ///
3129 /// let mut x = Float::from(PI);
3130 /// assert_eq!(
3131 /// x.mul_add_mul_prec_assign(y.clone(), z.clone(), w.clone(), 20),
3132 /// Less
3133 /// );
3134 /// assert_eq!(x.to_string(), "9.5199890");
3135 /// ```
3136 #[allow(clippy::needless_pass_by_value)]
3137 #[inline]
3138 pub fn mul_add_mul_prec_assign(&mut self, y: Self, z: Self, w: Self, prec: u64) -> Ordering {
3139 self.mul_add_mul_prec_round_assign(y, z, w, prec, Nearest)
3140 }
3141
3142 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
3143 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
3144 /// specified precision. The last [`Float`] on the right-hand side is taken by reference and the
3145 /// others by value. An [`Ordering`] is returned, indicating whether the rounded sum is less
3146 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
3147 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
3148 ///
3149 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3150 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3151 /// the `Nearest` rounding mode.
3152 ///
3153 /// $$
3154 /// x \gets xy+zw+\varepsilon.
3155 /// $$
3156 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3157 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3158 /// |xy+zw|\rfloor-p}$.
3159 ///
3160 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
3161 /// overflow, and underflow.
3162 ///
3163 /// If you want to use a rounding mode other than `Nearest`, consider using
3164 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know that your target precision is
3165 /// the maximum of the precisions of the inputs, consider using
3166 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
3167 ///
3168 /// # Worst-case complexity
3169 /// $T(n, m) = O(n \log n \log\log n + m)$
3170 ///
3171 /// $M(n, m) = O(n \log n + m)$
3172 ///
3173 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3174 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3175 /// `max(self.significant_bits(), prec)`.
3176 ///
3177 /// # Panics
3178 /// Panics if `prec` is zero.
3179 ///
3180 /// # Examples
3181 /// ```
3182 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3183 /// use malachite_float::Float;
3184 /// use std::cmp::Ordering::*;
3185 ///
3186 /// let y = Float::from(E);
3187 /// let z = Float::from(SQRT_2);
3188 /// let w = Float::from(LN_2);
3189 ///
3190 /// let mut x = Float::from(PI);
3191 /// assert_eq!(
3192 /// x.mul_add_mul_prec_assign_val_val_ref(y.clone(), z.clone(), &w, 5),
3193 /// Less
3194 /// );
3195 /// assert_eq!(x.to_string(), "9.50");
3196 ///
3197 /// let mut x = Float::from(PI);
3198 /// assert_eq!(
3199 /// x.mul_add_mul_prec_assign_val_val_ref(y.clone(), z.clone(), &w, 20),
3200 /// Less
3201 /// );
3202 /// assert_eq!(x.to_string(), "9.5199890");
3203 /// ```
3204 #[allow(clippy::needless_pass_by_value)]
3205 #[inline]
3206 pub fn mul_add_mul_prec_assign_val_val_ref(
3207 &mut self,
3208 y: Self,
3209 z: Self,
3210 w: &Self,
3211 prec: u64,
3212 ) -> Ordering {
3213 self.mul_add_mul_prec_round_assign_val_val_ref(y, z, w, prec, Nearest)
3214 }
3215
3216 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
3217 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
3218 /// specified precision. The middle [`Float`] on the right-hand side is taken by reference and
3219 /// the others by value. An [`Ordering`] is returned, indicating whether the rounded sum is less
3220 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
3221 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
3222 ///
3223 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3224 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3225 /// the `Nearest` rounding mode.
3226 ///
3227 /// $$
3228 /// x \gets xy+zw+\varepsilon.
3229 /// $$
3230 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3231 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3232 /// |xy+zw|\rfloor-p}$.
3233 ///
3234 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
3235 /// overflow, and underflow.
3236 ///
3237 /// If you want to use a rounding mode other than `Nearest`, consider using
3238 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know that your target precision is
3239 /// the maximum of the precisions of the inputs, consider using
3240 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
3241 ///
3242 /// # Worst-case complexity
3243 /// $T(n, m) = O(n \log n \log\log n + m)$
3244 ///
3245 /// $M(n, m) = O(n \log n + m)$
3246 ///
3247 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3248 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3249 /// `max(self.significant_bits(), prec)`.
3250 ///
3251 /// # Panics
3252 /// Panics if `prec` is zero.
3253 ///
3254 /// # Examples
3255 /// ```
3256 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3257 /// use malachite_float::Float;
3258 /// use std::cmp::Ordering::*;
3259 ///
3260 /// let y = Float::from(E);
3261 /// let z = Float::from(SQRT_2);
3262 /// let w = Float::from(LN_2);
3263 ///
3264 /// let mut x = Float::from(PI);
3265 /// assert_eq!(
3266 /// x.mul_add_mul_prec_assign_val_ref_val(y.clone(), &z, w.clone(), 5),
3267 /// Less
3268 /// );
3269 /// assert_eq!(x.to_string(), "9.50");
3270 ///
3271 /// let mut x = Float::from(PI);
3272 /// assert_eq!(
3273 /// x.mul_add_mul_prec_assign_val_ref_val(y.clone(), &z, w.clone(), 20),
3274 /// Less
3275 /// );
3276 /// assert_eq!(x.to_string(), "9.5199890");
3277 /// ```
3278 #[allow(clippy::needless_pass_by_value)]
3279 #[inline]
3280 pub fn mul_add_mul_prec_assign_val_ref_val(
3281 &mut self,
3282 y: Self,
3283 z: &Self,
3284 w: Self,
3285 prec: u64,
3286 ) -> Ordering {
3287 self.mul_add_mul_prec_round_assign_val_ref_val(y, z, w, prec, Nearest)
3288 }
3289
3290 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
3291 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
3292 /// specified precision. The first [`Float`] on the right-hand side is taken by value and the
3293 /// others by reference. An [`Ordering`] is returned, indicating whether the rounded sum is less
3294 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
3295 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
3296 ///
3297 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3298 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3299 /// the `Nearest` rounding mode.
3300 ///
3301 /// $$
3302 /// x \gets xy+zw+\varepsilon.
3303 /// $$
3304 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3305 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3306 /// |xy+zw|\rfloor-p}$.
3307 ///
3308 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
3309 /// overflow, and underflow.
3310 ///
3311 /// If you want to use a rounding mode other than `Nearest`, consider using
3312 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know that your target precision is
3313 /// the maximum of the precisions of the inputs, consider using
3314 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
3315 ///
3316 /// # Worst-case complexity
3317 /// $T(n, m) = O(n \log n \log\log n + m)$
3318 ///
3319 /// $M(n, m) = O(n \log n + m)$
3320 ///
3321 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3322 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3323 /// `max(self.significant_bits(), prec)`.
3324 ///
3325 /// # Panics
3326 /// Panics if `prec` is zero.
3327 ///
3328 /// # Examples
3329 /// ```
3330 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3331 /// use malachite_float::Float;
3332 /// use std::cmp::Ordering::*;
3333 ///
3334 /// let y = Float::from(E);
3335 /// let z = Float::from(SQRT_2);
3336 /// let w = Float::from(LN_2);
3337 ///
3338 /// let mut x = Float::from(PI);
3339 /// assert_eq!(
3340 /// x.mul_add_mul_prec_assign_val_ref_ref(y.clone(), &z, &w, 5),
3341 /// Less
3342 /// );
3343 /// assert_eq!(x.to_string(), "9.50");
3344 ///
3345 /// let mut x = Float::from(PI);
3346 /// assert_eq!(
3347 /// x.mul_add_mul_prec_assign_val_ref_ref(y.clone(), &z, &w, 20),
3348 /// Less
3349 /// );
3350 /// assert_eq!(x.to_string(), "9.5199890");
3351 /// ```
3352 #[allow(clippy::needless_pass_by_value)]
3353 #[inline]
3354 pub fn mul_add_mul_prec_assign_val_ref_ref(
3355 &mut self,
3356 y: Self,
3357 z: &Self,
3358 w: &Self,
3359 prec: u64,
3360 ) -> Ordering {
3361 self.mul_add_mul_prec_round_assign_val_ref_ref(y, z, w, prec, Nearest)
3362 }
3363
3364 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
3365 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
3366 /// specified precision. The first [`Float`] on the right-hand side is taken by reference and
3367 /// the others by value. An [`Ordering`] is returned, indicating whether the rounded sum is less
3368 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
3369 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
3370 ///
3371 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3372 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3373 /// the `Nearest` rounding mode.
3374 ///
3375 /// $$
3376 /// x \gets xy+zw+\varepsilon.
3377 /// $$
3378 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3379 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3380 /// |xy+zw|\rfloor-p}$.
3381 ///
3382 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
3383 /// overflow, and underflow.
3384 ///
3385 /// If you want to use a rounding mode other than `Nearest`, consider using
3386 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know that your target precision is
3387 /// the maximum of the precisions of the inputs, consider using
3388 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
3389 ///
3390 /// # Worst-case complexity
3391 /// $T(n, m) = O(n \log n \log\log n + m)$
3392 ///
3393 /// $M(n, m) = O(n \log n + m)$
3394 ///
3395 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3396 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3397 /// `max(self.significant_bits(), prec)`.
3398 ///
3399 /// # Panics
3400 /// Panics if `prec` is zero.
3401 ///
3402 /// # Examples
3403 /// ```
3404 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3405 /// use malachite_float::Float;
3406 /// use std::cmp::Ordering::*;
3407 ///
3408 /// let y = Float::from(E);
3409 /// let z = Float::from(SQRT_2);
3410 /// let w = Float::from(LN_2);
3411 ///
3412 /// let mut x = Float::from(PI);
3413 /// assert_eq!(
3414 /// x.mul_add_mul_prec_assign_ref_val_val(&y, z.clone(), w.clone(), 5),
3415 /// Less
3416 /// );
3417 /// assert_eq!(x.to_string(), "9.50");
3418 ///
3419 /// let mut x = Float::from(PI);
3420 /// assert_eq!(
3421 /// x.mul_add_mul_prec_assign_ref_val_val(&y, z.clone(), w.clone(), 20),
3422 /// Less
3423 /// );
3424 /// assert_eq!(x.to_string(), "9.5199890");
3425 /// ```
3426 #[allow(clippy::needless_pass_by_value)]
3427 #[inline]
3428 pub fn mul_add_mul_prec_assign_ref_val_val(
3429 &mut self,
3430 y: &Self,
3431 z: Self,
3432 w: Self,
3433 prec: u64,
3434 ) -> Ordering {
3435 self.mul_add_mul_prec_round_assign_ref_val_val(y, z, w, prec, Nearest)
3436 }
3437
3438 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
3439 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
3440 /// specified precision. The middle [`Float`] on the right-hand side is taken by value and the
3441 /// others by reference. An [`Ordering`] is returned, indicating whether the rounded sum is less
3442 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
3443 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
3444 ///
3445 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3446 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3447 /// the `Nearest` rounding mode.
3448 ///
3449 /// $$
3450 /// x \gets xy+zw+\varepsilon.
3451 /// $$
3452 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3453 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3454 /// |xy+zw|\rfloor-p}$.
3455 ///
3456 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
3457 /// overflow, and underflow.
3458 ///
3459 /// If you want to use a rounding mode other than `Nearest`, consider using
3460 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know that your target precision is
3461 /// the maximum of the precisions of the inputs, consider using
3462 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
3463 ///
3464 /// # Worst-case complexity
3465 /// $T(n, m) = O(n \log n \log\log n + m)$
3466 ///
3467 /// $M(n, m) = O(n \log n + m)$
3468 ///
3469 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3470 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3471 /// `max(self.significant_bits(), prec)`.
3472 ///
3473 /// # Panics
3474 /// Panics if `prec` is zero.
3475 ///
3476 /// # Examples
3477 /// ```
3478 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3479 /// use malachite_float::Float;
3480 /// use std::cmp::Ordering::*;
3481 ///
3482 /// let y = Float::from(E);
3483 /// let z = Float::from(SQRT_2);
3484 /// let w = Float::from(LN_2);
3485 ///
3486 /// let mut x = Float::from(PI);
3487 /// assert_eq!(
3488 /// x.mul_add_mul_prec_assign_ref_val_ref(&y, z.clone(), &w, 5),
3489 /// Less
3490 /// );
3491 /// assert_eq!(x.to_string(), "9.50");
3492 ///
3493 /// let mut x = Float::from(PI);
3494 /// assert_eq!(
3495 /// x.mul_add_mul_prec_assign_ref_val_ref(&y, z.clone(), &w, 20),
3496 /// Less
3497 /// );
3498 /// assert_eq!(x.to_string(), "9.5199890");
3499 /// ```
3500 #[allow(clippy::needless_pass_by_value)]
3501 #[inline]
3502 pub fn mul_add_mul_prec_assign_ref_val_ref(
3503 &mut self,
3504 y: &Self,
3505 z: Self,
3506 w: &Self,
3507 prec: u64,
3508 ) -> Ordering {
3509 self.mul_add_mul_prec_round_assign_ref_val_ref(y, z, w, prec, Nearest)
3510 }
3511
3512 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
3513 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
3514 /// specified precision. The last [`Float`] on the right-hand side is taken by value and the
3515 /// others by reference. An [`Ordering`] is returned, indicating whether the rounded sum is less
3516 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
3517 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
3518 ///
3519 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3520 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3521 /// the `Nearest` rounding mode.
3522 ///
3523 /// $$
3524 /// x \gets xy+zw+\varepsilon.
3525 /// $$
3526 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3527 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3528 /// |xy+zw|\rfloor-p}$.
3529 ///
3530 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
3531 /// overflow, and underflow.
3532 ///
3533 /// If you want to use a rounding mode other than `Nearest`, consider using
3534 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know that your target precision is
3535 /// the maximum of the precisions of the inputs, consider using
3536 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) 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 `self.significant_bits() +
3544 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3545 /// `max(self.significant_bits(), prec)`.
3546 ///
3547 /// # Panics
3548 /// Panics if `prec` is zero.
3549 ///
3550 /// # Examples
3551 /// ```
3552 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3553 /// use malachite_float::Float;
3554 /// use std::cmp::Ordering::*;
3555 ///
3556 /// let y = Float::from(E);
3557 /// let z = Float::from(SQRT_2);
3558 /// let w = Float::from(LN_2);
3559 ///
3560 /// let mut x = Float::from(PI);
3561 /// assert_eq!(
3562 /// x.mul_add_mul_prec_assign_ref_ref_val(&y, &z, w.clone(), 5),
3563 /// Less
3564 /// );
3565 /// assert_eq!(x.to_string(), "9.50");
3566 ///
3567 /// let mut x = Float::from(PI);
3568 /// assert_eq!(
3569 /// x.mul_add_mul_prec_assign_ref_ref_val(&y, &z, w.clone(), 20),
3570 /// Less
3571 /// );
3572 /// assert_eq!(x.to_string(), "9.5199890");
3573 /// ```
3574 #[allow(clippy::needless_pass_by_value)]
3575 #[inline]
3576 pub fn mul_add_mul_prec_assign_ref_ref_val(
3577 &mut self,
3578 y: &Self,
3579 z: &Self,
3580 w: Self,
3581 prec: u64,
3582 ) -> Ordering {
3583 self.mul_add_mul_prec_round_assign_ref_ref_val(y, z, w, prec, Nearest)
3584 }
3585
3586 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
3587 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
3588 /// specified precision. The [`Float`]s on the right-hand side are all taken by reference. An
3589 /// [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
3590 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
3591 /// this function assigns a `NaN` it also returns `Equal`.
3592 ///
3593 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3594 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3595 /// the `Nearest` rounding mode.
3596 ///
3597 /// $$
3598 /// x \gets xy+zw+\varepsilon.
3599 /// $$
3600 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3601 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3602 /// |xy+zw|\rfloor-p}$.
3603 ///
3604 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
3605 /// overflow, and underflow.
3606 ///
3607 /// If you want to use a rounding mode other than `Nearest`, consider using
3608 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know that your target precision is
3609 /// the maximum of the precisions of the inputs, consider using
3610 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
3611 ///
3612 /// # Worst-case complexity
3613 /// $T(n, m) = O(n \log n \log\log n + m)$
3614 ///
3615 /// $M(n, m) = O(n \log n + m)$
3616 ///
3617 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3618 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3619 /// `max(self.significant_bits(), prec)`.
3620 ///
3621 /// # Panics
3622 /// Panics if `prec` is zero.
3623 ///
3624 /// # Examples
3625 /// ```
3626 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3627 /// use malachite_float::Float;
3628 /// use std::cmp::Ordering::*;
3629 ///
3630 /// let y = Float::from(E);
3631 /// let z = Float::from(SQRT_2);
3632 /// let w = Float::from(LN_2);
3633 ///
3634 /// let mut x = Float::from(PI);
3635 /// assert_eq!(x.mul_add_mul_prec_assign_ref_ref_ref(&y, &z, &w, 5), Less);
3636 /// assert_eq!(x.to_string(), "9.50");
3637 ///
3638 /// let mut x = Float::from(PI);
3639 /// assert_eq!(x.mul_add_mul_prec_assign_ref_ref_ref(&y, &z, &w, 20), Less);
3640 /// assert_eq!(x.to_string(), "9.5199890");
3641 /// ```
3642 #[allow(clippy::needless_pass_by_value)]
3643 #[inline]
3644 pub fn mul_add_mul_prec_assign_ref_ref_ref(
3645 &mut self,
3646 y: &Self,
3647 z: &Self,
3648 w: &Self,
3649 prec: u64,
3650 ) -> Ordering {
3651 self.mul_add_mul_prec_round_assign_ref_ref_ref(y, z, w, prec, Nearest)
3652 }
3653
3654 /// Adds the products of two pairs of [`Float`]s, rounding the result with the specified
3655 /// rounding mode; the products are not rounded before the final addition, so there is a single
3656 /// rounding. All four [`Float`]s are taken by value. An [`Ordering`] is also returned,
3657 /// indicating whether the rounded sum is less than, equal to, or greater than the exact sum.
3658 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
3659 /// it also returns `Equal`.
3660 ///
3661 /// The precision of the output is the maximum of the precisions of the inputs. See
3662 /// [`RoundingMode`] for a description of the possible rounding modes.
3663 ///
3664 /// $$
3665 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
3666 /// $$
3667 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3668 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3669 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3670 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3671 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3672 ///
3673 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3674 ///
3675 /// Special cases:
3676 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3677 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3678 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3679 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3680 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3681 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3682 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
3683 /// - If exactly one product is infinite, the result is that product's infinity.
3684 /// - If both products are infinite, the result is their common infinity if their signs agree,
3685 /// and `NaN` otherwise.
3686 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
3687 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
3688 /// `Floor`
3689 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
3690 ///
3691 /// Overflow and underflow:
3692 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3693 /// returned instead.
3694 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
3695 /// is returned instead, where `p` is the precision of the output.
3696 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3697 /// returned instead.
3698 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3699 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3700 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3701 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3702 /// instead.
3703 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3704 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
3705 /// returned instead.
3706 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3707 /// instead.
3708 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3709 /// instead.
3710 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3711 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3712 /// returned instead.
3713 ///
3714 /// If you want to specify an output precision, consider using [`Float::mul_add_mul_prec_round`]
3715 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3716 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
3717 ///
3718 /// # Worst-case complexity
3719 /// $T(n, m) = O(n \log n \log\log n + m)$
3720 ///
3721 /// $M(n, m) = O(n \log n + m)$
3722 ///
3723 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3724 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3725 /// `self.significant_bits()`.
3726 ///
3727 /// # Panics
3728 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3729 /// represent the output.
3730 ///
3731 /// # Examples
3732 /// ```
3733 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3734 /// use malachite_base::rounding_modes::RoundingMode::*;
3735 /// use malachite_float::Float;
3736 /// use std::cmp::Ordering::*;
3737 ///
3738 /// let x = Float::from(PI);
3739 /// let y = Float::from(E);
3740 /// let z = Float::from(SQRT_2);
3741 /// let w = Float::from(LN_2);
3742 ///
3743 /// let (sum, o) = x
3744 /// .clone()
3745 /// .mul_add_mul_round(y.clone(), z.clone(), w.clone(), Floor);
3746 /// assert_eq!(sum.to_string(), "9.5199923661421124");
3747 /// assert_eq!(o, Less);
3748 ///
3749 /// let (sum, o) = x
3750 /// .clone()
3751 /// .mul_add_mul_round(y.clone(), z.clone(), w.clone(), Ceiling);
3752 /// assert_eq!(sum.to_string(), "9.5199923661421142");
3753 /// assert_eq!(o, Greater);
3754 ///
3755 /// let (sum, o) = x
3756 /// .clone()
3757 /// .mul_add_mul_round(y.clone(), z.clone(), w.clone(), Nearest);
3758 /// assert_eq!(sum.to_string(), "9.5199923661421142");
3759 /// assert_eq!(o, Greater);
3760 /// ```
3761 #[allow(clippy::needless_pass_by_value)]
3762 #[inline]
3763 pub fn mul_add_mul_round(
3764 self,
3765 y: Self,
3766 z: Self,
3767 w: Self,
3768 rm: RoundingMode,
3769 ) -> (Self, Ordering) {
3770 let prec = max!(
3771 self.significant_bits(),
3772 y.significant_bits(),
3773 z.significant_bits(),
3774 w.significant_bits()
3775 );
3776 self.mul_add_mul_prec_round(y, z, w, prec, rm)
3777 }
3778
3779 /// Adds the products of two pairs of [`Float`]s, rounding the result with the specified
3780 /// rounding mode; the products are not rounded before the final addition, so there is a single
3781 /// rounding. The first three [`Float`]s are taken by value and the fourth by reference. An
3782 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
3783 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
3784 /// this function returns a `NaN` it also returns `Equal`.
3785 ///
3786 /// The precision of the output is the maximum of the precisions of the inputs. See
3787 /// [`RoundingMode`] for a description of the possible rounding modes.
3788 ///
3789 /// $$
3790 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
3791 /// $$
3792 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3793 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3794 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3795 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3796 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3797 ///
3798 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3799 ///
3800 /// Special cases:
3801 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3802 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3803 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3804 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3805 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3806 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3807 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
3808 /// - If exactly one product is infinite, the result is that product's infinity.
3809 /// - If both products are infinite, the result is their common infinity if their signs agree,
3810 /// and `NaN` otherwise.
3811 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
3812 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
3813 /// `Floor`
3814 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
3815 ///
3816 /// Overflow and underflow:
3817 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3818 /// returned instead.
3819 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
3820 /// is returned instead, where `p` is the precision of the output.
3821 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3822 /// returned instead.
3823 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3824 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3825 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3826 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3827 /// instead.
3828 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3829 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
3830 /// returned instead.
3831 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3832 /// instead.
3833 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3834 /// instead.
3835 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3836 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3837 /// returned instead.
3838 ///
3839 /// If you want to specify an output precision, consider using [`Float::mul_add_mul_prec_round`]
3840 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3841 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
3842 ///
3843 /// # Worst-case complexity
3844 /// $T(n, m) = O(n \log n \log\log n + m)$
3845 ///
3846 /// $M(n, m) = O(n \log n + m)$
3847 ///
3848 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3849 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3850 /// `self.significant_bits()`.
3851 ///
3852 /// # Panics
3853 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3854 /// represent the output.
3855 ///
3856 /// # Examples
3857 /// ```
3858 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3859 /// use malachite_base::rounding_modes::RoundingMode::*;
3860 /// use malachite_float::Float;
3861 /// use std::cmp::Ordering::*;
3862 ///
3863 /// let x = Float::from(PI);
3864 /// let y = Float::from(E);
3865 /// let z = Float::from(SQRT_2);
3866 /// let w = Float::from(LN_2);
3867 ///
3868 /// let (sum, o) = x
3869 /// .clone()
3870 /// .mul_add_mul_round_val_val_val_ref(y.clone(), z.clone(), &w, Floor);
3871 /// assert_eq!(sum.to_string(), "9.5199923661421124");
3872 /// assert_eq!(o, Less);
3873 ///
3874 /// let (sum, o) =
3875 /// x.clone()
3876 /// .mul_add_mul_round_val_val_val_ref(y.clone(), z.clone(), &w, Ceiling);
3877 /// assert_eq!(sum.to_string(), "9.5199923661421142");
3878 /// assert_eq!(o, Greater);
3879 ///
3880 /// let (sum, o) =
3881 /// x.clone()
3882 /// .mul_add_mul_round_val_val_val_ref(y.clone(), z.clone(), &w, Nearest);
3883 /// assert_eq!(sum.to_string(), "9.5199923661421142");
3884 /// assert_eq!(o, Greater);
3885 /// ```
3886 #[allow(clippy::needless_pass_by_value)]
3887 #[inline]
3888 pub fn mul_add_mul_round_val_val_val_ref(
3889 self,
3890 y: Self,
3891 z: Self,
3892 w: &Self,
3893 rm: RoundingMode,
3894 ) -> (Self, Ordering) {
3895 let prec = max!(
3896 self.significant_bits(),
3897 y.significant_bits(),
3898 z.significant_bits(),
3899 w.significant_bits()
3900 );
3901 self.mul_add_mul_prec_round_val_val_val_ref(y, z, w, prec, rm)
3902 }
3903
3904 /// Adds the products of two pairs of [`Float`]s, rounding the result with the specified
3905 /// rounding mode; the products are not rounded before the final addition, so there is a single
3906 /// rounding. The third [`Float`] is taken by reference and the others by value. An [`Ordering`]
3907 /// is also returned, indicating whether the rounded sum is less than, equal to, or greater than
3908 /// the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
3909 /// returns a `NaN` it also returns `Equal`.
3910 ///
3911 /// The precision of the output is the maximum of the precisions of the inputs. See
3912 /// [`RoundingMode`] for a description of the possible rounding modes.
3913 ///
3914 /// $$
3915 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
3916 /// $$
3917 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3918 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3919 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3920 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3921 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3922 ///
3923 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3924 ///
3925 /// Special cases:
3926 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3927 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3928 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3929 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3930 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3931 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3932 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
3933 /// - If exactly one product is infinite, the result is that product's infinity.
3934 /// - If both products are infinite, the result is their common infinity if their signs agree,
3935 /// and `NaN` otherwise.
3936 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
3937 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
3938 /// `Floor`
3939 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
3940 ///
3941 /// Overflow and underflow:
3942 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3943 /// returned instead.
3944 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
3945 /// is returned instead, where `p` is the precision of the output.
3946 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3947 /// returned instead.
3948 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3949 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3950 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3951 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3952 /// instead.
3953 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3954 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
3955 /// returned instead.
3956 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3957 /// instead.
3958 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3959 /// instead.
3960 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3961 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3962 /// returned instead.
3963 ///
3964 /// If you want to specify an output precision, consider using [`Float::mul_add_mul_prec_round`]
3965 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3966 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
3967 ///
3968 /// # Worst-case complexity
3969 /// $T(n, m) = O(n \log n \log\log n + m)$
3970 ///
3971 /// $M(n, m) = O(n \log n + m)$
3972 ///
3973 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3974 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3975 /// `self.significant_bits()`.
3976 ///
3977 /// # Panics
3978 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3979 /// represent the output.
3980 ///
3981 /// # Examples
3982 /// ```
3983 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3984 /// use malachite_base::rounding_modes::RoundingMode::*;
3985 /// use malachite_float::Float;
3986 /// use std::cmp::Ordering::*;
3987 ///
3988 /// let x = Float::from(PI);
3989 /// let y = Float::from(E);
3990 /// let z = Float::from(SQRT_2);
3991 /// let w = Float::from(LN_2);
3992 ///
3993 /// let (sum, o) = x
3994 /// .clone()
3995 /// .mul_add_mul_round_val_val_ref_val(y.clone(), &z, w.clone(), Floor);
3996 /// assert_eq!(sum.to_string(), "9.5199923661421124");
3997 /// assert_eq!(o, Less);
3998 ///
3999 /// let (sum, o) =
4000 /// x.clone()
4001 /// .mul_add_mul_round_val_val_ref_val(y.clone(), &z, w.clone(), Ceiling);
4002 /// assert_eq!(sum.to_string(), "9.5199923661421142");
4003 /// assert_eq!(o, Greater);
4004 ///
4005 /// let (sum, o) =
4006 /// x.clone()
4007 /// .mul_add_mul_round_val_val_ref_val(y.clone(), &z, w.clone(), Nearest);
4008 /// assert_eq!(sum.to_string(), "9.5199923661421142");
4009 /// assert_eq!(o, Greater);
4010 /// ```
4011 #[allow(clippy::needless_pass_by_value)]
4012 #[inline]
4013 pub fn mul_add_mul_round_val_val_ref_val(
4014 self,
4015 y: Self,
4016 z: &Self,
4017 w: Self,
4018 rm: RoundingMode,
4019 ) -> (Self, Ordering) {
4020 let prec = max!(
4021 self.significant_bits(),
4022 y.significant_bits(),
4023 z.significant_bits(),
4024 w.significant_bits()
4025 );
4026 self.mul_add_mul_prec_round_val_val_ref_val(y, z, w, prec, rm)
4027 }
4028
4029 /// Adds the products of two pairs of [`Float`]s, rounding the result with the specified
4030 /// rounding mode; the products are not rounded before the final addition, so there is a single
4031 /// rounding. The first two [`Float`]s are taken by value and the last two by reference. An
4032 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
4033 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
4034 /// this function returns a `NaN` it also returns `Equal`.
4035 ///
4036 /// The precision of the output is the maximum of the precisions of the inputs. See
4037 /// [`RoundingMode`] for a description of the possible rounding modes.
4038 ///
4039 /// $$
4040 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
4041 /// $$
4042 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4043 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4044 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4045 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4046 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4047 ///
4048 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4049 ///
4050 /// Special cases:
4051 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4052 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4053 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4054 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4055 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4056 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4057 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
4058 /// - If exactly one product is infinite, the result is that product's infinity.
4059 /// - If both products are infinite, the result is their common infinity if their signs agree,
4060 /// and `NaN` otherwise.
4061 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
4062 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
4063 /// `Floor`
4064 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
4065 ///
4066 /// Overflow and underflow:
4067 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4068 /// returned instead.
4069 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
4070 /// is returned instead, where `p` is the precision of the output.
4071 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4072 /// returned instead.
4073 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4074 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4075 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4076 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4077 /// instead.
4078 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4079 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4080 /// returned instead.
4081 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4082 /// instead.
4083 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4084 /// instead.
4085 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4086 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4087 /// returned instead.
4088 ///
4089 /// If you want to specify an output precision, consider using [`Float::mul_add_mul_prec_round`]
4090 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
4091 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
4092 ///
4093 /// # Worst-case complexity
4094 /// $T(n, m) = O(n \log n \log\log n + m)$
4095 ///
4096 /// $M(n, m) = O(n \log n + m)$
4097 ///
4098 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4099 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4100 /// `self.significant_bits()`.
4101 ///
4102 /// # Panics
4103 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4104 /// represent the output.
4105 ///
4106 /// # Examples
4107 /// ```
4108 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4109 /// use malachite_base::rounding_modes::RoundingMode::*;
4110 /// use malachite_float::Float;
4111 /// use std::cmp::Ordering::*;
4112 ///
4113 /// let x = Float::from(PI);
4114 /// let y = Float::from(E);
4115 /// let z = Float::from(SQRT_2);
4116 /// let w = Float::from(LN_2);
4117 ///
4118 /// let (sum, o) = x
4119 /// .clone()
4120 /// .mul_add_mul_round_val_val_ref_ref(y.clone(), &z, &w, Floor);
4121 /// assert_eq!(sum.to_string(), "9.5199923661421124");
4122 /// assert_eq!(o, Less);
4123 ///
4124 /// let (sum, o) = x
4125 /// .clone()
4126 /// .mul_add_mul_round_val_val_ref_ref(y.clone(), &z, &w, Ceiling);
4127 /// assert_eq!(sum.to_string(), "9.5199923661421142");
4128 /// assert_eq!(o, Greater);
4129 ///
4130 /// let (sum, o) = x
4131 /// .clone()
4132 /// .mul_add_mul_round_val_val_ref_ref(y.clone(), &z, &w, Nearest);
4133 /// assert_eq!(sum.to_string(), "9.5199923661421142");
4134 /// assert_eq!(o, Greater);
4135 /// ```
4136 #[allow(clippy::needless_pass_by_value)]
4137 #[inline]
4138 pub fn mul_add_mul_round_val_val_ref_ref(
4139 self,
4140 y: Self,
4141 z: &Self,
4142 w: &Self,
4143 rm: RoundingMode,
4144 ) -> (Self, Ordering) {
4145 let prec = max!(
4146 self.significant_bits(),
4147 y.significant_bits(),
4148 z.significant_bits(),
4149 w.significant_bits()
4150 );
4151 self.mul_add_mul_prec_round_val_val_ref_ref(y, z, w, prec, rm)
4152 }
4153
4154 /// Adds the products of two pairs of [`Float`]s, rounding the result with the specified
4155 /// rounding mode; the products are not rounded before the final addition, so there is a single
4156 /// rounding. The second [`Float`] is taken by reference and the others by value. An
4157 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
4158 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
4159 /// this function returns a `NaN` it also returns `Equal`.
4160 ///
4161 /// The precision of the output is the maximum of the precisions of the inputs. See
4162 /// [`RoundingMode`] for a description of the possible rounding modes.
4163 ///
4164 /// $$
4165 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
4166 /// $$
4167 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4168 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4169 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4170 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4171 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4172 ///
4173 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4174 ///
4175 /// Special cases:
4176 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4177 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4178 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4179 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4180 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4181 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4182 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
4183 /// - If exactly one product is infinite, the result is that product's infinity.
4184 /// - If both products are infinite, the result is their common infinity if their signs agree,
4185 /// and `NaN` otherwise.
4186 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
4187 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
4188 /// `Floor`
4189 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
4190 ///
4191 /// Overflow and underflow:
4192 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4193 /// returned instead.
4194 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
4195 /// is returned instead, where `p` is the precision of the output.
4196 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4197 /// returned instead.
4198 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4199 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4200 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4201 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4202 /// instead.
4203 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4204 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4205 /// returned instead.
4206 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4207 /// instead.
4208 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4209 /// instead.
4210 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4211 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4212 /// returned instead.
4213 ///
4214 /// If you want to specify an output precision, consider using [`Float::mul_add_mul_prec_round`]
4215 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
4216 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
4217 ///
4218 /// # Worst-case complexity
4219 /// $T(n, m) = O(n \log n \log\log n + m)$
4220 ///
4221 /// $M(n, m) = O(n \log n + m)$
4222 ///
4223 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4224 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4225 /// `self.significant_bits()`.
4226 ///
4227 /// # Panics
4228 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4229 /// represent the output.
4230 ///
4231 /// # Examples
4232 /// ```
4233 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4234 /// use malachite_base::rounding_modes::RoundingMode::*;
4235 /// use malachite_float::Float;
4236 /// use std::cmp::Ordering::*;
4237 ///
4238 /// let x = Float::from(PI);
4239 /// let y = Float::from(E);
4240 /// let z = Float::from(SQRT_2);
4241 /// let w = Float::from(LN_2);
4242 ///
4243 /// let (sum, o) = x
4244 /// .clone()
4245 /// .mul_add_mul_round_val_ref_val_val(&y, z.clone(), w.clone(), Floor);
4246 /// assert_eq!(sum.to_string(), "9.5199923661421124");
4247 /// assert_eq!(o, Less);
4248 ///
4249 /// let (sum, o) =
4250 /// x.clone()
4251 /// .mul_add_mul_round_val_ref_val_val(&y, z.clone(), w.clone(), Ceiling);
4252 /// assert_eq!(sum.to_string(), "9.5199923661421142");
4253 /// assert_eq!(o, Greater);
4254 ///
4255 /// let (sum, o) =
4256 /// x.clone()
4257 /// .mul_add_mul_round_val_ref_val_val(&y, z.clone(), w.clone(), Nearest);
4258 /// assert_eq!(sum.to_string(), "9.5199923661421142");
4259 /// assert_eq!(o, Greater);
4260 /// ```
4261 #[allow(clippy::needless_pass_by_value)]
4262 #[inline]
4263 pub fn mul_add_mul_round_val_ref_val_val(
4264 self,
4265 y: &Self,
4266 z: Self,
4267 w: Self,
4268 rm: RoundingMode,
4269 ) -> (Self, Ordering) {
4270 let prec = max!(
4271 self.significant_bits(),
4272 y.significant_bits(),
4273 z.significant_bits(),
4274 w.significant_bits()
4275 );
4276 self.mul_add_mul_prec_round_val_ref_val_val(y, z, w, prec, rm)
4277 }
4278
4279 /// Adds the products of two pairs of [`Float`]s, rounding the result with the specified
4280 /// rounding mode; the products are not rounded before the final addition, so there is a single
4281 /// rounding. The second and fourth [`Float`]s are taken by reference and the others by value.
4282 /// An [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to,
4283 /// or greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
4284 /// this function returns a `NaN` it also returns `Equal`.
4285 ///
4286 /// The precision of the output is the maximum of the precisions of the inputs. See
4287 /// [`RoundingMode`] for a description of the possible rounding modes.
4288 ///
4289 /// $$
4290 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
4291 /// $$
4292 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4293 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4294 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4295 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4296 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4297 ///
4298 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4299 ///
4300 /// Special cases:
4301 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4302 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4303 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4304 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4305 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4306 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4307 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
4308 /// - If exactly one product is infinite, the result is that product's infinity.
4309 /// - If both products are infinite, the result is their common infinity if their signs agree,
4310 /// and `NaN` otherwise.
4311 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
4312 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
4313 /// `Floor`
4314 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
4315 ///
4316 /// Overflow and underflow:
4317 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4318 /// returned instead.
4319 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
4320 /// is returned instead, where `p` is the precision of the output.
4321 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4322 /// returned instead.
4323 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4324 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4325 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4326 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4327 /// instead.
4328 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4329 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4330 /// returned instead.
4331 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4332 /// instead.
4333 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4334 /// instead.
4335 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4336 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4337 /// returned instead.
4338 ///
4339 /// If you want to specify an output precision, consider using [`Float::mul_add_mul_prec_round`]
4340 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
4341 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
4342 ///
4343 /// # Worst-case complexity
4344 /// $T(n, m) = O(n \log n \log\log n + m)$
4345 ///
4346 /// $M(n, m) = O(n \log n + m)$
4347 ///
4348 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4349 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4350 /// `self.significant_bits()`.
4351 ///
4352 /// # Panics
4353 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4354 /// represent the output.
4355 ///
4356 /// # Examples
4357 /// ```
4358 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4359 /// use malachite_base::rounding_modes::RoundingMode::*;
4360 /// use malachite_float::Float;
4361 /// use std::cmp::Ordering::*;
4362 ///
4363 /// let x = Float::from(PI);
4364 /// let y = Float::from(E);
4365 /// let z = Float::from(SQRT_2);
4366 /// let w = Float::from(LN_2);
4367 ///
4368 /// let (sum, o) = x
4369 /// .clone()
4370 /// .mul_add_mul_round_val_ref_val_ref(&y, z.clone(), &w, Floor);
4371 /// assert_eq!(sum.to_string(), "9.5199923661421124");
4372 /// assert_eq!(o, Less);
4373 ///
4374 /// let (sum, o) = x
4375 /// .clone()
4376 /// .mul_add_mul_round_val_ref_val_ref(&y, z.clone(), &w, Ceiling);
4377 /// assert_eq!(sum.to_string(), "9.5199923661421142");
4378 /// assert_eq!(o, Greater);
4379 ///
4380 /// let (sum, o) = x
4381 /// .clone()
4382 /// .mul_add_mul_round_val_ref_val_ref(&y, z.clone(), &w, Nearest);
4383 /// assert_eq!(sum.to_string(), "9.5199923661421142");
4384 /// assert_eq!(o, Greater);
4385 /// ```
4386 #[allow(clippy::needless_pass_by_value)]
4387 #[inline]
4388 pub fn mul_add_mul_round_val_ref_val_ref(
4389 self,
4390 y: &Self,
4391 z: Self,
4392 w: &Self,
4393 rm: RoundingMode,
4394 ) -> (Self, Ordering) {
4395 let prec = max!(
4396 self.significant_bits(),
4397 y.significant_bits(),
4398 z.significant_bits(),
4399 w.significant_bits()
4400 );
4401 self.mul_add_mul_prec_round_val_ref_val_ref(y, z, w, prec, rm)
4402 }
4403
4404 /// Adds the products of two pairs of [`Float`]s, rounding the result with the specified
4405 /// rounding mode; the products are not rounded before the final addition, so there is a single
4406 /// rounding. The second and third [`Float`]s are taken by reference and the others by value. An
4407 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
4408 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
4409 /// this function returns a `NaN` it also returns `Equal`.
4410 ///
4411 /// The precision of the output is the maximum of the precisions of the inputs. See
4412 /// [`RoundingMode`] for a description of the possible rounding modes.
4413 ///
4414 /// $$
4415 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
4416 /// $$
4417 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4418 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4419 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4420 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4421 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4422 ///
4423 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4424 ///
4425 /// Special cases:
4426 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4427 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4428 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4429 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4430 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4431 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4432 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
4433 /// - If exactly one product is infinite, the result is that product's infinity.
4434 /// - If both products are infinite, the result is their common infinity if their signs agree,
4435 /// and `NaN` otherwise.
4436 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
4437 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
4438 /// `Floor`
4439 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
4440 ///
4441 /// Overflow and underflow:
4442 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4443 /// returned instead.
4444 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
4445 /// is returned instead, where `p` is the precision of the output.
4446 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4447 /// returned instead.
4448 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4449 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4450 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4451 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4452 /// instead.
4453 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4454 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4455 /// returned instead.
4456 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4457 /// instead.
4458 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4459 /// instead.
4460 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4461 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4462 /// returned instead.
4463 ///
4464 /// If you want to specify an output precision, consider using [`Float::mul_add_mul_prec_round`]
4465 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
4466 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
4467 ///
4468 /// # Worst-case complexity
4469 /// $T(n, m) = O(n \log n \log\log n + m)$
4470 ///
4471 /// $M(n, m) = O(n \log n + m)$
4472 ///
4473 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4474 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4475 /// `self.significant_bits()`.
4476 ///
4477 /// # Panics
4478 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4479 /// represent the output.
4480 ///
4481 /// # Examples
4482 /// ```
4483 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4484 /// use malachite_base::rounding_modes::RoundingMode::*;
4485 /// use malachite_float::Float;
4486 /// use std::cmp::Ordering::*;
4487 ///
4488 /// let x = Float::from(PI);
4489 /// let y = Float::from(E);
4490 /// let z = Float::from(SQRT_2);
4491 /// let w = Float::from(LN_2);
4492 ///
4493 /// let (sum, o) = x
4494 /// .clone()
4495 /// .mul_add_mul_round_val_ref_ref_val(&y, &z, w.clone(), Floor);
4496 /// assert_eq!(sum.to_string(), "9.5199923661421124");
4497 /// assert_eq!(o, Less);
4498 ///
4499 /// let (sum, o) = x
4500 /// .clone()
4501 /// .mul_add_mul_round_val_ref_ref_val(&y, &z, w.clone(), Ceiling);
4502 /// assert_eq!(sum.to_string(), "9.5199923661421142");
4503 /// assert_eq!(o, Greater);
4504 ///
4505 /// let (sum, o) = x
4506 /// .clone()
4507 /// .mul_add_mul_round_val_ref_ref_val(&y, &z, w.clone(), Nearest);
4508 /// assert_eq!(sum.to_string(), "9.5199923661421142");
4509 /// assert_eq!(o, Greater);
4510 /// ```
4511 #[allow(clippy::needless_pass_by_value)]
4512 #[inline]
4513 pub fn mul_add_mul_round_val_ref_ref_val(
4514 self,
4515 y: &Self,
4516 z: &Self,
4517 w: Self,
4518 rm: RoundingMode,
4519 ) -> (Self, Ordering) {
4520 let prec = max!(
4521 self.significant_bits(),
4522 y.significant_bits(),
4523 z.significant_bits(),
4524 w.significant_bits()
4525 );
4526 self.mul_add_mul_prec_round_val_ref_ref_val(y, z, w, prec, rm)
4527 }
4528
4529 /// Adds the products of two pairs of [`Float`]s, rounding the result with the specified
4530 /// rounding mode; the products are not rounded before the final addition, so there is a single
4531 /// rounding. The first [`Float`] is taken by value and the others by reference. An [`Ordering`]
4532 /// is also returned, indicating whether the rounded sum is less than, equal to, or greater than
4533 /// the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
4534 /// returns a `NaN` it also returns `Equal`.
4535 ///
4536 /// The precision of the output is the maximum of the precisions of the inputs. See
4537 /// [`RoundingMode`] for a description of the possible rounding modes.
4538 ///
4539 /// $$
4540 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
4541 /// $$
4542 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4543 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4544 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4545 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4546 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4547 ///
4548 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4549 ///
4550 /// Special cases:
4551 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4552 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4553 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4554 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4555 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4556 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4557 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
4558 /// - If exactly one product is infinite, the result is that product's infinity.
4559 /// - If both products are infinite, the result is their common infinity if their signs agree,
4560 /// and `NaN` otherwise.
4561 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
4562 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
4563 /// `Floor`
4564 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
4565 ///
4566 /// Overflow and underflow:
4567 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4568 /// returned instead.
4569 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
4570 /// is returned instead, where `p` is the precision of the output.
4571 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4572 /// returned instead.
4573 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4574 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4575 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4576 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4577 /// instead.
4578 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4579 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4580 /// returned instead.
4581 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4582 /// instead.
4583 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4584 /// instead.
4585 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4586 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4587 /// returned instead.
4588 ///
4589 /// If you want to specify an output precision, consider using [`Float::mul_add_mul_prec_round`]
4590 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
4591 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
4592 ///
4593 /// # Worst-case complexity
4594 /// $T(n, m) = O(n \log n \log\log n + m)$
4595 ///
4596 /// $M(n, m) = O(n \log n + m)$
4597 ///
4598 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4599 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4600 /// `self.significant_bits()`.
4601 ///
4602 /// # Panics
4603 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4604 /// represent the output.
4605 ///
4606 /// # Examples
4607 /// ```
4608 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4609 /// use malachite_base::rounding_modes::RoundingMode::*;
4610 /// use malachite_float::Float;
4611 /// use std::cmp::Ordering::*;
4612 ///
4613 /// let x = Float::from(PI);
4614 /// let y = Float::from(E);
4615 /// let z = Float::from(SQRT_2);
4616 /// let w = Float::from(LN_2);
4617 ///
4618 /// let (sum, o) = x
4619 /// .clone()
4620 /// .mul_add_mul_round_val_ref_ref_ref(&y, &z, &w, Floor);
4621 /// assert_eq!(sum.to_string(), "9.5199923661421124");
4622 /// assert_eq!(o, Less);
4623 ///
4624 /// let (sum, o) = x
4625 /// .clone()
4626 /// .mul_add_mul_round_val_ref_ref_ref(&y, &z, &w, Ceiling);
4627 /// assert_eq!(sum.to_string(), "9.5199923661421142");
4628 /// assert_eq!(o, Greater);
4629 ///
4630 /// let (sum, o) = x
4631 /// .clone()
4632 /// .mul_add_mul_round_val_ref_ref_ref(&y, &z, &w, Nearest);
4633 /// assert_eq!(sum.to_string(), "9.5199923661421142");
4634 /// assert_eq!(o, Greater);
4635 /// ```
4636 #[allow(clippy::needless_pass_by_value)]
4637 #[inline]
4638 pub fn mul_add_mul_round_val_ref_ref_ref(
4639 self,
4640 y: &Self,
4641 z: &Self,
4642 w: &Self,
4643 rm: RoundingMode,
4644 ) -> (Self, Ordering) {
4645 let prec = max!(
4646 self.significant_bits(),
4647 y.significant_bits(),
4648 z.significant_bits(),
4649 w.significant_bits()
4650 );
4651 self.mul_add_mul_prec_round_val_ref_ref_ref(y, z, w, prec, rm)
4652 }
4653
4654 /// Adds the products of two pairs of [`Float`]s, rounding the result with the specified
4655 /// rounding mode; the products are not rounded before the final addition, so there is a single
4656 /// rounding. All four [`Float`]s are taken by reference. An [`Ordering`] is also returned,
4657 /// indicating whether the rounded sum is less than, equal to, or greater than the exact sum.
4658 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
4659 /// it also returns `Equal`.
4660 ///
4661 /// The precision of the output is the maximum of the precisions of the inputs. See
4662 /// [`RoundingMode`] for a description of the possible rounding modes.
4663 ///
4664 /// $$
4665 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
4666 /// $$
4667 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4668 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4669 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4670 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4671 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4672 ///
4673 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4674 ///
4675 /// Special cases:
4676 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4677 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4678 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4679 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4680 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4681 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4682 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
4683 /// - If exactly one product is infinite, the result is that product's infinity.
4684 /// - If both products are infinite, the result is their common infinity if their signs agree,
4685 /// and `NaN` otherwise.
4686 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
4687 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
4688 /// `Floor`
4689 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
4690 ///
4691 /// Overflow and underflow:
4692 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4693 /// returned instead.
4694 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
4695 /// is returned instead, where `p` is the precision of the output.
4696 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4697 /// returned instead.
4698 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4699 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4700 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4701 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4702 /// instead.
4703 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4704 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4705 /// returned instead.
4706 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4707 /// instead.
4708 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4709 /// instead.
4710 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4711 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4712 /// returned instead.
4713 ///
4714 /// If you want to specify an output precision, consider using [`Float::mul_add_mul_prec_round`]
4715 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
4716 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
4717 ///
4718 /// # Worst-case complexity
4719 /// $T(n, m) = O(n \log n \log\log n + m)$
4720 ///
4721 /// $M(n, m) = O(n \log n + m)$
4722 ///
4723 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4724 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4725 /// `self.significant_bits()`.
4726 ///
4727 /// # Panics
4728 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4729 /// represent the output.
4730 ///
4731 /// # Examples
4732 /// ```
4733 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4734 /// use malachite_base::rounding_modes::RoundingMode::*;
4735 /// use malachite_float::Float;
4736 /// use std::cmp::Ordering::*;
4737 ///
4738 /// let x = Float::from(PI);
4739 /// let y = Float::from(E);
4740 /// let z = Float::from(SQRT_2);
4741 /// let w = Float::from(LN_2);
4742 ///
4743 /// let (sum, o) = x.mul_add_mul_round_ref_ref_ref_ref(&y, &z, &w, Floor);
4744 /// assert_eq!(sum.to_string(), "9.5199923661421124");
4745 /// assert_eq!(o, Less);
4746 ///
4747 /// let (sum, o) = x.mul_add_mul_round_ref_ref_ref_ref(&y, &z, &w, Ceiling);
4748 /// assert_eq!(sum.to_string(), "9.5199923661421142");
4749 /// assert_eq!(o, Greater);
4750 ///
4751 /// let (sum, o) = x.mul_add_mul_round_ref_ref_ref_ref(&y, &z, &w, Nearest);
4752 /// assert_eq!(sum.to_string(), "9.5199923661421142");
4753 /// assert_eq!(o, Greater);
4754 /// ```
4755 #[allow(clippy::needless_pass_by_value)]
4756 #[inline]
4757 pub fn mul_add_mul_round_ref_ref_ref_ref(
4758 &self,
4759 y: &Self,
4760 z: &Self,
4761 w: &Self,
4762 rm: RoundingMode,
4763 ) -> (Self, Ordering) {
4764 let prec = max!(
4765 self.significant_bits(),
4766 y.significant_bits(),
4767 z.significant_bits(),
4768 w.significant_bits()
4769 );
4770 self.mul_add_mul_prec_round_ref_ref_ref_ref(y, z, w, prec, rm)
4771 }
4772
4773 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
4774 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
4775 /// The [`Float`]s on the right-hand side are all taken by value. An [`Ordering`] is returned,
4776 /// indicating whether the rounded sum is less than, equal to, or greater than the exact sum.
4777 /// Although `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN`
4778 /// it also returns `Equal`.
4779 ///
4780 /// The precision of the output is the maximum of the precisions of the inputs. See
4781 /// [`RoundingMode`] for a description of the possible rounding modes.
4782 ///
4783 /// $$
4784 /// x \gets xy+zw+\varepsilon.
4785 /// $$
4786 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4787 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4788 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4789 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4790 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4791 ///
4792 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
4793 /// overflow, and underflow.
4794 ///
4795 /// If you want to specify an output precision, consider using
4796 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
4797 /// rounding mode, consider using
4798 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
4799 ///
4800 /// # Worst-case complexity
4801 /// $T(n, m) = O(n \log n \log\log n + m)$
4802 ///
4803 /// $M(n, m) = O(n \log n + m)$
4804 ///
4805 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4806 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4807 /// `self.significant_bits()`.
4808 ///
4809 /// # Panics
4810 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4811 /// represent the output.
4812 ///
4813 /// # Examples
4814 /// ```
4815 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4816 /// use malachite_base::rounding_modes::RoundingMode::*;
4817 /// use malachite_float::Float;
4818 /// use std::cmp::Ordering::*;
4819 ///
4820 /// let y = Float::from(E);
4821 /// let z = Float::from(SQRT_2);
4822 /// let w = Float::from(LN_2);
4823 ///
4824 /// let mut x = Float::from(PI);
4825 /// assert_eq!(
4826 /// x.mul_add_mul_round_assign(y.clone(), z.clone(), w.clone(), Floor),
4827 /// Less
4828 /// );
4829 /// assert_eq!(x.to_string(), "9.5199923661421124");
4830 ///
4831 /// let mut x = Float::from(PI);
4832 /// assert_eq!(
4833 /// x.mul_add_mul_round_assign(y.clone(), z.clone(), w.clone(), Ceiling),
4834 /// Greater
4835 /// );
4836 /// assert_eq!(x.to_string(), "9.5199923661421142");
4837 ///
4838 /// let mut x = Float::from(PI);
4839 /// assert_eq!(
4840 /// x.mul_add_mul_round_assign(y.clone(), z.clone(), w.clone(), Nearest),
4841 /// Greater
4842 /// );
4843 /// assert_eq!(x.to_string(), "9.5199923661421142");
4844 /// ```
4845 #[allow(clippy::needless_pass_by_value)]
4846 #[inline]
4847 pub fn mul_add_mul_round_assign(
4848 &mut self,
4849 y: Self,
4850 z: Self,
4851 w: Self,
4852 rm: RoundingMode,
4853 ) -> Ordering {
4854 let prec = max!(
4855 self.significant_bits(),
4856 y.significant_bits(),
4857 z.significant_bits(),
4858 w.significant_bits()
4859 );
4860 self.mul_add_mul_prec_round_assign(y, z, w, prec, rm)
4861 }
4862
4863 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
4864 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
4865 /// The last [`Float`] on the right-hand side is taken by reference and the others by value. An
4866 /// [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
4867 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
4868 /// this function assigns a `NaN` it also returns `Equal`.
4869 ///
4870 /// The precision of the output is the maximum of the precisions of the inputs. See
4871 /// [`RoundingMode`] for a description of the possible rounding modes.
4872 ///
4873 /// $$
4874 /// x \gets xy+zw+\varepsilon.
4875 /// $$
4876 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4877 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4878 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4879 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4880 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4881 ///
4882 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
4883 /// overflow, and underflow.
4884 ///
4885 /// If you want to specify an output precision, consider using
4886 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
4887 /// rounding mode, consider using
4888 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
4889 ///
4890 /// # Worst-case complexity
4891 /// $T(n, m) = O(n \log n \log\log n + m)$
4892 ///
4893 /// $M(n, m) = O(n \log n + m)$
4894 ///
4895 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4896 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4897 /// `self.significant_bits()`.
4898 ///
4899 /// # Panics
4900 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4901 /// represent the output.
4902 ///
4903 /// # Examples
4904 /// ```
4905 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4906 /// use malachite_base::rounding_modes::RoundingMode::*;
4907 /// use malachite_float::Float;
4908 /// use std::cmp::Ordering::*;
4909 ///
4910 /// let y = Float::from(E);
4911 /// let z = Float::from(SQRT_2);
4912 /// let w = Float::from(LN_2);
4913 ///
4914 /// let mut x = Float::from(PI);
4915 /// assert_eq!(
4916 /// x.mul_add_mul_round_assign_val_val_ref(y.clone(), z.clone(), &w, Floor),
4917 /// Less
4918 /// );
4919 /// assert_eq!(x.to_string(), "9.5199923661421124");
4920 ///
4921 /// let mut x = Float::from(PI);
4922 /// assert_eq!(
4923 /// x.mul_add_mul_round_assign_val_val_ref(y.clone(), z.clone(), &w, Ceiling),
4924 /// Greater
4925 /// );
4926 /// assert_eq!(x.to_string(), "9.5199923661421142");
4927 ///
4928 /// let mut x = Float::from(PI);
4929 /// assert_eq!(
4930 /// x.mul_add_mul_round_assign_val_val_ref(y.clone(), z.clone(), &w, Nearest),
4931 /// Greater
4932 /// );
4933 /// assert_eq!(x.to_string(), "9.5199923661421142");
4934 /// ```
4935 #[allow(clippy::needless_pass_by_value)]
4936 #[inline]
4937 pub fn mul_add_mul_round_assign_val_val_ref(
4938 &mut self,
4939 y: Self,
4940 z: Self,
4941 w: &Self,
4942 rm: RoundingMode,
4943 ) -> Ordering {
4944 let prec = max!(
4945 self.significant_bits(),
4946 y.significant_bits(),
4947 z.significant_bits(),
4948 w.significant_bits()
4949 );
4950 self.mul_add_mul_prec_round_assign_val_val_ref(y, z, w, prec, rm)
4951 }
4952
4953 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
4954 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
4955 /// The middle [`Float`] on the right-hand side is taken by reference and the others by value.
4956 /// An [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
4957 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
4958 /// this function assigns a `NaN` it also returns `Equal`.
4959 ///
4960 /// The precision of the output is the maximum of the precisions of the inputs. See
4961 /// [`RoundingMode`] for a description of the possible rounding modes.
4962 ///
4963 /// $$
4964 /// x \gets xy+zw+\varepsilon.
4965 /// $$
4966 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4967 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4968 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4969 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4970 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4971 ///
4972 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
4973 /// overflow, and underflow.
4974 ///
4975 /// If you want to specify an output precision, consider using
4976 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
4977 /// rounding mode, consider using
4978 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
4979 ///
4980 /// # Worst-case complexity
4981 /// $T(n, m) = O(n \log n \log\log n + m)$
4982 ///
4983 /// $M(n, m) = O(n \log n + m)$
4984 ///
4985 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4986 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4987 /// `self.significant_bits()`.
4988 ///
4989 /// # Panics
4990 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4991 /// represent the output.
4992 ///
4993 /// # Examples
4994 /// ```
4995 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4996 /// use malachite_base::rounding_modes::RoundingMode::*;
4997 /// use malachite_float::Float;
4998 /// use std::cmp::Ordering::*;
4999 ///
5000 /// let y = Float::from(E);
5001 /// let z = Float::from(SQRT_2);
5002 /// let w = Float::from(LN_2);
5003 ///
5004 /// let mut x = Float::from(PI);
5005 /// assert_eq!(
5006 /// x.mul_add_mul_round_assign_val_ref_val(y.clone(), &z, w.clone(), Floor),
5007 /// Less
5008 /// );
5009 /// assert_eq!(x.to_string(), "9.5199923661421124");
5010 ///
5011 /// let mut x = Float::from(PI);
5012 /// assert_eq!(
5013 /// x.mul_add_mul_round_assign_val_ref_val(y.clone(), &z, w.clone(), Ceiling),
5014 /// Greater
5015 /// );
5016 /// assert_eq!(x.to_string(), "9.5199923661421142");
5017 ///
5018 /// let mut x = Float::from(PI);
5019 /// assert_eq!(
5020 /// x.mul_add_mul_round_assign_val_ref_val(y.clone(), &z, w.clone(), Nearest),
5021 /// Greater
5022 /// );
5023 /// assert_eq!(x.to_string(), "9.5199923661421142");
5024 /// ```
5025 #[allow(clippy::needless_pass_by_value)]
5026 #[inline]
5027 pub fn mul_add_mul_round_assign_val_ref_val(
5028 &mut self,
5029 y: Self,
5030 z: &Self,
5031 w: Self,
5032 rm: RoundingMode,
5033 ) -> Ordering {
5034 let prec = max!(
5035 self.significant_bits(),
5036 y.significant_bits(),
5037 z.significant_bits(),
5038 w.significant_bits()
5039 );
5040 self.mul_add_mul_prec_round_assign_val_ref_val(y, z, w, prec, rm)
5041 }
5042
5043 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
5044 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
5045 /// The first [`Float`] on the right-hand side is taken by value and the others by reference. An
5046 /// [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
5047 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
5048 /// this function assigns a `NaN` it also returns `Equal`.
5049 ///
5050 /// The precision of the output is the maximum of the precisions of the inputs. See
5051 /// [`RoundingMode`] for a description of the possible rounding modes.
5052 ///
5053 /// $$
5054 /// x \gets xy+zw+\varepsilon.
5055 /// $$
5056 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5057 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5058 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
5059 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5060 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
5061 ///
5062 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
5063 /// overflow, and underflow.
5064 ///
5065 /// If you want to specify an output precision, consider using
5066 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
5067 /// rounding mode, consider using
5068 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
5069 ///
5070 /// # Worst-case complexity
5071 /// $T(n, m) = O(n \log n \log\log n + m)$
5072 ///
5073 /// $M(n, m) = O(n \log n + m)$
5074 ///
5075 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5076 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5077 /// `self.significant_bits()`.
5078 ///
5079 /// # Panics
5080 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
5081 /// represent the output.
5082 ///
5083 /// # Examples
5084 /// ```
5085 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
5086 /// use malachite_base::rounding_modes::RoundingMode::*;
5087 /// use malachite_float::Float;
5088 /// use std::cmp::Ordering::*;
5089 ///
5090 /// let y = Float::from(E);
5091 /// let z = Float::from(SQRT_2);
5092 /// let w = Float::from(LN_2);
5093 ///
5094 /// let mut x = Float::from(PI);
5095 /// assert_eq!(
5096 /// x.mul_add_mul_round_assign_val_ref_ref(y.clone(), &z, &w, Floor),
5097 /// Less
5098 /// );
5099 /// assert_eq!(x.to_string(), "9.5199923661421124");
5100 ///
5101 /// let mut x = Float::from(PI);
5102 /// assert_eq!(
5103 /// x.mul_add_mul_round_assign_val_ref_ref(y.clone(), &z, &w, Ceiling),
5104 /// Greater
5105 /// );
5106 /// assert_eq!(x.to_string(), "9.5199923661421142");
5107 ///
5108 /// let mut x = Float::from(PI);
5109 /// assert_eq!(
5110 /// x.mul_add_mul_round_assign_val_ref_ref(y.clone(), &z, &w, Nearest),
5111 /// Greater
5112 /// );
5113 /// assert_eq!(x.to_string(), "9.5199923661421142");
5114 /// ```
5115 #[allow(clippy::needless_pass_by_value)]
5116 #[inline]
5117 pub fn mul_add_mul_round_assign_val_ref_ref(
5118 &mut self,
5119 y: Self,
5120 z: &Self,
5121 w: &Self,
5122 rm: RoundingMode,
5123 ) -> Ordering {
5124 let prec = max!(
5125 self.significant_bits(),
5126 y.significant_bits(),
5127 z.significant_bits(),
5128 w.significant_bits()
5129 );
5130 self.mul_add_mul_prec_round_assign_val_ref_ref(y, z, w, prec, rm)
5131 }
5132
5133 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
5134 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
5135 /// The first [`Float`] on the right-hand side is taken by reference and the others by value. An
5136 /// [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
5137 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
5138 /// this function assigns a `NaN` it also returns `Equal`.
5139 ///
5140 /// The precision of the output is the maximum of the precisions of the inputs. See
5141 /// [`RoundingMode`] for a description of the possible rounding modes.
5142 ///
5143 /// $$
5144 /// x \gets xy+zw+\varepsilon.
5145 /// $$
5146 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5147 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5148 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
5149 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5150 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
5151 ///
5152 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
5153 /// overflow, and underflow.
5154 ///
5155 /// If you want to specify an output precision, consider using
5156 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
5157 /// rounding mode, consider using
5158 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
5159 ///
5160 /// # Worst-case complexity
5161 /// $T(n, m) = O(n \log n \log\log n + m)$
5162 ///
5163 /// $M(n, m) = O(n \log n + m)$
5164 ///
5165 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5166 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5167 /// `self.significant_bits()`.
5168 ///
5169 /// # Panics
5170 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
5171 /// represent the output.
5172 ///
5173 /// # Examples
5174 /// ```
5175 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
5176 /// use malachite_base::rounding_modes::RoundingMode::*;
5177 /// use malachite_float::Float;
5178 /// use std::cmp::Ordering::*;
5179 ///
5180 /// let y = Float::from(E);
5181 /// let z = Float::from(SQRT_2);
5182 /// let w = Float::from(LN_2);
5183 ///
5184 /// let mut x = Float::from(PI);
5185 /// assert_eq!(
5186 /// x.mul_add_mul_round_assign_ref_val_val(&y, z.clone(), w.clone(), Floor),
5187 /// Less
5188 /// );
5189 /// assert_eq!(x.to_string(), "9.5199923661421124");
5190 ///
5191 /// let mut x = Float::from(PI);
5192 /// assert_eq!(
5193 /// x.mul_add_mul_round_assign_ref_val_val(&y, z.clone(), w.clone(), Ceiling),
5194 /// Greater
5195 /// );
5196 /// assert_eq!(x.to_string(), "9.5199923661421142");
5197 ///
5198 /// let mut x = Float::from(PI);
5199 /// assert_eq!(
5200 /// x.mul_add_mul_round_assign_ref_val_val(&y, z.clone(), w.clone(), Nearest),
5201 /// Greater
5202 /// );
5203 /// assert_eq!(x.to_string(), "9.5199923661421142");
5204 /// ```
5205 #[allow(clippy::needless_pass_by_value)]
5206 #[inline]
5207 pub fn mul_add_mul_round_assign_ref_val_val(
5208 &mut self,
5209 y: &Self,
5210 z: Self,
5211 w: Self,
5212 rm: RoundingMode,
5213 ) -> Ordering {
5214 let prec = max!(
5215 self.significant_bits(),
5216 y.significant_bits(),
5217 z.significant_bits(),
5218 w.significant_bits()
5219 );
5220 self.mul_add_mul_prec_round_assign_ref_val_val(y, z, w, prec, rm)
5221 }
5222
5223 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
5224 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
5225 /// The middle [`Float`] on the right-hand side is taken by value and the others by reference.
5226 /// An [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
5227 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
5228 /// this function assigns a `NaN` it also returns `Equal`.
5229 ///
5230 /// The precision of the output is the maximum of the precisions of the inputs. See
5231 /// [`RoundingMode`] for a description of the possible rounding modes.
5232 ///
5233 /// $$
5234 /// x \gets xy+zw+\varepsilon.
5235 /// $$
5236 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5237 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5238 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
5239 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5240 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
5241 ///
5242 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
5243 /// overflow, and underflow.
5244 ///
5245 /// If you want to specify an output precision, consider using
5246 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
5247 /// rounding mode, consider using
5248 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
5249 ///
5250 /// # Worst-case complexity
5251 /// $T(n, m) = O(n \log n \log\log n + m)$
5252 ///
5253 /// $M(n, m) = O(n \log n + m)$
5254 ///
5255 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5256 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5257 /// `self.significant_bits()`.
5258 ///
5259 /// # Panics
5260 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
5261 /// represent the output.
5262 ///
5263 /// # Examples
5264 /// ```
5265 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
5266 /// use malachite_base::rounding_modes::RoundingMode::*;
5267 /// use malachite_float::Float;
5268 /// use std::cmp::Ordering::*;
5269 ///
5270 /// let y = Float::from(E);
5271 /// let z = Float::from(SQRT_2);
5272 /// let w = Float::from(LN_2);
5273 ///
5274 /// let mut x = Float::from(PI);
5275 /// assert_eq!(
5276 /// x.mul_add_mul_round_assign_ref_val_ref(&y, z.clone(), &w, Floor),
5277 /// Less
5278 /// );
5279 /// assert_eq!(x.to_string(), "9.5199923661421124");
5280 ///
5281 /// let mut x = Float::from(PI);
5282 /// assert_eq!(
5283 /// x.mul_add_mul_round_assign_ref_val_ref(&y, z.clone(), &w, Ceiling),
5284 /// Greater
5285 /// );
5286 /// assert_eq!(x.to_string(), "9.5199923661421142");
5287 ///
5288 /// let mut x = Float::from(PI);
5289 /// assert_eq!(
5290 /// x.mul_add_mul_round_assign_ref_val_ref(&y, z.clone(), &w, Nearest),
5291 /// Greater
5292 /// );
5293 /// assert_eq!(x.to_string(), "9.5199923661421142");
5294 /// ```
5295 #[allow(clippy::needless_pass_by_value)]
5296 #[inline]
5297 pub fn mul_add_mul_round_assign_ref_val_ref(
5298 &mut self,
5299 y: &Self,
5300 z: Self,
5301 w: &Self,
5302 rm: RoundingMode,
5303 ) -> Ordering {
5304 let prec = max!(
5305 self.significant_bits(),
5306 y.significant_bits(),
5307 z.significant_bits(),
5308 w.significant_bits()
5309 );
5310 self.mul_add_mul_prec_round_assign_ref_val_ref(y, z, w, prec, rm)
5311 }
5312
5313 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
5314 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
5315 /// The last [`Float`] on the right-hand side is taken by value and the others by reference. An
5316 /// [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
5317 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
5318 /// this function assigns a `NaN` it also returns `Equal`.
5319 ///
5320 /// The precision of the output is the maximum of the precisions of the inputs. See
5321 /// [`RoundingMode`] for a description of the possible rounding modes.
5322 ///
5323 /// $$
5324 /// x \gets xy+zw+\varepsilon.
5325 /// $$
5326 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5327 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5328 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
5329 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5330 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
5331 ///
5332 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
5333 /// overflow, and underflow.
5334 ///
5335 /// If you want to specify an output precision, consider using
5336 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
5337 /// rounding mode, consider using
5338 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
5339 ///
5340 /// # Worst-case complexity
5341 /// $T(n, m) = O(n \log n \log\log n + m)$
5342 ///
5343 /// $M(n, m) = O(n \log n + m)$
5344 ///
5345 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5346 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5347 /// `self.significant_bits()`.
5348 ///
5349 /// # Panics
5350 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
5351 /// represent the output.
5352 ///
5353 /// # Examples
5354 /// ```
5355 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
5356 /// use malachite_base::rounding_modes::RoundingMode::*;
5357 /// use malachite_float::Float;
5358 /// use std::cmp::Ordering::*;
5359 ///
5360 /// let y = Float::from(E);
5361 /// let z = Float::from(SQRT_2);
5362 /// let w = Float::from(LN_2);
5363 ///
5364 /// let mut x = Float::from(PI);
5365 /// assert_eq!(
5366 /// x.mul_add_mul_round_assign_ref_ref_val(&y, &z, w.clone(), Floor),
5367 /// Less
5368 /// );
5369 /// assert_eq!(x.to_string(), "9.5199923661421124");
5370 ///
5371 /// let mut x = Float::from(PI);
5372 /// assert_eq!(
5373 /// x.mul_add_mul_round_assign_ref_ref_val(&y, &z, w.clone(), Ceiling),
5374 /// Greater
5375 /// );
5376 /// assert_eq!(x.to_string(), "9.5199923661421142");
5377 ///
5378 /// let mut x = Float::from(PI);
5379 /// assert_eq!(
5380 /// x.mul_add_mul_round_assign_ref_ref_val(&y, &z, w.clone(), Nearest),
5381 /// Greater
5382 /// );
5383 /// assert_eq!(x.to_string(), "9.5199923661421142");
5384 /// ```
5385 #[allow(clippy::needless_pass_by_value)]
5386 #[inline]
5387 pub fn mul_add_mul_round_assign_ref_ref_val(
5388 &mut self,
5389 y: &Self,
5390 z: &Self,
5391 w: Self,
5392 rm: RoundingMode,
5393 ) -> Ordering {
5394 let prec = max!(
5395 self.significant_bits(),
5396 y.significant_bits(),
5397 z.significant_bits(),
5398 w.significant_bits()
5399 );
5400 self.mul_add_mul_prec_round_assign_ref_ref_val(y, z, w, prec, rm)
5401 }
5402
5403 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
5404 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
5405 /// The [`Float`]s on the right-hand side are all taken by reference. An [`Ordering`] is
5406 /// returned, indicating whether the rounded sum is less than, equal to, or greater than the
5407 /// exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
5408 /// assigns a `NaN` it also returns `Equal`.
5409 ///
5410 /// The precision of the output is the maximum of the precisions of the inputs. See
5411 /// [`RoundingMode`] for a description of the possible rounding modes.
5412 ///
5413 /// $$
5414 /// x \gets xy+zw+\varepsilon.
5415 /// $$
5416 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5417 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5418 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
5419 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5420 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
5421 ///
5422 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
5423 /// overflow, and underflow.
5424 ///
5425 /// If you want to specify an output precision, consider using
5426 /// [`Float::mul_add_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
5427 /// rounding mode, consider using
5428 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
5429 ///
5430 /// # Worst-case complexity
5431 /// $T(n, m) = O(n \log n \log\log n + m)$
5432 ///
5433 /// $M(n, m) = O(n \log n + m)$
5434 ///
5435 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5436 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5437 /// `self.significant_bits()`.
5438 ///
5439 /// # Panics
5440 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
5441 /// represent the output.
5442 ///
5443 /// # Examples
5444 /// ```
5445 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
5446 /// use malachite_base::rounding_modes::RoundingMode::*;
5447 /// use malachite_float::Float;
5448 /// use std::cmp::Ordering::*;
5449 ///
5450 /// let y = Float::from(E);
5451 /// let z = Float::from(SQRT_2);
5452 /// let w = Float::from(LN_2);
5453 ///
5454 /// let mut x = Float::from(PI);
5455 /// assert_eq!(
5456 /// x.mul_add_mul_round_assign_ref_ref_ref(&y, &z, &w, Floor),
5457 /// Less
5458 /// );
5459 /// assert_eq!(x.to_string(), "9.5199923661421124");
5460 ///
5461 /// let mut x = Float::from(PI);
5462 /// assert_eq!(
5463 /// x.mul_add_mul_round_assign_ref_ref_ref(&y, &z, &w, Ceiling),
5464 /// Greater
5465 /// );
5466 /// assert_eq!(x.to_string(), "9.5199923661421142");
5467 ///
5468 /// let mut x = Float::from(PI);
5469 /// assert_eq!(
5470 /// x.mul_add_mul_round_assign_ref_ref_ref(&y, &z, &w, Nearest),
5471 /// Greater
5472 /// );
5473 /// assert_eq!(x.to_string(), "9.5199923661421142");
5474 /// ```
5475 #[allow(clippy::needless_pass_by_value)]
5476 #[inline]
5477 pub fn mul_add_mul_round_assign_ref_ref_ref(
5478 &mut self,
5479 y: &Self,
5480 z: &Self,
5481 w: &Self,
5482 rm: RoundingMode,
5483 ) -> Ordering {
5484 let prec = max!(
5485 self.significant_bits(),
5486 y.significant_bits(),
5487 z.significant_bits(),
5488 w.significant_bits()
5489 );
5490 self.mul_add_mul_prec_round_assign_ref_ref_ref(y, z, w, prec, rm)
5491 }
5492}
5493
5494impl Float {
5495 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
5496 /// rounding the result to the specified precision and with the specified rounding mode; the
5497 /// [`Rational`] enters its product exactly and the products are not rounded before the final
5498 /// addition, so there is a single rounding. The [`Float`]s and the [`Rational`] are all taken
5499 /// by value. An [`Ordering`] is also returned, indicating whether the rounded sum is less than,
5500 /// equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
5501 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
5502 ///
5503 /// See [`RoundingMode`] for a description of the possible rounding modes.
5504 ///
5505 /// $$
5506 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
5507 /// $$
5508 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5509 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5510 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
5511 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5512 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
5513 ///
5514 /// If the output has a precision, it is `prec`.
5515 ///
5516 /// Special cases:
5517 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5518 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5519 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5520 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5521 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
5522 /// [`Rational`] counts as an unsigned zero and a positive sign.
5523 /// - If exactly one product is infinite, the result is that product's infinity.
5524 /// - If both products are infinite, the result is their common infinity if their signs agree,
5525 /// and `NaN` otherwise.
5526 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
5527 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
5528 /// `Floor`
5529 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
5530 ///
5531 /// Overflow and underflow:
5532 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5533 /// returned instead.
5534 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
5535 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5536 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5537 /// returned instead.
5538 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5539 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5540 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
5541 /// instead.
5542 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5543 /// instead.
5544 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5545 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5546 /// returned instead.
5547 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5548 /// instead.
5549 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5550 /// instead.
5551 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
5552 /// instead.
5553 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5554 /// returned instead.
5555 ///
5556 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_rational_prec`]
5557 /// instead. If you know that your target precision is the maximum of the precisions of the
5558 /// inputs, consider using [`Float::mul_add_mul_rational_round`] instead. If both of these
5559 /// things are true, consider using
5560 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
5561 ///
5562 /// # Worst-case complexity
5563 /// $T(n, m) = O(n \log n \log\log n + m)$
5564 ///
5565 /// $M(n, m) = O(n \log n + m)$
5566 ///
5567 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5568 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5569 /// `max(self.significant_bits(), prec)`.
5570 ///
5571 /// # Panics
5572 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
5573 /// representable with `prec` bits.
5574 ///
5575 /// # Examples
5576 /// ```
5577 /// use core::f64::consts::{E, PI, SQRT_2};
5578 /// use malachite_base::rounding_modes::RoundingMode::*;
5579 /// use malachite_float::Float;
5580 /// use malachite_q::Rational;
5581 /// use std::cmp::Ordering::*;
5582 ///
5583 /// let x = Float::from(PI);
5584 /// let y = Float::from(E);
5585 /// let z = Float::from(SQRT_2);
5586 /// let w = Rational::from_signeds(1, 3);
5587 ///
5588 /// let (sum, o) =
5589 /// x.clone()
5590 /// .mul_add_mul_rational_prec_round(y.clone(), z.clone(), w.clone(), 5, Floor);
5591 /// assert_eq!(sum.to_string(), "9.00");
5592 /// assert_eq!(o, Less);
5593 ///
5594 /// let (sum, o) =
5595 /// x.clone()
5596 /// .mul_add_mul_rational_prec_round(y.clone(), z.clone(), w.clone(), 5, Ceiling);
5597 /// assert_eq!(sum.to_string(), "9.50");
5598 /// assert_eq!(o, Greater);
5599 ///
5600 /// let (sum, o) =
5601 /// x.clone()
5602 /// .mul_add_mul_rational_prec_round(y.clone(), z.clone(), w.clone(), 5, Nearest);
5603 /// assert_eq!(sum.to_string(), "9.00");
5604 /// assert_eq!(o, Less);
5605 ///
5606 /// let (sum, o) =
5607 /// x.clone()
5608 /// .mul_add_mul_rational_prec_round(y.clone(), z.clone(), w.clone(), 20, Floor);
5609 /// assert_eq!(sum.to_string(), "9.0111237");
5610 /// assert_eq!(o, Less);
5611 ///
5612 /// let (sum, o) =
5613 /// x.clone()
5614 /// .mul_add_mul_rational_prec_round(y.clone(), z.clone(), w.clone(), 20, Ceiling);
5615 /// assert_eq!(sum.to_string(), "9.0111389");
5616 /// assert_eq!(o, Greater);
5617 ///
5618 /// let (sum, o) =
5619 /// x.clone()
5620 /// .mul_add_mul_rational_prec_round(y.clone(), z.clone(), w.clone(), 20, Nearest);
5621 /// assert_eq!(sum.to_string(), "9.0111389");
5622 /// assert_eq!(o, Greater);
5623 /// ```
5624 #[allow(clippy::needless_pass_by_value)]
5625 #[inline]
5626 pub fn mul_add_mul_rational_prec_round(
5627 self,
5628 y: Self,
5629 z: Self,
5630 w: Rational,
5631 prec: u64,
5632 rm: RoundingMode,
5633 ) -> (Self, Ordering) {
5634 mul_add_mul_rational_helper(&self, &y, &z, &w, false, prec, rm)
5635 }
5636
5637 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
5638 /// rounding the result to the specified precision and with the specified rounding mode; the
5639 /// [`Rational`] enters its product exactly and the products are not rounded before the final
5640 /// addition, so there is a single rounding. The [`Float`]s are taken by value and the
5641 /// [`Rational`] by reference. An [`Ordering`] is also returned, indicating whether the rounded
5642 /// sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
5643 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
5644 ///
5645 /// See [`RoundingMode`] for a description of the possible rounding modes.
5646 ///
5647 /// $$
5648 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
5649 /// $$
5650 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5651 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5652 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
5653 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5654 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
5655 ///
5656 /// If the output has a precision, it is `prec`.
5657 ///
5658 /// Special cases:
5659 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5660 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5661 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5662 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5663 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
5664 /// [`Rational`] counts as an unsigned zero and a positive sign.
5665 /// - If exactly one product is infinite, the result is that product's infinity.
5666 /// - If both products are infinite, the result is their common infinity if their signs agree,
5667 /// and `NaN` otherwise.
5668 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
5669 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
5670 /// `Floor`
5671 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
5672 ///
5673 /// Overflow and underflow:
5674 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5675 /// returned instead.
5676 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
5677 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5678 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5679 /// returned instead.
5680 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5681 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5682 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
5683 /// instead.
5684 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5685 /// instead.
5686 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5687 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5688 /// returned instead.
5689 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5690 /// instead.
5691 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5692 /// instead.
5693 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
5694 /// instead.
5695 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5696 /// returned instead.
5697 ///
5698 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_rational_prec`]
5699 /// instead. If you know that your target precision is the maximum of the precisions of the
5700 /// inputs, consider using [`Float::mul_add_mul_rational_round`] instead. If both of these
5701 /// things are true, consider using
5702 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
5703 ///
5704 /// # Worst-case complexity
5705 /// $T(n, m) = O(n \log n \log\log n + m)$
5706 ///
5707 /// $M(n, m) = O(n \log n + m)$
5708 ///
5709 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5710 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5711 /// `max(self.significant_bits(), prec)`.
5712 ///
5713 /// # Panics
5714 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
5715 /// representable with `prec` bits.
5716 ///
5717 /// # Examples
5718 /// ```
5719 /// use core::f64::consts::{E, PI, SQRT_2};
5720 /// use malachite_base::rounding_modes::RoundingMode::*;
5721 /// use malachite_float::Float;
5722 /// use malachite_q::Rational;
5723 /// use std::cmp::Ordering::*;
5724 ///
5725 /// let x = Float::from(PI);
5726 /// let y = Float::from(E);
5727 /// let z = Float::from(SQRT_2);
5728 /// let w = Rational::from_signeds(1, 3);
5729 ///
5730 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_val_ref(
5731 /// y.clone(),
5732 /// z.clone(),
5733 /// &w,
5734 /// 5,
5735 /// Floor,
5736 /// );
5737 /// assert_eq!(sum.to_string(), "9.00");
5738 /// assert_eq!(o, Less);
5739 ///
5740 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_val_ref(
5741 /// y.clone(),
5742 /// z.clone(),
5743 /// &w,
5744 /// 5,
5745 /// Ceiling,
5746 /// );
5747 /// assert_eq!(sum.to_string(), "9.50");
5748 /// assert_eq!(o, Greater);
5749 ///
5750 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_val_ref(
5751 /// y.clone(),
5752 /// z.clone(),
5753 /// &w,
5754 /// 5,
5755 /// Nearest,
5756 /// );
5757 /// assert_eq!(sum.to_string(), "9.00");
5758 /// assert_eq!(o, Less);
5759 ///
5760 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_val_ref(
5761 /// y.clone(),
5762 /// z.clone(),
5763 /// &w,
5764 /// 20,
5765 /// Floor,
5766 /// );
5767 /// assert_eq!(sum.to_string(), "9.0111237");
5768 /// assert_eq!(o, Less);
5769 ///
5770 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_val_ref(
5771 /// y.clone(),
5772 /// z.clone(),
5773 /// &w,
5774 /// 20,
5775 /// Ceiling,
5776 /// );
5777 /// assert_eq!(sum.to_string(), "9.0111389");
5778 /// assert_eq!(o, Greater);
5779 ///
5780 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_val_ref(
5781 /// y.clone(),
5782 /// z.clone(),
5783 /// &w,
5784 /// 20,
5785 /// Nearest,
5786 /// );
5787 /// assert_eq!(sum.to_string(), "9.0111389");
5788 /// assert_eq!(o, Greater);
5789 /// ```
5790 #[allow(clippy::needless_pass_by_value)]
5791 #[inline]
5792 pub fn mul_add_mul_rational_prec_round_val_val_val_ref(
5793 self,
5794 y: Self,
5795 z: Self,
5796 w: &Rational,
5797 prec: u64,
5798 rm: RoundingMode,
5799 ) -> (Self, Ordering) {
5800 mul_add_mul_rational_helper(&self, &y, &z, w, false, prec, rm)
5801 }
5802
5803 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
5804 /// rounding the result to the specified precision and with the specified rounding mode; the
5805 /// [`Rational`] enters its product exactly and the products are not rounded before the final
5806 /// addition, so there is a single rounding. The third [`Float`] is taken by reference and the
5807 /// other operands by value. An [`Ordering`] is also returned, indicating whether the rounded
5808 /// sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
5809 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
5810 ///
5811 /// See [`RoundingMode`] for a description of the possible rounding modes.
5812 ///
5813 /// $$
5814 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
5815 /// $$
5816 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5817 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5818 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
5819 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5820 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
5821 ///
5822 /// If the output has a precision, it is `prec`.
5823 ///
5824 /// Special cases:
5825 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5826 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5827 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5828 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5829 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
5830 /// [`Rational`] counts as an unsigned zero and a positive sign.
5831 /// - If exactly one product is infinite, the result is that product's infinity.
5832 /// - If both products are infinite, the result is their common infinity if their signs agree,
5833 /// and `NaN` otherwise.
5834 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
5835 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
5836 /// `Floor`
5837 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
5838 ///
5839 /// Overflow and underflow:
5840 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5841 /// returned instead.
5842 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
5843 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5844 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5845 /// returned instead.
5846 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5847 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5848 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
5849 /// instead.
5850 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5851 /// instead.
5852 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5853 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5854 /// returned instead.
5855 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5856 /// instead.
5857 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5858 /// instead.
5859 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
5860 /// instead.
5861 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5862 /// returned instead.
5863 ///
5864 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_rational_prec`]
5865 /// instead. If you know that your target precision is the maximum of the precisions of the
5866 /// inputs, consider using [`Float::mul_add_mul_rational_round`] instead. If both of these
5867 /// things are true, consider using
5868 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
5869 ///
5870 /// # Worst-case complexity
5871 /// $T(n, m) = O(n \log n \log\log n + m)$
5872 ///
5873 /// $M(n, m) = O(n \log n + m)$
5874 ///
5875 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5876 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5877 /// `max(self.significant_bits(), prec)`.
5878 ///
5879 /// # Panics
5880 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
5881 /// representable with `prec` bits.
5882 ///
5883 /// # Examples
5884 /// ```
5885 /// use core::f64::consts::{E, PI, SQRT_2};
5886 /// use malachite_base::rounding_modes::RoundingMode::*;
5887 /// use malachite_float::Float;
5888 /// use malachite_q::Rational;
5889 /// use std::cmp::Ordering::*;
5890 ///
5891 /// let x = Float::from(PI);
5892 /// let y = Float::from(E);
5893 /// let z = Float::from(SQRT_2);
5894 /// let w = Rational::from_signeds(1, 3);
5895 ///
5896 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_ref_val(
5897 /// y.clone(),
5898 /// &z,
5899 /// w.clone(),
5900 /// 5,
5901 /// Floor,
5902 /// );
5903 /// assert_eq!(sum.to_string(), "9.00");
5904 /// assert_eq!(o, Less);
5905 ///
5906 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_ref_val(
5907 /// y.clone(),
5908 /// &z,
5909 /// w.clone(),
5910 /// 5,
5911 /// Ceiling,
5912 /// );
5913 /// assert_eq!(sum.to_string(), "9.50");
5914 /// assert_eq!(o, Greater);
5915 ///
5916 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_ref_val(
5917 /// y.clone(),
5918 /// &z,
5919 /// w.clone(),
5920 /// 5,
5921 /// Nearest,
5922 /// );
5923 /// assert_eq!(sum.to_string(), "9.00");
5924 /// assert_eq!(o, Less);
5925 ///
5926 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_ref_val(
5927 /// y.clone(),
5928 /// &z,
5929 /// w.clone(),
5930 /// 20,
5931 /// Floor,
5932 /// );
5933 /// assert_eq!(sum.to_string(), "9.0111237");
5934 /// assert_eq!(o, Less);
5935 ///
5936 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_ref_val(
5937 /// y.clone(),
5938 /// &z,
5939 /// w.clone(),
5940 /// 20,
5941 /// Ceiling,
5942 /// );
5943 /// assert_eq!(sum.to_string(), "9.0111389");
5944 /// assert_eq!(o, Greater);
5945 ///
5946 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_ref_val(
5947 /// y.clone(),
5948 /// &z,
5949 /// w.clone(),
5950 /// 20,
5951 /// Nearest,
5952 /// );
5953 /// assert_eq!(sum.to_string(), "9.0111389");
5954 /// assert_eq!(o, Greater);
5955 /// ```
5956 #[allow(clippy::needless_pass_by_value)]
5957 #[inline]
5958 pub fn mul_add_mul_rational_prec_round_val_val_ref_val(
5959 self,
5960 y: Self,
5961 z: &Self,
5962 w: Rational,
5963 prec: u64,
5964 rm: RoundingMode,
5965 ) -> (Self, Ordering) {
5966 mul_add_mul_rational_helper(&self, &y, z, &w, false, prec, rm)
5967 }
5968
5969 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
5970 /// rounding the result to the specified precision and with the specified rounding mode; the
5971 /// [`Rational`] enters its product exactly and the products are not rounded before the final
5972 /// addition, so there is a single rounding. The first two [`Float`]s are taken by value and the
5973 /// third [`Float`] and the [`Rational`] by reference. An [`Ordering`] is also returned,
5974 /// indicating whether the rounded sum is less than, equal to, or greater than the exact sum.
5975 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
5976 /// it also returns `Equal`.
5977 ///
5978 /// See [`RoundingMode`] for a description of the possible rounding modes.
5979 ///
5980 /// $$
5981 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
5982 /// $$
5983 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5984 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5985 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
5986 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5987 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
5988 ///
5989 /// If the output has a precision, it is `prec`.
5990 ///
5991 /// Special cases:
5992 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5993 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5994 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5995 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5996 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
5997 /// [`Rational`] counts as an unsigned zero and a positive sign.
5998 /// - If exactly one product is infinite, the result is that product's infinity.
5999 /// - If both products are infinite, the result is their common infinity if their signs agree,
6000 /// and `NaN` otherwise.
6001 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
6002 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
6003 /// `Floor`
6004 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
6005 ///
6006 /// Overflow and underflow:
6007 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
6008 /// returned instead.
6009 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
6010 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6011 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
6012 /// returned instead.
6013 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
6014 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6015 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
6016 /// instead.
6017 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
6018 /// instead.
6019 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
6020 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
6021 /// returned instead.
6022 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
6023 /// instead.
6024 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
6025 /// instead.
6026 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
6027 /// instead.
6028 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
6029 /// returned instead.
6030 ///
6031 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_rational_prec`]
6032 /// instead. If you know that your target precision is the maximum of the precisions of the
6033 /// inputs, consider using [`Float::mul_add_mul_rational_round`] instead. If both of these
6034 /// things are true, consider using
6035 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
6036 ///
6037 /// # Worst-case complexity
6038 /// $T(n, m) = O(n \log n \log\log n + m)$
6039 ///
6040 /// $M(n, m) = O(n \log n + m)$
6041 ///
6042 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6043 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
6044 /// `max(self.significant_bits(), prec)`.
6045 ///
6046 /// # Panics
6047 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
6048 /// representable with `prec` bits.
6049 ///
6050 /// # Examples
6051 /// ```
6052 /// use core::f64::consts::{E, PI, SQRT_2};
6053 /// use malachite_base::rounding_modes::RoundingMode::*;
6054 /// use malachite_float::Float;
6055 /// use malachite_q::Rational;
6056 /// use std::cmp::Ordering::*;
6057 ///
6058 /// let x = Float::from(PI);
6059 /// let y = Float::from(E);
6060 /// let z = Float::from(SQRT_2);
6061 /// let w = Rational::from_signeds(1, 3);
6062 ///
6063 /// let (sum, o) =
6064 /// x.clone()
6065 /// .mul_add_mul_rational_prec_round_val_val_ref_ref(y.clone(), &z, &w, 5, Floor);
6066 /// assert_eq!(sum.to_string(), "9.00");
6067 /// assert_eq!(o, Less);
6068 ///
6069 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_ref_ref(
6070 /// y.clone(),
6071 /// &z,
6072 /// &w,
6073 /// 5,
6074 /// Ceiling,
6075 /// );
6076 /// assert_eq!(sum.to_string(), "9.50");
6077 /// assert_eq!(o, Greater);
6078 ///
6079 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_ref_ref(
6080 /// y.clone(),
6081 /// &z,
6082 /// &w,
6083 /// 5,
6084 /// Nearest,
6085 /// );
6086 /// assert_eq!(sum.to_string(), "9.00");
6087 /// assert_eq!(o, Less);
6088 ///
6089 /// let (sum, o) =
6090 /// x.clone()
6091 /// .mul_add_mul_rational_prec_round_val_val_ref_ref(y.clone(), &z, &w, 20, Floor);
6092 /// assert_eq!(sum.to_string(), "9.0111237");
6093 /// assert_eq!(o, Less);
6094 ///
6095 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_ref_ref(
6096 /// y.clone(),
6097 /// &z,
6098 /// &w,
6099 /// 20,
6100 /// Ceiling,
6101 /// );
6102 /// assert_eq!(sum.to_string(), "9.0111389");
6103 /// assert_eq!(o, Greater);
6104 ///
6105 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_val_ref_ref(
6106 /// y.clone(),
6107 /// &z,
6108 /// &w,
6109 /// 20,
6110 /// Nearest,
6111 /// );
6112 /// assert_eq!(sum.to_string(), "9.0111389");
6113 /// assert_eq!(o, Greater);
6114 /// ```
6115 #[allow(clippy::needless_pass_by_value)]
6116 #[inline]
6117 pub fn mul_add_mul_rational_prec_round_val_val_ref_ref(
6118 self,
6119 y: Self,
6120 z: &Self,
6121 w: &Rational,
6122 prec: u64,
6123 rm: RoundingMode,
6124 ) -> (Self, Ordering) {
6125 mul_add_mul_rational_helper(&self, &y, z, w, false, prec, rm)
6126 }
6127
6128 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
6129 /// rounding the result to the specified precision and with the specified rounding mode; the
6130 /// [`Rational`] enters its product exactly and the products are not rounded before the final
6131 /// addition, so there is a single rounding. The second [`Float`] is taken by reference and the
6132 /// other operands by value. An [`Ordering`] is also returned, indicating whether the rounded
6133 /// sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
6134 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
6135 ///
6136 /// See [`RoundingMode`] for a description of the possible rounding modes.
6137 ///
6138 /// $$
6139 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
6140 /// $$
6141 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6142 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6143 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
6144 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6145 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
6146 ///
6147 /// If the output has a precision, it is `prec`.
6148 ///
6149 /// Special cases:
6150 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6151 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6152 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6153 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6154 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
6155 /// [`Rational`] counts as an unsigned zero and a positive sign.
6156 /// - If exactly one product is infinite, the result is that product's infinity.
6157 /// - If both products are infinite, the result is their common infinity if their signs agree,
6158 /// and `NaN` otherwise.
6159 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
6160 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
6161 /// `Floor`
6162 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
6163 ///
6164 /// Overflow and underflow:
6165 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
6166 /// returned instead.
6167 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
6168 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6169 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
6170 /// returned instead.
6171 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
6172 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6173 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
6174 /// instead.
6175 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
6176 /// instead.
6177 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
6178 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
6179 /// returned instead.
6180 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
6181 /// instead.
6182 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
6183 /// instead.
6184 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
6185 /// instead.
6186 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
6187 /// returned instead.
6188 ///
6189 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_rational_prec`]
6190 /// instead. If you know that your target precision is the maximum of the precisions of the
6191 /// inputs, consider using [`Float::mul_add_mul_rational_round`] instead. If both of these
6192 /// things are true, consider using
6193 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
6194 ///
6195 /// # Worst-case complexity
6196 /// $T(n, m) = O(n \log n \log\log n + m)$
6197 ///
6198 /// $M(n, m) = O(n \log n + m)$
6199 ///
6200 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6201 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
6202 /// `max(self.significant_bits(), prec)`.
6203 ///
6204 /// # Panics
6205 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
6206 /// representable with `prec` bits.
6207 ///
6208 /// # Examples
6209 /// ```
6210 /// use core::f64::consts::{E, PI, SQRT_2};
6211 /// use malachite_base::rounding_modes::RoundingMode::*;
6212 /// use malachite_float::Float;
6213 /// use malachite_q::Rational;
6214 /// use std::cmp::Ordering::*;
6215 ///
6216 /// let x = Float::from(PI);
6217 /// let y = Float::from(E);
6218 /// let z = Float::from(SQRT_2);
6219 /// let w = Rational::from_signeds(1, 3);
6220 ///
6221 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_ref_val_val(
6222 /// &y,
6223 /// z.clone(),
6224 /// w.clone(),
6225 /// 5,
6226 /// Floor,
6227 /// );
6228 /// assert_eq!(sum.to_string(), "9.00");
6229 /// assert_eq!(o, Less);
6230 ///
6231 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_ref_val_val(
6232 /// &y,
6233 /// z.clone(),
6234 /// w.clone(),
6235 /// 5,
6236 /// Ceiling,
6237 /// );
6238 /// assert_eq!(sum.to_string(), "9.50");
6239 /// assert_eq!(o, Greater);
6240 ///
6241 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_ref_val_val(
6242 /// &y,
6243 /// z.clone(),
6244 /// w.clone(),
6245 /// 5,
6246 /// Nearest,
6247 /// );
6248 /// assert_eq!(sum.to_string(), "9.00");
6249 /// assert_eq!(o, Less);
6250 ///
6251 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_ref_val_val(
6252 /// &y,
6253 /// z.clone(),
6254 /// w.clone(),
6255 /// 20,
6256 /// Floor,
6257 /// );
6258 /// assert_eq!(sum.to_string(), "9.0111237");
6259 /// assert_eq!(o, Less);
6260 ///
6261 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_ref_val_val(
6262 /// &y,
6263 /// z.clone(),
6264 /// w.clone(),
6265 /// 20,
6266 /// Ceiling,
6267 /// );
6268 /// assert_eq!(sum.to_string(), "9.0111389");
6269 /// assert_eq!(o, Greater);
6270 ///
6271 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_ref_val_val(
6272 /// &y,
6273 /// z.clone(),
6274 /// w.clone(),
6275 /// 20,
6276 /// Nearest,
6277 /// );
6278 /// assert_eq!(sum.to_string(), "9.0111389");
6279 /// assert_eq!(o, Greater);
6280 /// ```
6281 #[allow(clippy::needless_pass_by_value)]
6282 #[inline]
6283 pub fn mul_add_mul_rational_prec_round_val_ref_val_val(
6284 self,
6285 y: &Self,
6286 z: Self,
6287 w: Rational,
6288 prec: u64,
6289 rm: RoundingMode,
6290 ) -> (Self, Ordering) {
6291 mul_add_mul_rational_helper(&self, y, &z, &w, false, prec, rm)
6292 }
6293
6294 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
6295 /// rounding the result to the specified precision and with the specified rounding mode; the
6296 /// [`Rational`] enters its product exactly and the products are not rounded before the final
6297 /// addition, so there is a single rounding. The second [`Float`] and the [`Rational`] are taken
6298 /// by reference and the other operands by value. An [`Ordering`] is also returned, indicating
6299 /// whether the rounded sum is less than, equal to, or greater than the exact sum. Although
6300 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
6301 /// returns `Equal`.
6302 ///
6303 /// See [`RoundingMode`] for a description of the possible rounding modes.
6304 ///
6305 /// $$
6306 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
6307 /// $$
6308 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6309 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6310 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
6311 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6312 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
6313 ///
6314 /// If the output has a precision, it is `prec`.
6315 ///
6316 /// Special cases:
6317 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6318 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6319 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6320 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6321 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
6322 /// [`Rational`] counts as an unsigned zero and a positive sign.
6323 /// - If exactly one product is infinite, the result is that product's infinity.
6324 /// - If both products are infinite, the result is their common infinity if their signs agree,
6325 /// and `NaN` otherwise.
6326 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
6327 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
6328 /// `Floor`
6329 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
6330 ///
6331 /// Overflow and underflow:
6332 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
6333 /// returned instead.
6334 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
6335 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6336 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
6337 /// returned instead.
6338 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
6339 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6340 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
6341 /// instead.
6342 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
6343 /// instead.
6344 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
6345 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
6346 /// returned instead.
6347 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
6348 /// instead.
6349 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
6350 /// instead.
6351 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
6352 /// instead.
6353 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
6354 /// returned instead.
6355 ///
6356 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_rational_prec`]
6357 /// instead. If you know that your target precision is the maximum of the precisions of the
6358 /// inputs, consider using [`Float::mul_add_mul_rational_round`] instead. If both of these
6359 /// things are true, consider using
6360 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
6361 ///
6362 /// # Worst-case complexity
6363 /// $T(n, m) = O(n \log n \log\log n + m)$
6364 ///
6365 /// $M(n, m) = O(n \log n + m)$
6366 ///
6367 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6368 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
6369 /// `max(self.significant_bits(), prec)`.
6370 ///
6371 /// # Panics
6372 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
6373 /// representable with `prec` bits.
6374 ///
6375 /// # Examples
6376 /// ```
6377 /// use core::f64::consts::{E, PI, SQRT_2};
6378 /// use malachite_base::rounding_modes::RoundingMode::*;
6379 /// use malachite_float::Float;
6380 /// use malachite_q::Rational;
6381 /// use std::cmp::Ordering::*;
6382 ///
6383 /// let x = Float::from(PI);
6384 /// let y = Float::from(E);
6385 /// let z = Float::from(SQRT_2);
6386 /// let w = Rational::from_signeds(1, 3);
6387 ///
6388 /// let (sum, o) =
6389 /// x.clone()
6390 /// .mul_add_mul_rational_prec_round_val_ref_val_ref(&y, z.clone(), &w, 5, Floor);
6391 /// assert_eq!(sum.to_string(), "9.00");
6392 /// assert_eq!(o, Less);
6393 ///
6394 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_ref_val_ref(
6395 /// &y,
6396 /// z.clone(),
6397 /// &w,
6398 /// 5,
6399 /// Ceiling,
6400 /// );
6401 /// assert_eq!(sum.to_string(), "9.50");
6402 /// assert_eq!(o, Greater);
6403 ///
6404 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_ref_val_ref(
6405 /// &y,
6406 /// z.clone(),
6407 /// &w,
6408 /// 5,
6409 /// Nearest,
6410 /// );
6411 /// assert_eq!(sum.to_string(), "9.00");
6412 /// assert_eq!(o, Less);
6413 ///
6414 /// let (sum, o) =
6415 /// x.clone()
6416 /// .mul_add_mul_rational_prec_round_val_ref_val_ref(&y, z.clone(), &w, 20, Floor);
6417 /// assert_eq!(sum.to_string(), "9.0111237");
6418 /// assert_eq!(o, Less);
6419 ///
6420 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_ref_val_ref(
6421 /// &y,
6422 /// z.clone(),
6423 /// &w,
6424 /// 20,
6425 /// Ceiling,
6426 /// );
6427 /// assert_eq!(sum.to_string(), "9.0111389");
6428 /// assert_eq!(o, Greater);
6429 ///
6430 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_ref_val_ref(
6431 /// &y,
6432 /// z.clone(),
6433 /// &w,
6434 /// 20,
6435 /// Nearest,
6436 /// );
6437 /// assert_eq!(sum.to_string(), "9.0111389");
6438 /// assert_eq!(o, Greater);
6439 /// ```
6440 #[allow(clippy::needless_pass_by_value)]
6441 #[inline]
6442 pub fn mul_add_mul_rational_prec_round_val_ref_val_ref(
6443 self,
6444 y: &Self,
6445 z: Self,
6446 w: &Rational,
6447 prec: u64,
6448 rm: RoundingMode,
6449 ) -> (Self, Ordering) {
6450 mul_add_mul_rational_helper(&self, y, &z, w, false, prec, rm)
6451 }
6452
6453 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
6454 /// rounding the result to the specified precision and with the specified rounding mode; the
6455 /// [`Rational`] enters its product exactly and the products are not rounded before the final
6456 /// addition, so there is a single rounding. The second and third [`Float`]s are taken by
6457 /// reference and the other operands by value. An [`Ordering`] is also returned, indicating
6458 /// whether the rounded sum is less than, equal to, or greater than the exact sum. Although
6459 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
6460 /// returns `Equal`.
6461 ///
6462 /// See [`RoundingMode`] for a description of the possible rounding modes.
6463 ///
6464 /// $$
6465 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
6466 /// $$
6467 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6468 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6469 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
6470 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6471 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
6472 ///
6473 /// If the output has a precision, it is `prec`.
6474 ///
6475 /// Special cases:
6476 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6477 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6478 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6479 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6480 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
6481 /// [`Rational`] counts as an unsigned zero and a positive sign.
6482 /// - If exactly one product is infinite, the result is that product's infinity.
6483 /// - If both products are infinite, the result is their common infinity if their signs agree,
6484 /// and `NaN` otherwise.
6485 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
6486 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
6487 /// `Floor`
6488 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
6489 ///
6490 /// Overflow and underflow:
6491 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
6492 /// returned instead.
6493 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
6494 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6495 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
6496 /// returned instead.
6497 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
6498 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6499 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
6500 /// instead.
6501 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
6502 /// instead.
6503 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
6504 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
6505 /// returned instead.
6506 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
6507 /// instead.
6508 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
6509 /// instead.
6510 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
6511 /// instead.
6512 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
6513 /// returned instead.
6514 ///
6515 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_rational_prec`]
6516 /// instead. If you know that your target precision is the maximum of the precisions of the
6517 /// inputs, consider using [`Float::mul_add_mul_rational_round`] instead. If both of these
6518 /// things are true, consider using
6519 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
6520 ///
6521 /// # Worst-case complexity
6522 /// $T(n, m) = O(n \log n \log\log n + m)$
6523 ///
6524 /// $M(n, m) = O(n \log n + m)$
6525 ///
6526 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6527 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
6528 /// `max(self.significant_bits(), prec)`.
6529 ///
6530 /// # Panics
6531 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
6532 /// representable with `prec` bits.
6533 ///
6534 /// # Examples
6535 /// ```
6536 /// use core::f64::consts::{E, PI, SQRT_2};
6537 /// use malachite_base::rounding_modes::RoundingMode::*;
6538 /// use malachite_float::Float;
6539 /// use malachite_q::Rational;
6540 /// use std::cmp::Ordering::*;
6541 ///
6542 /// let x = Float::from(PI);
6543 /// let y = Float::from(E);
6544 /// let z = Float::from(SQRT_2);
6545 /// let w = Rational::from_signeds(1, 3);
6546 ///
6547 /// let (sum, o) =
6548 /// x.clone()
6549 /// .mul_add_mul_rational_prec_round_val_ref_ref_val(&y, &z, w.clone(), 5, Floor);
6550 /// assert_eq!(sum.to_string(), "9.00");
6551 /// assert_eq!(o, Less);
6552 ///
6553 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_ref_ref_val(
6554 /// &y,
6555 /// &z,
6556 /// w.clone(),
6557 /// 5,
6558 /// Ceiling,
6559 /// );
6560 /// assert_eq!(sum.to_string(), "9.50");
6561 /// assert_eq!(o, Greater);
6562 ///
6563 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_ref_ref_val(
6564 /// &y,
6565 /// &z,
6566 /// w.clone(),
6567 /// 5,
6568 /// Nearest,
6569 /// );
6570 /// assert_eq!(sum.to_string(), "9.00");
6571 /// assert_eq!(o, Less);
6572 ///
6573 /// let (sum, o) =
6574 /// x.clone()
6575 /// .mul_add_mul_rational_prec_round_val_ref_ref_val(&y, &z, w.clone(), 20, Floor);
6576 /// assert_eq!(sum.to_string(), "9.0111237");
6577 /// assert_eq!(o, Less);
6578 ///
6579 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_ref_ref_val(
6580 /// &y,
6581 /// &z,
6582 /// w.clone(),
6583 /// 20,
6584 /// Ceiling,
6585 /// );
6586 /// assert_eq!(sum.to_string(), "9.0111389");
6587 /// assert_eq!(o, Greater);
6588 ///
6589 /// let (sum, o) = x.clone().mul_add_mul_rational_prec_round_val_ref_ref_val(
6590 /// &y,
6591 /// &z,
6592 /// w.clone(),
6593 /// 20,
6594 /// Nearest,
6595 /// );
6596 /// assert_eq!(sum.to_string(), "9.0111389");
6597 /// assert_eq!(o, Greater);
6598 /// ```
6599 #[allow(clippy::needless_pass_by_value)]
6600 #[inline]
6601 pub fn mul_add_mul_rational_prec_round_val_ref_ref_val(
6602 self,
6603 y: &Self,
6604 z: &Self,
6605 w: Rational,
6606 prec: u64,
6607 rm: RoundingMode,
6608 ) -> (Self, Ordering) {
6609 mul_add_mul_rational_helper(&self, y, z, &w, false, prec, rm)
6610 }
6611
6612 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
6613 /// rounding the result to the specified precision and with the specified rounding mode; the
6614 /// [`Rational`] enters its product exactly and the products are not rounded before the final
6615 /// addition, so there is a single rounding. The first [`Float`] is taken by value and the other
6616 /// operands by reference. An [`Ordering`] is also returned, indicating whether the rounded sum
6617 /// is less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
6618 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
6619 ///
6620 /// See [`RoundingMode`] for a description of the possible rounding modes.
6621 ///
6622 /// $$
6623 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
6624 /// $$
6625 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6626 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6627 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
6628 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6629 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
6630 ///
6631 /// If the output has a precision, it is `prec`.
6632 ///
6633 /// Special cases:
6634 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6635 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6636 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6637 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6638 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
6639 /// [`Rational`] counts as an unsigned zero and a positive sign.
6640 /// - If exactly one product is infinite, the result is that product's infinity.
6641 /// - If both products are infinite, the result is their common infinity if their signs agree,
6642 /// and `NaN` otherwise.
6643 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
6644 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
6645 /// `Floor`
6646 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
6647 ///
6648 /// Overflow and underflow:
6649 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
6650 /// returned instead.
6651 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
6652 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6653 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
6654 /// returned instead.
6655 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
6656 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6657 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
6658 /// instead.
6659 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
6660 /// instead.
6661 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
6662 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
6663 /// returned instead.
6664 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
6665 /// instead.
6666 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
6667 /// instead.
6668 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
6669 /// instead.
6670 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
6671 /// returned instead.
6672 ///
6673 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_rational_prec`]
6674 /// instead. If you know that your target precision is the maximum of the precisions of the
6675 /// inputs, consider using [`Float::mul_add_mul_rational_round`] instead. If both of these
6676 /// things are true, consider using
6677 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
6678 ///
6679 /// # Worst-case complexity
6680 /// $T(n, m) = O(n \log n \log\log n + m)$
6681 ///
6682 /// $M(n, m) = O(n \log n + m)$
6683 ///
6684 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6685 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
6686 /// `max(self.significant_bits(), prec)`.
6687 ///
6688 /// # Panics
6689 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
6690 /// representable with `prec` bits.
6691 ///
6692 /// # Examples
6693 /// ```
6694 /// use core::f64::consts::{E, PI, SQRT_2};
6695 /// use malachite_base::rounding_modes::RoundingMode::*;
6696 /// use malachite_float::Float;
6697 /// use malachite_q::Rational;
6698 /// use std::cmp::Ordering::*;
6699 ///
6700 /// let x = Float::from(PI);
6701 /// let y = Float::from(E);
6702 /// let z = Float::from(SQRT_2);
6703 /// let w = Rational::from_signeds(1, 3);
6704 ///
6705 /// let (sum, o) = x
6706 /// .clone()
6707 /// .mul_add_mul_rational_prec_round_val_ref_ref_ref(&y, &z, &w, 5, Floor);
6708 /// assert_eq!(sum.to_string(), "9.00");
6709 /// assert_eq!(o, Less);
6710 ///
6711 /// let (sum, o) = x
6712 /// .clone()
6713 /// .mul_add_mul_rational_prec_round_val_ref_ref_ref(&y, &z, &w, 5, Ceiling);
6714 /// assert_eq!(sum.to_string(), "9.50");
6715 /// assert_eq!(o, Greater);
6716 ///
6717 /// let (sum, o) = x
6718 /// .clone()
6719 /// .mul_add_mul_rational_prec_round_val_ref_ref_ref(&y, &z, &w, 5, Nearest);
6720 /// assert_eq!(sum.to_string(), "9.00");
6721 /// assert_eq!(o, Less);
6722 ///
6723 /// let (sum, o) = x
6724 /// .clone()
6725 /// .mul_add_mul_rational_prec_round_val_ref_ref_ref(&y, &z, &w, 20, Floor);
6726 /// assert_eq!(sum.to_string(), "9.0111237");
6727 /// assert_eq!(o, Less);
6728 ///
6729 /// let (sum, o) = x
6730 /// .clone()
6731 /// .mul_add_mul_rational_prec_round_val_ref_ref_ref(&y, &z, &w, 20, Ceiling);
6732 /// assert_eq!(sum.to_string(), "9.0111389");
6733 /// assert_eq!(o, Greater);
6734 ///
6735 /// let (sum, o) = x
6736 /// .clone()
6737 /// .mul_add_mul_rational_prec_round_val_ref_ref_ref(&y, &z, &w, 20, Nearest);
6738 /// assert_eq!(sum.to_string(), "9.0111389");
6739 /// assert_eq!(o, Greater);
6740 /// ```
6741 #[allow(clippy::needless_pass_by_value)]
6742 #[inline]
6743 pub fn mul_add_mul_rational_prec_round_val_ref_ref_ref(
6744 self,
6745 y: &Self,
6746 z: &Self,
6747 w: &Rational,
6748 prec: u64,
6749 rm: RoundingMode,
6750 ) -> (Self, Ordering) {
6751 mul_add_mul_rational_helper(&self, y, z, w, false, prec, rm)
6752 }
6753
6754 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
6755 /// rounding the result to the specified precision and with the specified rounding mode; the
6756 /// [`Rational`] enters its product exactly and the products are not rounded before the final
6757 /// addition, so there is a single rounding. The [`Float`]s and the [`Rational`] are all taken
6758 /// by reference. An [`Ordering`] is also returned, indicating whether the rounded sum is less
6759 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
6760 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
6761 ///
6762 /// See [`RoundingMode`] for a description of the possible rounding modes.
6763 ///
6764 /// $$
6765 /// f(x,y,z,w,p,m) = xy+zw+\varepsilon.
6766 /// $$
6767 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6768 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6769 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
6770 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6771 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
6772 ///
6773 /// If the output has a precision, it is `prec`.
6774 ///
6775 /// Special cases:
6776 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6777 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6778 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6779 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6780 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
6781 /// [`Rational`] counts as an unsigned zero and a positive sign.
6782 /// - If exactly one product is infinite, the result is that product's infinity.
6783 /// - If both products are infinite, the result is their common infinity if their signs agree,
6784 /// and `NaN` otherwise.
6785 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
6786 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
6787 /// `Floor`
6788 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
6789 ///
6790 /// Overflow and underflow:
6791 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
6792 /// returned instead.
6793 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
6794 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6795 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
6796 /// returned instead.
6797 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
6798 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6799 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
6800 /// instead.
6801 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
6802 /// instead.
6803 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
6804 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
6805 /// returned instead.
6806 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
6807 /// instead.
6808 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
6809 /// instead.
6810 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
6811 /// instead.
6812 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
6813 /// returned instead.
6814 ///
6815 /// If you know you'll be using `Nearest`, consider using [`Float::mul_add_mul_rational_prec`]
6816 /// instead. If you know that your target precision is the maximum of the precisions of the
6817 /// inputs, consider using [`Float::mul_add_mul_rational_round`] instead. If both of these
6818 /// things are true, consider using
6819 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
6820 ///
6821 /// # Worst-case complexity
6822 /// $T(n, m) = O(n \log n \log\log n + m)$
6823 ///
6824 /// $M(n, m) = O(n \log n + m)$
6825 ///
6826 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6827 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
6828 /// `max(self.significant_bits(), prec)`.
6829 ///
6830 /// # Panics
6831 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
6832 /// representable with `prec` bits.
6833 ///
6834 /// # Examples
6835 /// ```
6836 /// use core::f64::consts::{E, PI, SQRT_2};
6837 /// use malachite_base::rounding_modes::RoundingMode::*;
6838 /// use malachite_float::Float;
6839 /// use malachite_q::Rational;
6840 /// use std::cmp::Ordering::*;
6841 ///
6842 /// let x = Float::from(PI);
6843 /// let y = Float::from(E);
6844 /// let z = Float::from(SQRT_2);
6845 /// let w = Rational::from_signeds(1, 3);
6846 ///
6847 /// let (sum, o) = x.mul_add_mul_rational_prec_round_ref_ref_ref_ref(&y, &z, &w, 5, Floor);
6848 /// assert_eq!(sum.to_string(), "9.00");
6849 /// assert_eq!(o, Less);
6850 ///
6851 /// let (sum, o) = x.mul_add_mul_rational_prec_round_ref_ref_ref_ref(&y, &z, &w, 5, Ceiling);
6852 /// assert_eq!(sum.to_string(), "9.50");
6853 /// assert_eq!(o, Greater);
6854 ///
6855 /// let (sum, o) = x.mul_add_mul_rational_prec_round_ref_ref_ref_ref(&y, &z, &w, 5, Nearest);
6856 /// assert_eq!(sum.to_string(), "9.00");
6857 /// assert_eq!(o, Less);
6858 ///
6859 /// let (sum, o) = x.mul_add_mul_rational_prec_round_ref_ref_ref_ref(&y, &z, &w, 20, Floor);
6860 /// assert_eq!(sum.to_string(), "9.0111237");
6861 /// assert_eq!(o, Less);
6862 ///
6863 /// let (sum, o) = x.mul_add_mul_rational_prec_round_ref_ref_ref_ref(&y, &z, &w, 20, Ceiling);
6864 /// assert_eq!(sum.to_string(), "9.0111389");
6865 /// assert_eq!(o, Greater);
6866 ///
6867 /// let (sum, o) = x.mul_add_mul_rational_prec_round_ref_ref_ref_ref(&y, &z, &w, 20, Nearest);
6868 /// assert_eq!(sum.to_string(), "9.0111389");
6869 /// assert_eq!(o, Greater);
6870 /// ```
6871 #[allow(clippy::needless_pass_by_value)]
6872 #[inline]
6873 pub fn mul_add_mul_rational_prec_round_ref_ref_ref_ref(
6874 &self,
6875 y: &Self,
6876 z: &Self,
6877 w: &Rational,
6878 prec: u64,
6879 rm: RoundingMode,
6880 ) -> (Self, Ordering) {
6881 mul_add_mul_rational_helper(self, y, z, w, false, prec, rm)
6882 }
6883
6884 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
6885 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
6886 /// the specified rounding mode. The [`Float`]s on the right-hand side are all taken by value.
6887 /// An [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
6888 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
6889 /// this function assigns a `NaN` it also returns `Equal`.
6890 ///
6891 /// See [`RoundingMode`] for a description of the possible rounding modes.
6892 ///
6893 /// $$
6894 /// x \gets xy+zw+\varepsilon.
6895 /// $$
6896 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6897 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6898 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
6899 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6900 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
6901 ///
6902 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
6903 /// overflow, and underflow.
6904 ///
6905 /// If you know you'll be using `Nearest`, consider using
6906 /// [`Float::mul_add_mul_rational_prec_assign`] instead. If you know that your target precision
6907 /// is the maximum of the precisions of the inputs, consider using
6908 /// [`Float::mul_add_mul_rational_round_assign`] instead. If both of these things are true,
6909 /// consider using
6910 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
6911 ///
6912 /// # Worst-case complexity
6913 /// $T(n, m) = O(n \log n \log\log n + m)$
6914 ///
6915 /// $M(n, m) = O(n \log n + m)$
6916 ///
6917 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6918 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
6919 /// `max(self.significant_bits(), prec)`.
6920 ///
6921 /// # Panics
6922 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
6923 /// representable with `prec` bits.
6924 ///
6925 /// # Examples
6926 /// ```
6927 /// use core::f64::consts::{E, PI, SQRT_2};
6928 /// use malachite_base::rounding_modes::RoundingMode::*;
6929 /// use malachite_float::Float;
6930 /// use malachite_q::Rational;
6931 /// use std::cmp::Ordering::*;
6932 ///
6933 /// let y = Float::from(E);
6934 /// let z = Float::from(SQRT_2);
6935 /// let w = Rational::from_signeds(1, 3);
6936 ///
6937 /// let mut x = Float::from(PI);
6938 /// assert_eq!(
6939 /// x.mul_add_mul_rational_prec_round_assign(y.clone(), z.clone(), w.clone(), 5, Floor),
6940 /// Less
6941 /// );
6942 /// assert_eq!(x.to_string(), "9.00");
6943 ///
6944 /// let mut x = Float::from(PI);
6945 /// assert_eq!(
6946 /// x.mul_add_mul_rational_prec_round_assign(y.clone(), z.clone(), w.clone(), 5, Ceiling),
6947 /// Greater
6948 /// );
6949 /// assert_eq!(x.to_string(), "9.50");
6950 ///
6951 /// let mut x = Float::from(PI);
6952 /// assert_eq!(
6953 /// x.mul_add_mul_rational_prec_round_assign(y.clone(), z.clone(), w.clone(), 5, Nearest),
6954 /// Less
6955 /// );
6956 /// assert_eq!(x.to_string(), "9.00");
6957 /// ```
6958 #[allow(clippy::needless_pass_by_value)]
6959 #[inline]
6960 pub fn mul_add_mul_rational_prec_round_assign(
6961 &mut self,
6962 y: Self,
6963 z: Self,
6964 w: Rational,
6965 prec: u64,
6966 rm: RoundingMode,
6967 ) -> Ordering {
6968 let (s, o) = mul_add_mul_rational_helper(self, &y, &z, &w, false, prec, rm);
6969 *self = s;
6970 o
6971 }
6972
6973 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
6974 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
6975 /// the specified rounding mode. The last [`Float`] on the right-hand side is taken by reference
6976 /// and the others by value. An [`Ordering`] is returned, indicating whether the rounded sum is
6977 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
6978 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
6979 ///
6980 /// See [`RoundingMode`] for a description of the possible rounding modes.
6981 ///
6982 /// $$
6983 /// x \gets xy+zw+\varepsilon.
6984 /// $$
6985 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6986 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6987 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
6988 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6989 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
6990 ///
6991 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
6992 /// overflow, and underflow.
6993 ///
6994 /// If you know you'll be using `Nearest`, consider using
6995 /// [`Float::mul_add_mul_rational_prec_assign`] instead. If you know that your target precision
6996 /// is the maximum of the precisions of the inputs, consider using
6997 /// [`Float::mul_add_mul_rational_round_assign`] instead. If both of these things are true,
6998 /// consider using
6999 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
7000 ///
7001 /// # Worst-case complexity
7002 /// $T(n, m) = O(n \log n \log\log n + m)$
7003 ///
7004 /// $M(n, m) = O(n \log n + m)$
7005 ///
7006 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7007 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7008 /// `max(self.significant_bits(), prec)`.
7009 ///
7010 /// # Panics
7011 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
7012 /// representable with `prec` bits.
7013 ///
7014 /// # Examples
7015 /// ```
7016 /// use core::f64::consts::{E, PI, SQRT_2};
7017 /// use malachite_base::rounding_modes::RoundingMode::*;
7018 /// use malachite_float::Float;
7019 /// use malachite_q::Rational;
7020 /// use std::cmp::Ordering::*;
7021 ///
7022 /// let y = Float::from(E);
7023 /// let z = Float::from(SQRT_2);
7024 /// let w = Rational::from_signeds(1, 3);
7025 ///
7026 /// let mut x = Float::from(PI);
7027 /// assert_eq!(
7028 /// x.mul_add_mul_rational_prec_round_assign_val_val_ref(
7029 /// y.clone(),
7030 /// z.clone(),
7031 /// &w,
7032 /// 5,
7033 /// Floor
7034 /// ),
7035 /// Less
7036 /// );
7037 /// assert_eq!(x.to_string(), "9.00");
7038 ///
7039 /// let mut x = Float::from(PI);
7040 /// assert_eq!(
7041 /// x.mul_add_mul_rational_prec_round_assign_val_val_ref(
7042 /// y.clone(),
7043 /// z.clone(),
7044 /// &w,
7045 /// 5,
7046 /// Ceiling
7047 /// ),
7048 /// Greater
7049 /// );
7050 /// assert_eq!(x.to_string(), "9.50");
7051 ///
7052 /// let mut x = Float::from(PI);
7053 /// assert_eq!(
7054 /// x.mul_add_mul_rational_prec_round_assign_val_val_ref(
7055 /// y.clone(),
7056 /// z.clone(),
7057 /// &w,
7058 /// 5,
7059 /// Nearest
7060 /// ),
7061 /// Less
7062 /// );
7063 /// assert_eq!(x.to_string(), "9.00");
7064 /// ```
7065 #[allow(clippy::needless_pass_by_value)]
7066 #[inline]
7067 pub fn mul_add_mul_rational_prec_round_assign_val_val_ref(
7068 &mut self,
7069 y: Self,
7070 z: Self,
7071 w: &Rational,
7072 prec: u64,
7073 rm: RoundingMode,
7074 ) -> Ordering {
7075 let (s, o) = mul_add_mul_rational_helper(self, &y, &z, w, false, prec, rm);
7076 *self = s;
7077 o
7078 }
7079
7080 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
7081 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
7082 /// the specified rounding mode. The middle [`Float`] on the right-hand side is taken by
7083 /// reference and the others by value. An [`Ordering`] is returned, indicating whether the
7084 /// rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
7085 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
7086 ///
7087 /// See [`RoundingMode`] for a description of the possible rounding modes.
7088 ///
7089 /// $$
7090 /// x \gets xy+zw+\varepsilon.
7091 /// $$
7092 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7093 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7094 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
7095 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7096 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
7097 ///
7098 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
7099 /// overflow, and underflow.
7100 ///
7101 /// If you know you'll be using `Nearest`, consider using
7102 /// [`Float::mul_add_mul_rational_prec_assign`] instead. If you know that your target precision
7103 /// is the maximum of the precisions of the inputs, consider using
7104 /// [`Float::mul_add_mul_rational_round_assign`] instead. If both of these things are true,
7105 /// consider using
7106 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
7107 ///
7108 /// # Worst-case complexity
7109 /// $T(n, m) = O(n \log n \log\log n + m)$
7110 ///
7111 /// $M(n, m) = O(n \log n + m)$
7112 ///
7113 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7114 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7115 /// `max(self.significant_bits(), prec)`.
7116 ///
7117 /// # Panics
7118 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
7119 /// representable with `prec` bits.
7120 ///
7121 /// # Examples
7122 /// ```
7123 /// use core::f64::consts::{E, PI, SQRT_2};
7124 /// use malachite_base::rounding_modes::RoundingMode::*;
7125 /// use malachite_float::Float;
7126 /// use malachite_q::Rational;
7127 /// use std::cmp::Ordering::*;
7128 ///
7129 /// let y = Float::from(E);
7130 /// let z = Float::from(SQRT_2);
7131 /// let w = Rational::from_signeds(1, 3);
7132 ///
7133 /// let mut x = Float::from(PI);
7134 /// assert_eq!(
7135 /// x.mul_add_mul_rational_prec_round_assign_val_ref_val(
7136 /// y.clone(),
7137 /// &z,
7138 /// w.clone(),
7139 /// 5,
7140 /// Floor
7141 /// ),
7142 /// Less
7143 /// );
7144 /// assert_eq!(x.to_string(), "9.00");
7145 ///
7146 /// let mut x = Float::from(PI);
7147 /// assert_eq!(
7148 /// x.mul_add_mul_rational_prec_round_assign_val_ref_val(
7149 /// y.clone(),
7150 /// &z,
7151 /// w.clone(),
7152 /// 5,
7153 /// Ceiling
7154 /// ),
7155 /// Greater
7156 /// );
7157 /// assert_eq!(x.to_string(), "9.50");
7158 ///
7159 /// let mut x = Float::from(PI);
7160 /// assert_eq!(
7161 /// x.mul_add_mul_rational_prec_round_assign_val_ref_val(
7162 /// y.clone(),
7163 /// &z,
7164 /// w.clone(),
7165 /// 5,
7166 /// Nearest
7167 /// ),
7168 /// Less
7169 /// );
7170 /// assert_eq!(x.to_string(), "9.00");
7171 /// ```
7172 #[allow(clippy::needless_pass_by_value)]
7173 #[inline]
7174 pub fn mul_add_mul_rational_prec_round_assign_val_ref_val(
7175 &mut self,
7176 y: Self,
7177 z: &Self,
7178 w: Rational,
7179 prec: u64,
7180 rm: RoundingMode,
7181 ) -> Ordering {
7182 let (s, o) = mul_add_mul_rational_helper(self, &y, z, &w, false, prec, rm);
7183 *self = s;
7184 o
7185 }
7186
7187 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
7188 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
7189 /// the specified rounding mode. The first [`Float`] on the right-hand side is taken by value
7190 /// and the others by reference. An [`Ordering`] is returned, indicating whether the rounded sum
7191 /// is less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
7192 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
7193 ///
7194 /// See [`RoundingMode`] for a description of the possible rounding modes.
7195 ///
7196 /// $$
7197 /// x \gets xy+zw+\varepsilon.
7198 /// $$
7199 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7200 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7201 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
7202 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7203 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
7204 ///
7205 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
7206 /// overflow, and underflow.
7207 ///
7208 /// If you know you'll be using `Nearest`, consider using
7209 /// [`Float::mul_add_mul_rational_prec_assign`] instead. If you know that your target precision
7210 /// is the maximum of the precisions of the inputs, consider using
7211 /// [`Float::mul_add_mul_rational_round_assign`] instead. If both of these things are true,
7212 /// consider using
7213 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
7214 ///
7215 /// # Worst-case complexity
7216 /// $T(n, m) = O(n \log n \log\log n + m)$
7217 ///
7218 /// $M(n, m) = O(n \log n + m)$
7219 ///
7220 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7221 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7222 /// `max(self.significant_bits(), prec)`.
7223 ///
7224 /// # Panics
7225 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
7226 /// representable with `prec` bits.
7227 ///
7228 /// # Examples
7229 /// ```
7230 /// use core::f64::consts::{E, PI, SQRT_2};
7231 /// use malachite_base::rounding_modes::RoundingMode::*;
7232 /// use malachite_float::Float;
7233 /// use malachite_q::Rational;
7234 /// use std::cmp::Ordering::*;
7235 ///
7236 /// let y = Float::from(E);
7237 /// let z = Float::from(SQRT_2);
7238 /// let w = Rational::from_signeds(1, 3);
7239 ///
7240 /// let mut x = Float::from(PI);
7241 /// assert_eq!(
7242 /// x.mul_add_mul_rational_prec_round_assign_val_ref_ref(y.clone(), &z, &w, 5, Floor),
7243 /// Less
7244 /// );
7245 /// assert_eq!(x.to_string(), "9.00");
7246 ///
7247 /// let mut x = Float::from(PI);
7248 /// assert_eq!(
7249 /// x.mul_add_mul_rational_prec_round_assign_val_ref_ref(y.clone(), &z, &w, 5, Ceiling),
7250 /// Greater
7251 /// );
7252 /// assert_eq!(x.to_string(), "9.50");
7253 ///
7254 /// let mut x = Float::from(PI);
7255 /// assert_eq!(
7256 /// x.mul_add_mul_rational_prec_round_assign_val_ref_ref(y.clone(), &z, &w, 5, Nearest),
7257 /// Less
7258 /// );
7259 /// assert_eq!(x.to_string(), "9.00");
7260 /// ```
7261 #[allow(clippy::needless_pass_by_value)]
7262 #[inline]
7263 pub fn mul_add_mul_rational_prec_round_assign_val_ref_ref(
7264 &mut self,
7265 y: Self,
7266 z: &Self,
7267 w: &Rational,
7268 prec: u64,
7269 rm: RoundingMode,
7270 ) -> Ordering {
7271 let (s, o) = mul_add_mul_rational_helper(self, &y, z, w, false, prec, rm);
7272 *self = s;
7273 o
7274 }
7275
7276 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
7277 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
7278 /// the specified rounding mode. The first [`Float`] on the right-hand side is taken by
7279 /// reference and the others by value. An [`Ordering`] is returned, indicating whether the
7280 /// rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
7281 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
7282 ///
7283 /// See [`RoundingMode`] for a description of the possible rounding modes.
7284 ///
7285 /// $$
7286 /// x \gets xy+zw+\varepsilon.
7287 /// $$
7288 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7289 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7290 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
7291 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7292 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
7293 ///
7294 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
7295 /// overflow, and underflow.
7296 ///
7297 /// If you know you'll be using `Nearest`, consider using
7298 /// [`Float::mul_add_mul_rational_prec_assign`] instead. If you know that your target precision
7299 /// is the maximum of the precisions of the inputs, consider using
7300 /// [`Float::mul_add_mul_rational_round_assign`] instead. If both of these things are true,
7301 /// consider using
7302 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
7303 ///
7304 /// # Worst-case complexity
7305 /// $T(n, m) = O(n \log n \log\log n + m)$
7306 ///
7307 /// $M(n, m) = O(n \log n + m)$
7308 ///
7309 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7310 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7311 /// `max(self.significant_bits(), prec)`.
7312 ///
7313 /// # Panics
7314 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
7315 /// representable with `prec` bits.
7316 ///
7317 /// # Examples
7318 /// ```
7319 /// use core::f64::consts::{E, PI, SQRT_2};
7320 /// use malachite_base::rounding_modes::RoundingMode::*;
7321 /// use malachite_float::Float;
7322 /// use malachite_q::Rational;
7323 /// use std::cmp::Ordering::*;
7324 ///
7325 /// let y = Float::from(E);
7326 /// let z = Float::from(SQRT_2);
7327 /// let w = Rational::from_signeds(1, 3);
7328 ///
7329 /// let mut x = Float::from(PI);
7330 /// assert_eq!(
7331 /// x.mul_add_mul_rational_prec_round_assign_ref_val_val(
7332 /// &y,
7333 /// z.clone(),
7334 /// w.clone(),
7335 /// 5,
7336 /// Floor
7337 /// ),
7338 /// Less
7339 /// );
7340 /// assert_eq!(x.to_string(), "9.00");
7341 ///
7342 /// let mut x = Float::from(PI);
7343 /// assert_eq!(
7344 /// x.mul_add_mul_rational_prec_round_assign_ref_val_val(
7345 /// &y,
7346 /// z.clone(),
7347 /// w.clone(),
7348 /// 5,
7349 /// Ceiling
7350 /// ),
7351 /// Greater
7352 /// );
7353 /// assert_eq!(x.to_string(), "9.50");
7354 ///
7355 /// let mut x = Float::from(PI);
7356 /// assert_eq!(
7357 /// x.mul_add_mul_rational_prec_round_assign_ref_val_val(
7358 /// &y,
7359 /// z.clone(),
7360 /// w.clone(),
7361 /// 5,
7362 /// Nearest
7363 /// ),
7364 /// Less
7365 /// );
7366 /// assert_eq!(x.to_string(), "9.00");
7367 /// ```
7368 #[allow(clippy::needless_pass_by_value)]
7369 #[inline]
7370 pub fn mul_add_mul_rational_prec_round_assign_ref_val_val(
7371 &mut self,
7372 y: &Self,
7373 z: Self,
7374 w: Rational,
7375 prec: u64,
7376 rm: RoundingMode,
7377 ) -> Ordering {
7378 let (s, o) = mul_add_mul_rational_helper(self, y, &z, &w, false, prec, rm);
7379 *self = s;
7380 o
7381 }
7382
7383 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
7384 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
7385 /// the specified rounding mode. The middle [`Float`] on the right-hand side is taken by value
7386 /// and the others by reference. An [`Ordering`] is returned, indicating whether the rounded sum
7387 /// is less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
7388 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
7389 ///
7390 /// See [`RoundingMode`] for a description of the possible rounding modes.
7391 ///
7392 /// $$
7393 /// x \gets xy+zw+\varepsilon.
7394 /// $$
7395 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7396 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7397 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
7398 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7399 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
7400 ///
7401 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
7402 /// overflow, and underflow.
7403 ///
7404 /// If you know you'll be using `Nearest`, consider using
7405 /// [`Float::mul_add_mul_rational_prec_assign`] instead. If you know that your target precision
7406 /// is the maximum of the precisions of the inputs, consider using
7407 /// [`Float::mul_add_mul_rational_round_assign`] instead. If both of these things are true,
7408 /// consider using
7409 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
7410 ///
7411 /// # Worst-case complexity
7412 /// $T(n, m) = O(n \log n \log\log n + m)$
7413 ///
7414 /// $M(n, m) = O(n \log n + m)$
7415 ///
7416 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7417 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7418 /// `max(self.significant_bits(), prec)`.
7419 ///
7420 /// # Panics
7421 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
7422 /// representable with `prec` bits.
7423 ///
7424 /// # Examples
7425 /// ```
7426 /// use core::f64::consts::{E, PI, SQRT_2};
7427 /// use malachite_base::rounding_modes::RoundingMode::*;
7428 /// use malachite_float::Float;
7429 /// use malachite_q::Rational;
7430 /// use std::cmp::Ordering::*;
7431 ///
7432 /// let y = Float::from(E);
7433 /// let z = Float::from(SQRT_2);
7434 /// let w = Rational::from_signeds(1, 3);
7435 ///
7436 /// let mut x = Float::from(PI);
7437 /// assert_eq!(
7438 /// x.mul_add_mul_rational_prec_round_assign_ref_val_ref(&y, z.clone(), &w, 5, Floor),
7439 /// Less
7440 /// );
7441 /// assert_eq!(x.to_string(), "9.00");
7442 ///
7443 /// let mut x = Float::from(PI);
7444 /// assert_eq!(
7445 /// x.mul_add_mul_rational_prec_round_assign_ref_val_ref(&y, z.clone(), &w, 5, Ceiling),
7446 /// Greater
7447 /// );
7448 /// assert_eq!(x.to_string(), "9.50");
7449 ///
7450 /// let mut x = Float::from(PI);
7451 /// assert_eq!(
7452 /// x.mul_add_mul_rational_prec_round_assign_ref_val_ref(&y, z.clone(), &w, 5, Nearest),
7453 /// Less
7454 /// );
7455 /// assert_eq!(x.to_string(), "9.00");
7456 /// ```
7457 #[allow(clippy::needless_pass_by_value)]
7458 #[inline]
7459 pub fn mul_add_mul_rational_prec_round_assign_ref_val_ref(
7460 &mut self,
7461 y: &Self,
7462 z: Self,
7463 w: &Rational,
7464 prec: u64,
7465 rm: RoundingMode,
7466 ) -> Ordering {
7467 let (s, o) = mul_add_mul_rational_helper(self, y, &z, w, false, prec, rm);
7468 *self = s;
7469 o
7470 }
7471
7472 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
7473 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
7474 /// the specified rounding mode. The last [`Float`] on the right-hand side is taken by value and
7475 /// the others by reference. An [`Ordering`] is returned, indicating whether the rounded sum is
7476 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
7477 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
7478 ///
7479 /// See [`RoundingMode`] for a description of the possible rounding modes.
7480 ///
7481 /// $$
7482 /// x \gets xy+zw+\varepsilon.
7483 /// $$
7484 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7485 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7486 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
7487 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7488 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
7489 ///
7490 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
7491 /// overflow, and underflow.
7492 ///
7493 /// If you know you'll be using `Nearest`, consider using
7494 /// [`Float::mul_add_mul_rational_prec_assign`] instead. If you know that your target precision
7495 /// is the maximum of the precisions of the inputs, consider using
7496 /// [`Float::mul_add_mul_rational_round_assign`] instead. If both of these things are true,
7497 /// consider using
7498 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
7499 ///
7500 /// # Worst-case complexity
7501 /// $T(n, m) = O(n \log n \log\log n + m)$
7502 ///
7503 /// $M(n, m) = O(n \log n + m)$
7504 ///
7505 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7506 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7507 /// `max(self.significant_bits(), prec)`.
7508 ///
7509 /// # Panics
7510 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
7511 /// representable with `prec` bits.
7512 ///
7513 /// # Examples
7514 /// ```
7515 /// use core::f64::consts::{E, PI, SQRT_2};
7516 /// use malachite_base::rounding_modes::RoundingMode::*;
7517 /// use malachite_float::Float;
7518 /// use malachite_q::Rational;
7519 /// use std::cmp::Ordering::*;
7520 ///
7521 /// let y = Float::from(E);
7522 /// let z = Float::from(SQRT_2);
7523 /// let w = Rational::from_signeds(1, 3);
7524 ///
7525 /// let mut x = Float::from(PI);
7526 /// assert_eq!(
7527 /// x.mul_add_mul_rational_prec_round_assign_ref_ref_val(&y, &z, w.clone(), 5, Floor),
7528 /// Less
7529 /// );
7530 /// assert_eq!(x.to_string(), "9.00");
7531 ///
7532 /// let mut x = Float::from(PI);
7533 /// assert_eq!(
7534 /// x.mul_add_mul_rational_prec_round_assign_ref_ref_val(&y, &z, w.clone(), 5, Ceiling),
7535 /// Greater
7536 /// );
7537 /// assert_eq!(x.to_string(), "9.50");
7538 ///
7539 /// let mut x = Float::from(PI);
7540 /// assert_eq!(
7541 /// x.mul_add_mul_rational_prec_round_assign_ref_ref_val(&y, &z, w.clone(), 5, Nearest),
7542 /// Less
7543 /// );
7544 /// assert_eq!(x.to_string(), "9.00");
7545 /// ```
7546 #[allow(clippy::needless_pass_by_value)]
7547 #[inline]
7548 pub fn mul_add_mul_rational_prec_round_assign_ref_ref_val(
7549 &mut self,
7550 y: &Self,
7551 z: &Self,
7552 w: Rational,
7553 prec: u64,
7554 rm: RoundingMode,
7555 ) -> Ordering {
7556 let (s, o) = mul_add_mul_rational_helper(self, y, z, &w, false, prec, rm);
7557 *self = s;
7558 o
7559 }
7560
7561 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
7562 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
7563 /// the specified rounding mode. The [`Float`]s on the right-hand side are all taken by
7564 /// reference. An [`Ordering`] is returned, indicating whether the rounded sum is less than,
7565 /// equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
7566 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
7567 ///
7568 /// See [`RoundingMode`] for a description of the possible rounding modes.
7569 ///
7570 /// $$
7571 /// x \gets xy+zw+\varepsilon.
7572 /// $$
7573 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7574 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7575 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$.
7576 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7577 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$.
7578 ///
7579 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
7580 /// overflow, and underflow.
7581 ///
7582 /// If you know you'll be using `Nearest`, consider using
7583 /// [`Float::mul_add_mul_rational_prec_assign`] instead. If you know that your target precision
7584 /// is the maximum of the precisions of the inputs, consider using
7585 /// [`Float::mul_add_mul_rational_round_assign`] instead. If both of these things are true,
7586 /// consider using
7587 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
7588 ///
7589 /// # Worst-case complexity
7590 /// $T(n, m) = O(n \log n \log\log n + m)$
7591 ///
7592 /// $M(n, m) = O(n \log n + m)$
7593 ///
7594 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7595 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7596 /// `max(self.significant_bits(), prec)`.
7597 ///
7598 /// # Panics
7599 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
7600 /// representable with `prec` bits.
7601 ///
7602 /// # Examples
7603 /// ```
7604 /// use core::f64::consts::{E, PI, SQRT_2};
7605 /// use malachite_base::rounding_modes::RoundingMode::*;
7606 /// use malachite_float::Float;
7607 /// use malachite_q::Rational;
7608 /// use std::cmp::Ordering::*;
7609 ///
7610 /// let y = Float::from(E);
7611 /// let z = Float::from(SQRT_2);
7612 /// let w = Rational::from_signeds(1, 3);
7613 ///
7614 /// let mut x = Float::from(PI);
7615 /// assert_eq!(
7616 /// x.mul_add_mul_rational_prec_round_assign_ref_ref_ref(&y, &z, &w, 5, Floor),
7617 /// Less
7618 /// );
7619 /// assert_eq!(x.to_string(), "9.00");
7620 ///
7621 /// let mut x = Float::from(PI);
7622 /// assert_eq!(
7623 /// x.mul_add_mul_rational_prec_round_assign_ref_ref_ref(&y, &z, &w, 5, Ceiling),
7624 /// Greater
7625 /// );
7626 /// assert_eq!(x.to_string(), "9.50");
7627 ///
7628 /// let mut x = Float::from(PI);
7629 /// assert_eq!(
7630 /// x.mul_add_mul_rational_prec_round_assign_ref_ref_ref(&y, &z, &w, 5, Nearest),
7631 /// Less
7632 /// );
7633 /// assert_eq!(x.to_string(), "9.00");
7634 /// ```
7635 #[allow(clippy::needless_pass_by_value)]
7636 #[inline]
7637 pub fn mul_add_mul_rational_prec_round_assign_ref_ref_ref(
7638 &mut self,
7639 y: &Self,
7640 z: &Self,
7641 w: &Rational,
7642 prec: u64,
7643 rm: RoundingMode,
7644 ) -> Ordering {
7645 let (s, o) = mul_add_mul_rational_helper(self, y, z, w, false, prec, rm);
7646 *self = s;
7647 o
7648 }
7649
7650 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
7651 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
7652 /// its product exactly and the products are not rounded before the final addition, so there is
7653 /// a single rounding. The [`Float`]s and the [`Rational`] are all taken by value. An
7654 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
7655 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
7656 /// this function returns a `NaN` it also returns `Equal`.
7657 ///
7658 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
7659 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
7660 /// the `Nearest` rounding mode.
7661 ///
7662 /// $$
7663 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
7664 /// $$
7665 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7666 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
7667 /// |xy+zw|\rfloor-p}$.
7668 ///
7669 /// If the output has a precision, it is `prec`.
7670 ///
7671 /// Special cases:
7672 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7673 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7674 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7675 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7676 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
7677 /// [`Rational`] counts as an unsigned zero and a positive sign.
7678 /// - If exactly one product is infinite, the result is that product's infinity.
7679 /// - If both products are infinite, the result is their common infinity if their signs agree,
7680 /// and `NaN` otherwise.
7681 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
7682 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
7683 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
7684 ///
7685 /// Overflow and underflow:
7686 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
7687 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
7688 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
7689 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
7690 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
7691 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
7692 ///
7693 /// If you want to use a rounding mode other than `Nearest`, consider using
7694 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know that your target precision
7695 /// is the maximum of the precisions of the inputs, consider using
7696 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
7697 ///
7698 /// # Worst-case complexity
7699 /// $T(n, m) = O(n \log n \log\log n + m)$
7700 ///
7701 /// $M(n, m) = O(n \log n + m)$
7702 ///
7703 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7704 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7705 /// `max(self.significant_bits(), prec)`.
7706 ///
7707 /// # Panics
7708 /// Panics if `prec` is zero.
7709 ///
7710 /// # Examples
7711 /// ```
7712 /// use core::f64::consts::{E, PI, SQRT_2};
7713 /// use malachite_float::Float;
7714 /// use malachite_q::Rational;
7715 /// use std::cmp::Ordering::*;
7716 ///
7717 /// let x = Float::from(PI);
7718 /// let y = Float::from(E);
7719 /// let z = Float::from(SQRT_2);
7720 /// let w = Rational::from_signeds(1, 3);
7721 ///
7722 /// let (sum, o) = x
7723 /// .clone()
7724 /// .mul_add_mul_rational_prec(y.clone(), z.clone(), w.clone(), 5);
7725 /// assert_eq!(sum.to_string(), "9.00");
7726 /// assert_eq!(o, Less);
7727 ///
7728 /// let (sum, o) = x
7729 /// .clone()
7730 /// .mul_add_mul_rational_prec(y.clone(), z.clone(), w.clone(), 20);
7731 /// assert_eq!(sum.to_string(), "9.0111389");
7732 /// assert_eq!(o, Greater);
7733 /// ```
7734 #[allow(clippy::needless_pass_by_value)]
7735 #[inline]
7736 pub fn mul_add_mul_rational_prec(
7737 self,
7738 y: Self,
7739 z: Self,
7740 w: Rational,
7741 prec: u64,
7742 ) -> (Self, Ordering) {
7743 self.mul_add_mul_rational_prec_round(y, z, w, prec, Nearest)
7744 }
7745
7746 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
7747 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
7748 /// its product exactly and the products are not rounded before the final addition, so there is
7749 /// a single rounding. The [`Float`]s are taken by value and the [`Rational`] by reference. An
7750 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
7751 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
7752 /// this function returns a `NaN` it also returns `Equal`.
7753 ///
7754 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
7755 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
7756 /// the `Nearest` rounding mode.
7757 ///
7758 /// $$
7759 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
7760 /// $$
7761 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7762 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
7763 /// |xy+zw|\rfloor-p}$.
7764 ///
7765 /// If the output has a precision, it is `prec`.
7766 ///
7767 /// Special cases:
7768 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7769 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7770 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7771 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7772 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
7773 /// [`Rational`] counts as an unsigned zero and a positive sign.
7774 /// - If exactly one product is infinite, the result is that product's infinity.
7775 /// - If both products are infinite, the result is their common infinity if their signs agree,
7776 /// and `NaN` otherwise.
7777 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
7778 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
7779 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
7780 ///
7781 /// Overflow and underflow:
7782 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
7783 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
7784 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
7785 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
7786 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
7787 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
7788 ///
7789 /// If you want to use a rounding mode other than `Nearest`, consider using
7790 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know that your target precision
7791 /// is the maximum of the precisions of the inputs, consider using
7792 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
7793 ///
7794 /// # Worst-case complexity
7795 /// $T(n, m) = O(n \log n \log\log n + m)$
7796 ///
7797 /// $M(n, m) = O(n \log n + m)$
7798 ///
7799 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7800 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7801 /// `max(self.significant_bits(), prec)`.
7802 ///
7803 /// # Panics
7804 /// Panics if `prec` is zero.
7805 ///
7806 /// # Examples
7807 /// ```
7808 /// use core::f64::consts::{E, PI, SQRT_2};
7809 /// use malachite_float::Float;
7810 /// use malachite_q::Rational;
7811 /// use std::cmp::Ordering::*;
7812 ///
7813 /// let x = Float::from(PI);
7814 /// let y = Float::from(E);
7815 /// let z = Float::from(SQRT_2);
7816 /// let w = Rational::from_signeds(1, 3);
7817 ///
7818 /// let (sum, o) =
7819 /// x.clone()
7820 /// .mul_add_mul_rational_prec_val_val_val_ref(y.clone(), z.clone(), &w, 5);
7821 /// assert_eq!(sum.to_string(), "9.00");
7822 /// assert_eq!(o, Less);
7823 ///
7824 /// let (sum, o) =
7825 /// x.clone()
7826 /// .mul_add_mul_rational_prec_val_val_val_ref(y.clone(), z.clone(), &w, 20);
7827 /// assert_eq!(sum.to_string(), "9.0111389");
7828 /// assert_eq!(o, Greater);
7829 /// ```
7830 #[allow(clippy::needless_pass_by_value)]
7831 #[inline]
7832 pub fn mul_add_mul_rational_prec_val_val_val_ref(
7833 self,
7834 y: Self,
7835 z: Self,
7836 w: &Rational,
7837 prec: u64,
7838 ) -> (Self, Ordering) {
7839 self.mul_add_mul_rational_prec_round_val_val_val_ref(y, z, w, prec, Nearest)
7840 }
7841
7842 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
7843 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
7844 /// its product exactly and the products are not rounded before the final addition, so there is
7845 /// a single rounding. The third [`Float`] is taken by reference and the other operands by
7846 /// value. An [`Ordering`] is also returned, indicating whether the rounded sum is less than,
7847 /// equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
7848 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
7849 ///
7850 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
7851 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
7852 /// the `Nearest` rounding mode.
7853 ///
7854 /// $$
7855 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
7856 /// $$
7857 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7858 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
7859 /// |xy+zw|\rfloor-p}$.
7860 ///
7861 /// If the output has a precision, it is `prec`.
7862 ///
7863 /// Special cases:
7864 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7865 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7866 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7867 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7868 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
7869 /// [`Rational`] counts as an unsigned zero and a positive sign.
7870 /// - If exactly one product is infinite, the result is that product's infinity.
7871 /// - If both products are infinite, the result is their common infinity if their signs agree,
7872 /// and `NaN` otherwise.
7873 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
7874 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
7875 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
7876 ///
7877 /// Overflow and underflow:
7878 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
7879 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
7880 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
7881 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
7882 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
7883 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
7884 ///
7885 /// If you want to use a rounding mode other than `Nearest`, consider using
7886 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know that your target precision
7887 /// is the maximum of the precisions of the inputs, consider using
7888 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
7889 ///
7890 /// # Worst-case complexity
7891 /// $T(n, m) = O(n \log n \log\log n + m)$
7892 ///
7893 /// $M(n, m) = O(n \log n + m)$
7894 ///
7895 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7896 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7897 /// `max(self.significant_bits(), prec)`.
7898 ///
7899 /// # Panics
7900 /// Panics if `prec` is zero.
7901 ///
7902 /// # Examples
7903 /// ```
7904 /// use core::f64::consts::{E, PI, SQRT_2};
7905 /// use malachite_float::Float;
7906 /// use malachite_q::Rational;
7907 /// use std::cmp::Ordering::*;
7908 ///
7909 /// let x = Float::from(PI);
7910 /// let y = Float::from(E);
7911 /// let z = Float::from(SQRT_2);
7912 /// let w = Rational::from_signeds(1, 3);
7913 ///
7914 /// let (sum, o) =
7915 /// x.clone()
7916 /// .mul_add_mul_rational_prec_val_val_ref_val(y.clone(), &z, w.clone(), 5);
7917 /// assert_eq!(sum.to_string(), "9.00");
7918 /// assert_eq!(o, Less);
7919 ///
7920 /// let (sum, o) =
7921 /// x.clone()
7922 /// .mul_add_mul_rational_prec_val_val_ref_val(y.clone(), &z, w.clone(), 20);
7923 /// assert_eq!(sum.to_string(), "9.0111389");
7924 /// assert_eq!(o, Greater);
7925 /// ```
7926 #[allow(clippy::needless_pass_by_value)]
7927 #[inline]
7928 pub fn mul_add_mul_rational_prec_val_val_ref_val(
7929 self,
7930 y: Self,
7931 z: &Self,
7932 w: Rational,
7933 prec: u64,
7934 ) -> (Self, Ordering) {
7935 self.mul_add_mul_rational_prec_round_val_val_ref_val(y, z, w, prec, Nearest)
7936 }
7937
7938 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
7939 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
7940 /// its product exactly and the products are not rounded before the final addition, so there is
7941 /// a single rounding. The first two [`Float`]s are taken by value and the third [`Float`] and
7942 /// the [`Rational`] by reference. An [`Ordering`] is also returned, indicating whether the
7943 /// rounded sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
7944 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
7945 ///
7946 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
7947 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
7948 /// the `Nearest` rounding mode.
7949 ///
7950 /// $$
7951 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
7952 /// $$
7953 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7954 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
7955 /// |xy+zw|\rfloor-p}$.
7956 ///
7957 /// If the output has a precision, it is `prec`.
7958 ///
7959 /// Special cases:
7960 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7961 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7962 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7963 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7964 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
7965 /// [`Rational`] counts as an unsigned zero and a positive sign.
7966 /// - If exactly one product is infinite, the result is that product's infinity.
7967 /// - If both products are infinite, the result is their common infinity if their signs agree,
7968 /// and `NaN` otherwise.
7969 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
7970 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
7971 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
7972 ///
7973 /// Overflow and underflow:
7974 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
7975 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
7976 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
7977 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
7978 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
7979 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
7980 ///
7981 /// If you want to use a rounding mode other than `Nearest`, consider using
7982 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know that your target precision
7983 /// is the maximum of the precisions of the inputs, consider using
7984 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
7985 ///
7986 /// # Worst-case complexity
7987 /// $T(n, m) = O(n \log n \log\log n + m)$
7988 ///
7989 /// $M(n, m) = O(n \log n + m)$
7990 ///
7991 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7992 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7993 /// `max(self.significant_bits(), prec)`.
7994 ///
7995 /// # Panics
7996 /// Panics if `prec` is zero.
7997 ///
7998 /// # Examples
7999 /// ```
8000 /// use core::f64::consts::{E, PI, SQRT_2};
8001 /// use malachite_float::Float;
8002 /// use malachite_q::Rational;
8003 /// use std::cmp::Ordering::*;
8004 ///
8005 /// let x = Float::from(PI);
8006 /// let y = Float::from(E);
8007 /// let z = Float::from(SQRT_2);
8008 /// let w = Rational::from_signeds(1, 3);
8009 ///
8010 /// let (sum, o) = x
8011 /// .clone()
8012 /// .mul_add_mul_rational_prec_val_val_ref_ref(y.clone(), &z, &w, 5);
8013 /// assert_eq!(sum.to_string(), "9.00");
8014 /// assert_eq!(o, Less);
8015 ///
8016 /// let (sum, o) = x
8017 /// .clone()
8018 /// .mul_add_mul_rational_prec_val_val_ref_ref(y.clone(), &z, &w, 20);
8019 /// assert_eq!(sum.to_string(), "9.0111389");
8020 /// assert_eq!(o, Greater);
8021 /// ```
8022 #[allow(clippy::needless_pass_by_value)]
8023 #[inline]
8024 pub fn mul_add_mul_rational_prec_val_val_ref_ref(
8025 self,
8026 y: Self,
8027 z: &Self,
8028 w: &Rational,
8029 prec: u64,
8030 ) -> (Self, Ordering) {
8031 self.mul_add_mul_rational_prec_round_val_val_ref_ref(y, z, w, prec, Nearest)
8032 }
8033
8034 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
8035 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
8036 /// its product exactly and the products are not rounded before the final addition, so there is
8037 /// a single rounding. The second [`Float`] is taken by reference and the other operands by
8038 /// value. An [`Ordering`] is also returned, indicating whether the rounded sum is less than,
8039 /// equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
8040 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
8041 ///
8042 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8043 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8044 /// the `Nearest` rounding mode.
8045 ///
8046 /// $$
8047 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
8048 /// $$
8049 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8050 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8051 /// |xy+zw|\rfloor-p}$.
8052 ///
8053 /// If the output has a precision, it is `prec`.
8054 ///
8055 /// Special cases:
8056 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8057 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8058 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8059 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8060 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
8061 /// [`Rational`] counts as an unsigned zero and a positive sign.
8062 /// - If exactly one product is infinite, the result is that product's infinity.
8063 /// - If both products are infinite, the result is their common infinity if their signs agree,
8064 /// and `NaN` otherwise.
8065 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
8066 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
8067 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
8068 ///
8069 /// Overflow and underflow:
8070 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8071 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8072 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8073 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8074 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
8075 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8076 ///
8077 /// If you want to use a rounding mode other than `Nearest`, consider using
8078 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know that your target precision
8079 /// is the maximum of the precisions of the inputs, consider using
8080 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
8081 ///
8082 /// # Worst-case complexity
8083 /// $T(n, m) = O(n \log n \log\log n + m)$
8084 ///
8085 /// $M(n, m) = O(n \log n + m)$
8086 ///
8087 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8088 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8089 /// `max(self.significant_bits(), prec)`.
8090 ///
8091 /// # Panics
8092 /// Panics if `prec` is zero.
8093 ///
8094 /// # Examples
8095 /// ```
8096 /// use core::f64::consts::{E, PI, SQRT_2};
8097 /// use malachite_float::Float;
8098 /// use malachite_q::Rational;
8099 /// use std::cmp::Ordering::*;
8100 ///
8101 /// let x = Float::from(PI);
8102 /// let y = Float::from(E);
8103 /// let z = Float::from(SQRT_2);
8104 /// let w = Rational::from_signeds(1, 3);
8105 ///
8106 /// let (sum, o) =
8107 /// x.clone()
8108 /// .mul_add_mul_rational_prec_val_ref_val_val(&y, z.clone(), w.clone(), 5);
8109 /// assert_eq!(sum.to_string(), "9.00");
8110 /// assert_eq!(o, Less);
8111 ///
8112 /// let (sum, o) =
8113 /// x.clone()
8114 /// .mul_add_mul_rational_prec_val_ref_val_val(&y, z.clone(), w.clone(), 20);
8115 /// assert_eq!(sum.to_string(), "9.0111389");
8116 /// assert_eq!(o, Greater);
8117 /// ```
8118 #[allow(clippy::needless_pass_by_value)]
8119 #[inline]
8120 pub fn mul_add_mul_rational_prec_val_ref_val_val(
8121 self,
8122 y: &Self,
8123 z: Self,
8124 w: Rational,
8125 prec: u64,
8126 ) -> (Self, Ordering) {
8127 self.mul_add_mul_rational_prec_round_val_ref_val_val(y, z, w, prec, Nearest)
8128 }
8129
8130 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
8131 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
8132 /// its product exactly and the products are not rounded before the final addition, so there is
8133 /// a single rounding. The second [`Float`] and the [`Rational`] are taken by reference and the
8134 /// other operands by value. An [`Ordering`] is also returned, indicating whether the rounded
8135 /// sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
8136 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
8137 ///
8138 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8139 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8140 /// the `Nearest` rounding mode.
8141 ///
8142 /// $$
8143 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
8144 /// $$
8145 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8146 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8147 /// |xy+zw|\rfloor-p}$.
8148 ///
8149 /// If the output has a precision, it is `prec`.
8150 ///
8151 /// Special cases:
8152 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8153 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8154 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8155 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8156 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
8157 /// [`Rational`] counts as an unsigned zero and a positive sign.
8158 /// - If exactly one product is infinite, the result is that product's infinity.
8159 /// - If both products are infinite, the result is their common infinity if their signs agree,
8160 /// and `NaN` otherwise.
8161 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
8162 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
8163 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
8164 ///
8165 /// Overflow and underflow:
8166 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8167 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8168 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8169 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8170 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
8171 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8172 ///
8173 /// If you want to use a rounding mode other than `Nearest`, consider using
8174 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know that your target precision
8175 /// is the maximum of the precisions of the inputs, consider using
8176 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
8177 ///
8178 /// # Worst-case complexity
8179 /// $T(n, m) = O(n \log n \log\log n + m)$
8180 ///
8181 /// $M(n, m) = O(n \log n + m)$
8182 ///
8183 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8184 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8185 /// `max(self.significant_bits(), prec)`.
8186 ///
8187 /// # Panics
8188 /// Panics if `prec` is zero.
8189 ///
8190 /// # Examples
8191 /// ```
8192 /// use core::f64::consts::{E, PI, SQRT_2};
8193 /// use malachite_float::Float;
8194 /// use malachite_q::Rational;
8195 /// use std::cmp::Ordering::*;
8196 ///
8197 /// let x = Float::from(PI);
8198 /// let y = Float::from(E);
8199 /// let z = Float::from(SQRT_2);
8200 /// let w = Rational::from_signeds(1, 3);
8201 ///
8202 /// let (sum, o) = x
8203 /// .clone()
8204 /// .mul_add_mul_rational_prec_val_ref_val_ref(&y, z.clone(), &w, 5);
8205 /// assert_eq!(sum.to_string(), "9.00");
8206 /// assert_eq!(o, Less);
8207 ///
8208 /// let (sum, o) = x
8209 /// .clone()
8210 /// .mul_add_mul_rational_prec_val_ref_val_ref(&y, z.clone(), &w, 20);
8211 /// assert_eq!(sum.to_string(), "9.0111389");
8212 /// assert_eq!(o, Greater);
8213 /// ```
8214 #[allow(clippy::needless_pass_by_value)]
8215 #[inline]
8216 pub fn mul_add_mul_rational_prec_val_ref_val_ref(
8217 self,
8218 y: &Self,
8219 z: Self,
8220 w: &Rational,
8221 prec: u64,
8222 ) -> (Self, Ordering) {
8223 self.mul_add_mul_rational_prec_round_val_ref_val_ref(y, z, w, prec, Nearest)
8224 }
8225
8226 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
8227 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
8228 /// its product exactly and the products are not rounded before the final addition, so there is
8229 /// a single rounding. The second and third [`Float`]s are taken by reference and the other
8230 /// operands by value. An [`Ordering`] is also returned, indicating whether the rounded sum is
8231 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
8232 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
8233 ///
8234 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8235 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8236 /// the `Nearest` rounding mode.
8237 ///
8238 /// $$
8239 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
8240 /// $$
8241 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8242 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8243 /// |xy+zw|\rfloor-p}$.
8244 ///
8245 /// If the output has a precision, it is `prec`.
8246 ///
8247 /// Special cases:
8248 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8249 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8250 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8251 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8252 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
8253 /// [`Rational`] counts as an unsigned zero and a positive sign.
8254 /// - If exactly one product is infinite, the result is that product's infinity.
8255 /// - If both products are infinite, the result is their common infinity if their signs agree,
8256 /// and `NaN` otherwise.
8257 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
8258 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
8259 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
8260 ///
8261 /// Overflow and underflow:
8262 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8263 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8264 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8265 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8266 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
8267 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8268 ///
8269 /// If you want to use a rounding mode other than `Nearest`, consider using
8270 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know that your target precision
8271 /// is the maximum of the precisions of the inputs, consider using
8272 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
8273 ///
8274 /// # Worst-case complexity
8275 /// $T(n, m) = O(n \log n \log\log n + m)$
8276 ///
8277 /// $M(n, m) = O(n \log n + m)$
8278 ///
8279 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8280 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8281 /// `max(self.significant_bits(), prec)`.
8282 ///
8283 /// # Panics
8284 /// Panics if `prec` is zero.
8285 ///
8286 /// # Examples
8287 /// ```
8288 /// use core::f64::consts::{E, PI, SQRT_2};
8289 /// use malachite_float::Float;
8290 /// use malachite_q::Rational;
8291 /// use std::cmp::Ordering::*;
8292 ///
8293 /// let x = Float::from(PI);
8294 /// let y = Float::from(E);
8295 /// let z = Float::from(SQRT_2);
8296 /// let w = Rational::from_signeds(1, 3);
8297 ///
8298 /// let (sum, o) = x
8299 /// .clone()
8300 /// .mul_add_mul_rational_prec_val_ref_ref_val(&y, &z, w.clone(), 5);
8301 /// assert_eq!(sum.to_string(), "9.00");
8302 /// assert_eq!(o, Less);
8303 ///
8304 /// let (sum, o) = x
8305 /// .clone()
8306 /// .mul_add_mul_rational_prec_val_ref_ref_val(&y, &z, w.clone(), 20);
8307 /// assert_eq!(sum.to_string(), "9.0111389");
8308 /// assert_eq!(o, Greater);
8309 /// ```
8310 #[allow(clippy::needless_pass_by_value)]
8311 #[inline]
8312 pub fn mul_add_mul_rational_prec_val_ref_ref_val(
8313 self,
8314 y: &Self,
8315 z: &Self,
8316 w: Rational,
8317 prec: u64,
8318 ) -> (Self, Ordering) {
8319 self.mul_add_mul_rational_prec_round_val_ref_ref_val(y, z, w, prec, Nearest)
8320 }
8321
8322 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
8323 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
8324 /// its product exactly and the products are not rounded before the final addition, so there is
8325 /// a single rounding. The first [`Float`] is taken by value and the other operands by
8326 /// reference. An [`Ordering`] is also returned, indicating whether the rounded sum is less
8327 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
8328 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
8329 ///
8330 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8331 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8332 /// the `Nearest` rounding mode.
8333 ///
8334 /// $$
8335 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
8336 /// $$
8337 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8338 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8339 /// |xy+zw|\rfloor-p}$.
8340 ///
8341 /// If the output has a precision, it is `prec`.
8342 ///
8343 /// Special cases:
8344 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8345 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8346 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8347 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8348 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
8349 /// [`Rational`] counts as an unsigned zero and a positive sign.
8350 /// - If exactly one product is infinite, the result is that product's infinity.
8351 /// - If both products are infinite, the result is their common infinity if their signs agree,
8352 /// and `NaN` otherwise.
8353 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
8354 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
8355 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
8356 ///
8357 /// Overflow and underflow:
8358 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8359 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8360 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8361 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8362 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
8363 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8364 ///
8365 /// If you want to use a rounding mode other than `Nearest`, consider using
8366 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know that your target precision
8367 /// is the maximum of the precisions of the inputs, consider using
8368 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
8369 ///
8370 /// # Worst-case complexity
8371 /// $T(n, m) = O(n \log n \log\log n + m)$
8372 ///
8373 /// $M(n, m) = O(n \log n + m)$
8374 ///
8375 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8376 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8377 /// `max(self.significant_bits(), prec)`.
8378 ///
8379 /// # Panics
8380 /// Panics if `prec` is zero.
8381 ///
8382 /// # Examples
8383 /// ```
8384 /// use core::f64::consts::{E, PI, SQRT_2};
8385 /// use malachite_float::Float;
8386 /// use malachite_q::Rational;
8387 /// use std::cmp::Ordering::*;
8388 ///
8389 /// let x = Float::from(PI);
8390 /// let y = Float::from(E);
8391 /// let z = Float::from(SQRT_2);
8392 /// let w = Rational::from_signeds(1, 3);
8393 ///
8394 /// let (sum, o) = x
8395 /// .clone()
8396 /// .mul_add_mul_rational_prec_val_ref_ref_ref(&y, &z, &w, 5);
8397 /// assert_eq!(sum.to_string(), "9.00");
8398 /// assert_eq!(o, Less);
8399 ///
8400 /// let (sum, o) = x
8401 /// .clone()
8402 /// .mul_add_mul_rational_prec_val_ref_ref_ref(&y, &z, &w, 20);
8403 /// assert_eq!(sum.to_string(), "9.0111389");
8404 /// assert_eq!(o, Greater);
8405 /// ```
8406 #[allow(clippy::needless_pass_by_value)]
8407 #[inline]
8408 pub fn mul_add_mul_rational_prec_val_ref_ref_ref(
8409 self,
8410 y: &Self,
8411 z: &Self,
8412 w: &Rational,
8413 prec: u64,
8414 ) -> (Self, Ordering) {
8415 self.mul_add_mul_rational_prec_round_val_ref_ref_ref(y, z, w, prec, Nearest)
8416 }
8417
8418 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
8419 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
8420 /// its product exactly and the products are not rounded before the final addition, so there is
8421 /// a single rounding. The [`Float`]s and the [`Rational`] are all taken by reference. An
8422 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
8423 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
8424 /// this function returns a `NaN` it also returns `Equal`.
8425 ///
8426 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8427 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8428 /// the `Nearest` rounding mode.
8429 ///
8430 /// $$
8431 /// f(x,y,z,w,p) = xy+zw+\varepsilon.
8432 /// $$
8433 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8434 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8435 /// |xy+zw|\rfloor-p}$.
8436 ///
8437 /// If the output has a precision, it is `prec`.
8438 ///
8439 /// Special cases:
8440 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8441 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8442 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8443 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8444 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
8445 /// [`Rational`] counts as an unsigned zero and a positive sign.
8446 /// - If exactly one product is infinite, the result is that product's infinity.
8447 /// - If both products are infinite, the result is their common infinity if their signs agree,
8448 /// and `NaN` otherwise.
8449 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
8450 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$, the products are
8451 /// - $f(x,y,z,w,p)=0.0$ if $xy=-zw$ and the products are finite and nonzero
8452 ///
8453 /// Overflow and underflow:
8454 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8455 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8456 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8457 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8458 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
8459 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8460 ///
8461 /// If you want to use a rounding mode other than `Nearest`, consider using
8462 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know that your target precision
8463 /// is the maximum of the precisions of the inputs, consider using
8464 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
8465 ///
8466 /// # Worst-case complexity
8467 /// $T(n, m) = O(n \log n \log\log n + m)$
8468 ///
8469 /// $M(n, m) = O(n \log n + m)$
8470 ///
8471 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8472 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8473 /// `max(self.significant_bits(), prec)`.
8474 ///
8475 /// # Panics
8476 /// Panics if `prec` is zero.
8477 ///
8478 /// # Examples
8479 /// ```
8480 /// use core::f64::consts::{E, PI, SQRT_2};
8481 /// use malachite_float::Float;
8482 /// use malachite_q::Rational;
8483 /// use std::cmp::Ordering::*;
8484 ///
8485 /// let x = Float::from(PI);
8486 /// let y = Float::from(E);
8487 /// let z = Float::from(SQRT_2);
8488 /// let w = Rational::from_signeds(1, 3);
8489 ///
8490 /// let (sum, o) = x.mul_add_mul_rational_prec_ref_ref_ref_ref(&y, &z, &w, 5);
8491 /// assert_eq!(sum.to_string(), "9.00");
8492 /// assert_eq!(o, Less);
8493 ///
8494 /// let (sum, o) = x.mul_add_mul_rational_prec_ref_ref_ref_ref(&y, &z, &w, 20);
8495 /// assert_eq!(sum.to_string(), "9.0111389");
8496 /// assert_eq!(o, Greater);
8497 /// ```
8498 #[allow(clippy::needless_pass_by_value)]
8499 #[inline]
8500 pub fn mul_add_mul_rational_prec_ref_ref_ref_ref(
8501 &self,
8502 y: &Self,
8503 z: &Self,
8504 w: &Rational,
8505 prec: u64,
8506 ) -> (Self, Ordering) {
8507 self.mul_add_mul_rational_prec_round_ref_ref_ref_ref(y, z, w, prec, Nearest)
8508 }
8509
8510 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
8511 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
8512 /// specified precision. The [`Float`]s on the right-hand side are all taken by value. An
8513 /// [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
8514 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
8515 /// this function assigns a `NaN` it also returns `Equal`.
8516 ///
8517 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8518 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8519 /// the `Nearest` rounding mode.
8520 ///
8521 /// $$
8522 /// x \gets xy+zw+\varepsilon.
8523 /// $$
8524 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8525 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8526 /// |xy+zw|\rfloor-p}$.
8527 ///
8528 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
8529 /// overflow, and underflow.
8530 ///
8531 /// If you want to use a rounding mode other than `Nearest`, consider using
8532 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know that your target
8533 /// precision is the maximum of the precisions of the inputs, consider using
8534 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
8535 ///
8536 /// # Worst-case complexity
8537 /// $T(n, m) = O(n \log n \log\log n + m)$
8538 ///
8539 /// $M(n, m) = O(n \log n + m)$
8540 ///
8541 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8542 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8543 /// `max(self.significant_bits(), prec)`.
8544 ///
8545 /// # Panics
8546 /// Panics if `prec` is zero.
8547 ///
8548 /// # Examples
8549 /// ```
8550 /// use core::f64::consts::{E, PI, SQRT_2};
8551 /// use malachite_float::Float;
8552 /// use malachite_q::Rational;
8553 /// use std::cmp::Ordering::*;
8554 ///
8555 /// let y = Float::from(E);
8556 /// let z = Float::from(SQRT_2);
8557 /// let w = Rational::from_signeds(1, 3);
8558 ///
8559 /// let mut x = Float::from(PI);
8560 /// assert_eq!(
8561 /// x.mul_add_mul_rational_prec_assign(y.clone(), z.clone(), w.clone(), 5),
8562 /// Less
8563 /// );
8564 /// assert_eq!(x.to_string(), "9.00");
8565 ///
8566 /// let mut x = Float::from(PI);
8567 /// assert_eq!(
8568 /// x.mul_add_mul_rational_prec_assign(y.clone(), z.clone(), w.clone(), 20),
8569 /// Greater
8570 /// );
8571 /// assert_eq!(x.to_string(), "9.0111389");
8572 /// ```
8573 #[allow(clippy::needless_pass_by_value)]
8574 #[inline]
8575 pub fn mul_add_mul_rational_prec_assign(
8576 &mut self,
8577 y: Self,
8578 z: Self,
8579 w: Rational,
8580 prec: u64,
8581 ) -> Ordering {
8582 self.mul_add_mul_rational_prec_round_assign(y, z, w, prec, Nearest)
8583 }
8584
8585 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
8586 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
8587 /// specified precision. The last [`Float`] on the right-hand side is taken by reference and the
8588 /// others by value. An [`Ordering`] is returned, indicating whether the rounded sum is less
8589 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
8590 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
8591 ///
8592 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8593 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8594 /// the `Nearest` rounding mode.
8595 ///
8596 /// $$
8597 /// x \gets xy+zw+\varepsilon.
8598 /// $$
8599 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8600 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8601 /// |xy+zw|\rfloor-p}$.
8602 ///
8603 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
8604 /// overflow, and underflow.
8605 ///
8606 /// If you want to use a rounding mode other than `Nearest`, consider using
8607 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know that your target
8608 /// precision is the maximum of the precisions of the inputs, consider using
8609 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
8610 ///
8611 /// # Worst-case complexity
8612 /// $T(n, m) = O(n \log n \log\log n + m)$
8613 ///
8614 /// $M(n, m) = O(n \log n + m)$
8615 ///
8616 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8617 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8618 /// `max(self.significant_bits(), prec)`.
8619 ///
8620 /// # Panics
8621 /// Panics if `prec` is zero.
8622 ///
8623 /// # Examples
8624 /// ```
8625 /// use core::f64::consts::{E, PI, SQRT_2};
8626 /// use malachite_float::Float;
8627 /// use malachite_q::Rational;
8628 /// use std::cmp::Ordering::*;
8629 ///
8630 /// let y = Float::from(E);
8631 /// let z = Float::from(SQRT_2);
8632 /// let w = Rational::from_signeds(1, 3);
8633 ///
8634 /// let mut x = Float::from(PI);
8635 /// assert_eq!(
8636 /// x.mul_add_mul_rational_prec_assign_val_val_ref(y.clone(), z.clone(), &w, 5),
8637 /// Less
8638 /// );
8639 /// assert_eq!(x.to_string(), "9.00");
8640 ///
8641 /// let mut x = Float::from(PI);
8642 /// assert_eq!(
8643 /// x.mul_add_mul_rational_prec_assign_val_val_ref(y.clone(), z.clone(), &w, 20),
8644 /// Greater
8645 /// );
8646 /// assert_eq!(x.to_string(), "9.0111389");
8647 /// ```
8648 #[allow(clippy::needless_pass_by_value)]
8649 #[inline]
8650 pub fn mul_add_mul_rational_prec_assign_val_val_ref(
8651 &mut self,
8652 y: Self,
8653 z: Self,
8654 w: &Rational,
8655 prec: u64,
8656 ) -> Ordering {
8657 self.mul_add_mul_rational_prec_round_assign_val_val_ref(y, z, w, prec, Nearest)
8658 }
8659
8660 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
8661 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
8662 /// specified precision. The middle [`Float`] on the right-hand side is taken by reference and
8663 /// the others by value. An [`Ordering`] is returned, indicating whether the rounded sum is less
8664 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
8665 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
8666 ///
8667 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8668 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8669 /// the `Nearest` rounding mode.
8670 ///
8671 /// $$
8672 /// x \gets xy+zw+\varepsilon.
8673 /// $$
8674 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8675 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8676 /// |xy+zw|\rfloor-p}$.
8677 ///
8678 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
8679 /// overflow, and underflow.
8680 ///
8681 /// If you want to use a rounding mode other than `Nearest`, consider using
8682 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know that your target
8683 /// precision is the maximum of the precisions of the inputs, consider using
8684 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
8685 ///
8686 /// # Worst-case complexity
8687 /// $T(n, m) = O(n \log n \log\log n + m)$
8688 ///
8689 /// $M(n, m) = O(n \log n + m)$
8690 ///
8691 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8692 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8693 /// `max(self.significant_bits(), prec)`.
8694 ///
8695 /// # Panics
8696 /// Panics if `prec` is zero.
8697 ///
8698 /// # Examples
8699 /// ```
8700 /// use core::f64::consts::{E, PI, SQRT_2};
8701 /// use malachite_float::Float;
8702 /// use malachite_q::Rational;
8703 /// use std::cmp::Ordering::*;
8704 ///
8705 /// let y = Float::from(E);
8706 /// let z = Float::from(SQRT_2);
8707 /// let w = Rational::from_signeds(1, 3);
8708 ///
8709 /// let mut x = Float::from(PI);
8710 /// assert_eq!(
8711 /// x.mul_add_mul_rational_prec_assign_val_ref_val(y.clone(), &z, w.clone(), 5),
8712 /// Less
8713 /// );
8714 /// assert_eq!(x.to_string(), "9.00");
8715 ///
8716 /// let mut x = Float::from(PI);
8717 /// assert_eq!(
8718 /// x.mul_add_mul_rational_prec_assign_val_ref_val(y.clone(), &z, w.clone(), 20),
8719 /// Greater
8720 /// );
8721 /// assert_eq!(x.to_string(), "9.0111389");
8722 /// ```
8723 #[allow(clippy::needless_pass_by_value)]
8724 #[inline]
8725 pub fn mul_add_mul_rational_prec_assign_val_ref_val(
8726 &mut self,
8727 y: Self,
8728 z: &Self,
8729 w: Rational,
8730 prec: u64,
8731 ) -> Ordering {
8732 self.mul_add_mul_rational_prec_round_assign_val_ref_val(y, z, w, prec, Nearest)
8733 }
8734
8735 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
8736 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
8737 /// specified precision. The first [`Float`] on the right-hand side is taken by value and the
8738 /// others by reference. An [`Ordering`] is returned, indicating whether the rounded sum is less
8739 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
8740 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
8741 ///
8742 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8743 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8744 /// the `Nearest` rounding mode.
8745 ///
8746 /// $$
8747 /// x \gets xy+zw+\varepsilon.
8748 /// $$
8749 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8750 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8751 /// |xy+zw|\rfloor-p}$.
8752 ///
8753 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
8754 /// overflow, and underflow.
8755 ///
8756 /// If you want to use a rounding mode other than `Nearest`, consider using
8757 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know that your target
8758 /// precision is the maximum of the precisions of the inputs, consider using
8759 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
8760 ///
8761 /// # Worst-case complexity
8762 /// $T(n, m) = O(n \log n \log\log n + m)$
8763 ///
8764 /// $M(n, m) = O(n \log n + m)$
8765 ///
8766 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8767 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8768 /// `max(self.significant_bits(), prec)`.
8769 ///
8770 /// # Panics
8771 /// Panics if `prec` is zero.
8772 ///
8773 /// # Examples
8774 /// ```
8775 /// use core::f64::consts::{E, PI, SQRT_2};
8776 /// use malachite_float::Float;
8777 /// use malachite_q::Rational;
8778 /// use std::cmp::Ordering::*;
8779 ///
8780 /// let y = Float::from(E);
8781 /// let z = Float::from(SQRT_2);
8782 /// let w = Rational::from_signeds(1, 3);
8783 ///
8784 /// let mut x = Float::from(PI);
8785 /// assert_eq!(
8786 /// x.mul_add_mul_rational_prec_assign_val_ref_ref(y.clone(), &z, &w, 5),
8787 /// Less
8788 /// );
8789 /// assert_eq!(x.to_string(), "9.00");
8790 ///
8791 /// let mut x = Float::from(PI);
8792 /// assert_eq!(
8793 /// x.mul_add_mul_rational_prec_assign_val_ref_ref(y.clone(), &z, &w, 20),
8794 /// Greater
8795 /// );
8796 /// assert_eq!(x.to_string(), "9.0111389");
8797 /// ```
8798 #[allow(clippy::needless_pass_by_value)]
8799 #[inline]
8800 pub fn mul_add_mul_rational_prec_assign_val_ref_ref(
8801 &mut self,
8802 y: Self,
8803 z: &Self,
8804 w: &Rational,
8805 prec: u64,
8806 ) -> Ordering {
8807 self.mul_add_mul_rational_prec_round_assign_val_ref_ref(y, z, w, prec, Nearest)
8808 }
8809
8810 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
8811 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
8812 /// specified precision. The first [`Float`] on the right-hand side is taken by reference and
8813 /// the others by value. An [`Ordering`] is returned, indicating whether the rounded sum is less
8814 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
8815 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
8816 ///
8817 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8818 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8819 /// the `Nearest` rounding mode.
8820 ///
8821 /// $$
8822 /// x \gets xy+zw+\varepsilon.
8823 /// $$
8824 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8825 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8826 /// |xy+zw|\rfloor-p}$.
8827 ///
8828 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
8829 /// overflow, and underflow.
8830 ///
8831 /// If you want to use a rounding mode other than `Nearest`, consider using
8832 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know that your target
8833 /// precision is the maximum of the precisions of the inputs, consider using
8834 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
8835 ///
8836 /// # Worst-case complexity
8837 /// $T(n, m) = O(n \log n \log\log n + m)$
8838 ///
8839 /// $M(n, m) = O(n \log n + m)$
8840 ///
8841 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8842 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8843 /// `max(self.significant_bits(), prec)`.
8844 ///
8845 /// # Panics
8846 /// Panics if `prec` is zero.
8847 ///
8848 /// # Examples
8849 /// ```
8850 /// use core::f64::consts::{E, PI, SQRT_2};
8851 /// use malachite_float::Float;
8852 /// use malachite_q::Rational;
8853 /// use std::cmp::Ordering::*;
8854 ///
8855 /// let y = Float::from(E);
8856 /// let z = Float::from(SQRT_2);
8857 /// let w = Rational::from_signeds(1, 3);
8858 ///
8859 /// let mut x = Float::from(PI);
8860 /// assert_eq!(
8861 /// x.mul_add_mul_rational_prec_assign_ref_val_val(&y, z.clone(), w.clone(), 5),
8862 /// Less
8863 /// );
8864 /// assert_eq!(x.to_string(), "9.00");
8865 ///
8866 /// let mut x = Float::from(PI);
8867 /// assert_eq!(
8868 /// x.mul_add_mul_rational_prec_assign_ref_val_val(&y, z.clone(), w.clone(), 20),
8869 /// Greater
8870 /// );
8871 /// assert_eq!(x.to_string(), "9.0111389");
8872 /// ```
8873 #[allow(clippy::needless_pass_by_value)]
8874 #[inline]
8875 pub fn mul_add_mul_rational_prec_assign_ref_val_val(
8876 &mut self,
8877 y: &Self,
8878 z: Self,
8879 w: Rational,
8880 prec: u64,
8881 ) -> Ordering {
8882 self.mul_add_mul_rational_prec_round_assign_ref_val_val(y, z, w, prec, Nearest)
8883 }
8884
8885 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
8886 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
8887 /// specified precision. The middle [`Float`] on the right-hand side is taken by value and the
8888 /// others by reference. An [`Ordering`] is returned, indicating whether the rounded sum is less
8889 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
8890 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
8891 ///
8892 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8893 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8894 /// the `Nearest` rounding mode.
8895 ///
8896 /// $$
8897 /// x \gets xy+zw+\varepsilon.
8898 /// $$
8899 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8900 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8901 /// |xy+zw|\rfloor-p}$.
8902 ///
8903 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
8904 /// overflow, and underflow.
8905 ///
8906 /// If you want to use a rounding mode other than `Nearest`, consider using
8907 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know that your target
8908 /// precision is the maximum of the precisions of the inputs, consider using
8909 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
8910 ///
8911 /// # Worst-case complexity
8912 /// $T(n, m) = O(n \log n \log\log n + m)$
8913 ///
8914 /// $M(n, m) = O(n \log n + m)$
8915 ///
8916 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8917 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8918 /// `max(self.significant_bits(), prec)`.
8919 ///
8920 /// # Panics
8921 /// Panics if `prec` is zero.
8922 ///
8923 /// # Examples
8924 /// ```
8925 /// use core::f64::consts::{E, PI, SQRT_2};
8926 /// use malachite_float::Float;
8927 /// use malachite_q::Rational;
8928 /// use std::cmp::Ordering::*;
8929 ///
8930 /// let y = Float::from(E);
8931 /// let z = Float::from(SQRT_2);
8932 /// let w = Rational::from_signeds(1, 3);
8933 ///
8934 /// let mut x = Float::from(PI);
8935 /// assert_eq!(
8936 /// x.mul_add_mul_rational_prec_assign_ref_val_ref(&y, z.clone(), &w, 5),
8937 /// Less
8938 /// );
8939 /// assert_eq!(x.to_string(), "9.00");
8940 ///
8941 /// let mut x = Float::from(PI);
8942 /// assert_eq!(
8943 /// x.mul_add_mul_rational_prec_assign_ref_val_ref(&y, z.clone(), &w, 20),
8944 /// Greater
8945 /// );
8946 /// assert_eq!(x.to_string(), "9.0111389");
8947 /// ```
8948 #[allow(clippy::needless_pass_by_value)]
8949 #[inline]
8950 pub fn mul_add_mul_rational_prec_assign_ref_val_ref(
8951 &mut self,
8952 y: &Self,
8953 z: Self,
8954 w: &Rational,
8955 prec: u64,
8956 ) -> Ordering {
8957 self.mul_add_mul_rational_prec_round_assign_ref_val_ref(y, z, w, prec, Nearest)
8958 }
8959
8960 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
8961 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
8962 /// specified precision. The last [`Float`] on the right-hand side is taken by value and the
8963 /// others by reference. An [`Ordering`] is returned, indicating whether the rounded sum is less
8964 /// than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
8965 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
8966 ///
8967 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8968 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8969 /// the `Nearest` rounding mode.
8970 ///
8971 /// $$
8972 /// x \gets xy+zw+\varepsilon.
8973 /// $$
8974 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8975 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8976 /// |xy+zw|\rfloor-p}$.
8977 ///
8978 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
8979 /// overflow, and underflow.
8980 ///
8981 /// If you want to use a rounding mode other than `Nearest`, consider using
8982 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know that your target
8983 /// precision is the maximum of the precisions of the inputs, consider using
8984 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
8985 ///
8986 /// # Worst-case complexity
8987 /// $T(n, m) = O(n \log n \log\log n + m)$
8988 ///
8989 /// $M(n, m) = O(n \log n + m)$
8990 ///
8991 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8992 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8993 /// `max(self.significant_bits(), prec)`.
8994 ///
8995 /// # Panics
8996 /// Panics if `prec` is zero.
8997 ///
8998 /// # Examples
8999 /// ```
9000 /// use core::f64::consts::{E, PI, SQRT_2};
9001 /// use malachite_float::Float;
9002 /// use malachite_q::Rational;
9003 /// use std::cmp::Ordering::*;
9004 ///
9005 /// let y = Float::from(E);
9006 /// let z = Float::from(SQRT_2);
9007 /// let w = Rational::from_signeds(1, 3);
9008 ///
9009 /// let mut x = Float::from(PI);
9010 /// assert_eq!(
9011 /// x.mul_add_mul_rational_prec_assign_ref_ref_val(&y, &z, w.clone(), 5),
9012 /// Less
9013 /// );
9014 /// assert_eq!(x.to_string(), "9.00");
9015 ///
9016 /// let mut x = Float::from(PI);
9017 /// assert_eq!(
9018 /// x.mul_add_mul_rational_prec_assign_ref_ref_val(&y, &z, w.clone(), 20),
9019 /// Greater
9020 /// );
9021 /// assert_eq!(x.to_string(), "9.0111389");
9022 /// ```
9023 #[allow(clippy::needless_pass_by_value)]
9024 #[inline]
9025 pub fn mul_add_mul_rational_prec_assign_ref_ref_val(
9026 &mut self,
9027 y: &Self,
9028 z: &Self,
9029 w: Rational,
9030 prec: u64,
9031 ) -> Ordering {
9032 self.mul_add_mul_rational_prec_round_assign_ref_ref_val(y, z, w, prec, Nearest)
9033 }
9034
9035 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
9036 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
9037 /// specified precision. The [`Float`]s on the right-hand side are all taken by reference. An
9038 /// [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
9039 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
9040 /// this function assigns a `NaN` it also returns `Equal`.
9041 ///
9042 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
9043 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
9044 /// the `Nearest` rounding mode.
9045 ///
9046 /// $$
9047 /// x \gets xy+zw+\varepsilon.
9048 /// $$
9049 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9050 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
9051 /// |xy+zw|\rfloor-p}$.
9052 ///
9053 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
9054 /// overflow, and underflow.
9055 ///
9056 /// If you want to use a rounding mode other than `Nearest`, consider using
9057 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know that your target
9058 /// precision is the maximum of the precisions of the inputs, consider using
9059 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
9060 ///
9061 /// # Worst-case complexity
9062 /// $T(n, m) = O(n \log n \log\log n + m)$
9063 ///
9064 /// $M(n, m) = O(n \log n + m)$
9065 ///
9066 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9067 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9068 /// `max(self.significant_bits(), prec)`.
9069 ///
9070 /// # Panics
9071 /// Panics if `prec` is zero.
9072 ///
9073 /// # Examples
9074 /// ```
9075 /// use core::f64::consts::{E, PI, SQRT_2};
9076 /// use malachite_float::Float;
9077 /// use malachite_q::Rational;
9078 /// use std::cmp::Ordering::*;
9079 ///
9080 /// let y = Float::from(E);
9081 /// let z = Float::from(SQRT_2);
9082 /// let w = Rational::from_signeds(1, 3);
9083 ///
9084 /// let mut x = Float::from(PI);
9085 /// assert_eq!(
9086 /// x.mul_add_mul_rational_prec_assign_ref_ref_ref(&y, &z, &w, 5),
9087 /// Less
9088 /// );
9089 /// assert_eq!(x.to_string(), "9.00");
9090 ///
9091 /// let mut x = Float::from(PI);
9092 /// assert_eq!(
9093 /// x.mul_add_mul_rational_prec_assign_ref_ref_ref(&y, &z, &w, 20),
9094 /// Greater
9095 /// );
9096 /// assert_eq!(x.to_string(), "9.0111389");
9097 /// ```
9098 #[allow(clippy::needless_pass_by_value)]
9099 #[inline]
9100 pub fn mul_add_mul_rational_prec_assign_ref_ref_ref(
9101 &mut self,
9102 y: &Self,
9103 z: &Self,
9104 w: &Rational,
9105 prec: u64,
9106 ) -> Ordering {
9107 self.mul_add_mul_rational_prec_round_assign_ref_ref_ref(y, z, w, prec, Nearest)
9108 }
9109
9110 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
9111 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9112 /// exactly and the products are not rounded before the final addition, so there is a single
9113 /// rounding. The [`Float`]s and the [`Rational`] are all taken by value. An [`Ordering`] is
9114 /// also returned, indicating whether the rounded sum is less than, equal to, or greater than
9115 /// the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
9116 /// returns a `NaN` it also returns `Equal`.
9117 ///
9118 /// The precision of the output is the maximum of the precisions of the inputs. See
9119 /// [`RoundingMode`] for a description of the possible rounding modes.
9120 ///
9121 /// $$
9122 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
9123 /// $$
9124 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9125 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
9126 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
9127 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
9128 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
9129 ///
9130 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9131 ///
9132 /// Special cases:
9133 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9134 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9135 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9136 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9137 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
9138 /// [`Rational`] counts as an unsigned zero and a positive sign.
9139 /// - If exactly one product is infinite, the result is that product's infinity.
9140 /// - If both products are infinite, the result is their common infinity if their signs agree,
9141 /// and `NaN` otherwise.
9142 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
9143 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
9144 /// `Floor`
9145 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
9146 ///
9147 /// Overflow and underflow:
9148 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
9149 /// returned instead.
9150 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
9151 /// is returned instead, where `p` is the precision of the output.
9152 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
9153 /// returned instead.
9154 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
9155 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
9156 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
9157 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
9158 /// instead.
9159 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
9160 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
9161 /// returned instead.
9162 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
9163 /// instead.
9164 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
9165 /// instead.
9166 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
9167 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
9168 /// returned instead.
9169 ///
9170 /// If you want to specify an output precision, consider using
9171 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know you'll be using the
9172 /// `Nearest` rounding mode, consider using
9173 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
9174 ///
9175 /// # Worst-case complexity
9176 /// $T(n, m) = O(n \log n \log\log n + m)$
9177 ///
9178 /// $M(n, m) = O(n \log n + m)$
9179 ///
9180 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9181 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9182 /// `self.significant_bits()`.
9183 ///
9184 /// # Panics
9185 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
9186 /// represent the output.
9187 ///
9188 /// # Examples
9189 /// ```
9190 /// use core::f64::consts::{E, PI, SQRT_2};
9191 /// use malachite_base::rounding_modes::RoundingMode::*;
9192 /// use malachite_float::Float;
9193 /// use malachite_q::Rational;
9194 /// use std::cmp::Ordering::*;
9195 ///
9196 /// let x = Float::from(PI);
9197 /// let y = Float::from(E);
9198 /// let z = Float::from(SQRT_2);
9199 /// let w = Rational::from_signeds(1, 3);
9200 ///
9201 /// let (sum, o) = x
9202 /// .clone()
9203 /// .mul_add_mul_rational_round(y.clone(), z.clone(), w.clone(), Floor);
9204 /// assert_eq!(sum.to_string(), "9.0111387434645973");
9205 /// assert_eq!(o, Less);
9206 ///
9207 /// let (sum, o) =
9208 /// x.clone()
9209 /// .mul_add_mul_rational_round(y.clone(), z.clone(), w.clone(), Ceiling);
9210 /// assert_eq!(sum.to_string(), "9.0111387434645991");
9211 /// assert_eq!(o, Greater);
9212 ///
9213 /// let (sum, o) =
9214 /// x.clone()
9215 /// .mul_add_mul_rational_round(y.clone(), z.clone(), w.clone(), Nearest);
9216 /// assert_eq!(sum.to_string(), "9.0111387434645973");
9217 /// assert_eq!(o, Less);
9218 /// ```
9219 #[allow(clippy::needless_pass_by_value)]
9220 #[inline]
9221 pub fn mul_add_mul_rational_round(
9222 self,
9223 y: Self,
9224 z: Self,
9225 w: Rational,
9226 rm: RoundingMode,
9227 ) -> (Self, Ordering) {
9228 let prec = max!(
9229 self.significant_bits(),
9230 y.significant_bits(),
9231 z.significant_bits()
9232 );
9233 self.mul_add_mul_rational_prec_round(y, z, w, prec, rm)
9234 }
9235
9236 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
9237 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9238 /// exactly and the products are not rounded before the final addition, so there is a single
9239 /// rounding. The [`Float`]s are taken by value and the [`Rational`] by reference. An
9240 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
9241 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
9242 /// this function returns a `NaN` it also returns `Equal`.
9243 ///
9244 /// The precision of the output is the maximum of the precisions of the inputs. See
9245 /// [`RoundingMode`] for a description of the possible rounding modes.
9246 ///
9247 /// $$
9248 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
9249 /// $$
9250 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9251 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
9252 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
9253 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
9254 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
9255 ///
9256 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9257 ///
9258 /// Special cases:
9259 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9260 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9261 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9262 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9263 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
9264 /// [`Rational`] counts as an unsigned zero and a positive sign.
9265 /// - If exactly one product is infinite, the result is that product's infinity.
9266 /// - If both products are infinite, the result is their common infinity if their signs agree,
9267 /// and `NaN` otherwise.
9268 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
9269 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
9270 /// `Floor`
9271 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
9272 ///
9273 /// Overflow and underflow:
9274 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
9275 /// returned instead.
9276 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
9277 /// is returned instead, where `p` is the precision of the output.
9278 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
9279 /// returned instead.
9280 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
9281 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
9282 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
9283 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
9284 /// instead.
9285 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
9286 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
9287 /// returned instead.
9288 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
9289 /// instead.
9290 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
9291 /// instead.
9292 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
9293 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
9294 /// returned instead.
9295 ///
9296 /// If you want to specify an output precision, consider using
9297 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know you'll be using the
9298 /// `Nearest` rounding mode, consider using
9299 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
9300 ///
9301 /// # Worst-case complexity
9302 /// $T(n, m) = O(n \log n \log\log n + m)$
9303 ///
9304 /// $M(n, m) = O(n \log n + m)$
9305 ///
9306 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9307 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9308 /// `self.significant_bits()`.
9309 ///
9310 /// # Panics
9311 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
9312 /// represent the output.
9313 ///
9314 /// # Examples
9315 /// ```
9316 /// use core::f64::consts::{E, PI, SQRT_2};
9317 /// use malachite_base::rounding_modes::RoundingMode::*;
9318 /// use malachite_float::Float;
9319 /// use malachite_q::Rational;
9320 /// use std::cmp::Ordering::*;
9321 ///
9322 /// let x = Float::from(PI);
9323 /// let y = Float::from(E);
9324 /// let z = Float::from(SQRT_2);
9325 /// let w = Rational::from_signeds(1, 3);
9326 ///
9327 /// let (sum, o) =
9328 /// x.clone()
9329 /// .mul_add_mul_rational_round_val_val_val_ref(y.clone(), z.clone(), &w, Floor);
9330 /// assert_eq!(sum.to_string(), "9.0111387434645973");
9331 /// assert_eq!(o, Less);
9332 ///
9333 /// let (sum, o) =
9334 /// x.clone()
9335 /// .mul_add_mul_rational_round_val_val_val_ref(y.clone(), z.clone(), &w, Ceiling);
9336 /// assert_eq!(sum.to_string(), "9.0111387434645991");
9337 /// assert_eq!(o, Greater);
9338 ///
9339 /// let (sum, o) =
9340 /// x.clone()
9341 /// .mul_add_mul_rational_round_val_val_val_ref(y.clone(), z.clone(), &w, Nearest);
9342 /// assert_eq!(sum.to_string(), "9.0111387434645973");
9343 /// assert_eq!(o, Less);
9344 /// ```
9345 #[allow(clippy::needless_pass_by_value)]
9346 #[inline]
9347 pub fn mul_add_mul_rational_round_val_val_val_ref(
9348 self,
9349 y: Self,
9350 z: Self,
9351 w: &Rational,
9352 rm: RoundingMode,
9353 ) -> (Self, Ordering) {
9354 let prec = max!(
9355 self.significant_bits(),
9356 y.significant_bits(),
9357 z.significant_bits()
9358 );
9359 self.mul_add_mul_rational_prec_round_val_val_val_ref(y, z, w, prec, rm)
9360 }
9361
9362 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
9363 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9364 /// exactly and the products are not rounded before the final addition, so there is a single
9365 /// rounding. The third [`Float`] is taken by reference and the other operands by value. An
9366 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
9367 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
9368 /// this function returns a `NaN` it also returns `Equal`.
9369 ///
9370 /// The precision of the output is the maximum of the precisions of the inputs. See
9371 /// [`RoundingMode`] for a description of the possible rounding modes.
9372 ///
9373 /// $$
9374 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
9375 /// $$
9376 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9377 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
9378 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
9379 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
9380 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
9381 ///
9382 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9383 ///
9384 /// Special cases:
9385 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9386 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9387 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9388 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9389 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
9390 /// [`Rational`] counts as an unsigned zero and a positive sign.
9391 /// - If exactly one product is infinite, the result is that product's infinity.
9392 /// - If both products are infinite, the result is their common infinity if their signs agree,
9393 /// and `NaN` otherwise.
9394 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
9395 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
9396 /// `Floor`
9397 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
9398 ///
9399 /// Overflow and underflow:
9400 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
9401 /// returned instead.
9402 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
9403 /// is returned instead, where `p` is the precision of the output.
9404 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
9405 /// returned instead.
9406 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
9407 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
9408 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
9409 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
9410 /// instead.
9411 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
9412 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
9413 /// returned instead.
9414 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
9415 /// instead.
9416 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
9417 /// instead.
9418 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
9419 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
9420 /// returned instead.
9421 ///
9422 /// If you want to specify an output precision, consider using
9423 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know you'll be using the
9424 /// `Nearest` rounding mode, consider using
9425 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
9426 ///
9427 /// # Worst-case complexity
9428 /// $T(n, m) = O(n \log n \log\log n + m)$
9429 ///
9430 /// $M(n, m) = O(n \log n + m)$
9431 ///
9432 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9433 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9434 /// `self.significant_bits()`.
9435 ///
9436 /// # Panics
9437 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
9438 /// represent the output.
9439 ///
9440 /// # Examples
9441 /// ```
9442 /// use core::f64::consts::{E, PI, SQRT_2};
9443 /// use malachite_base::rounding_modes::RoundingMode::*;
9444 /// use malachite_float::Float;
9445 /// use malachite_q::Rational;
9446 /// use std::cmp::Ordering::*;
9447 ///
9448 /// let x = Float::from(PI);
9449 /// let y = Float::from(E);
9450 /// let z = Float::from(SQRT_2);
9451 /// let w = Rational::from_signeds(1, 3);
9452 ///
9453 /// let (sum, o) =
9454 /// x.clone()
9455 /// .mul_add_mul_rational_round_val_val_ref_val(y.clone(), &z, w.clone(), Floor);
9456 /// assert_eq!(sum.to_string(), "9.0111387434645973");
9457 /// assert_eq!(o, Less);
9458 ///
9459 /// let (sum, o) =
9460 /// x.clone()
9461 /// .mul_add_mul_rational_round_val_val_ref_val(y.clone(), &z, w.clone(), Ceiling);
9462 /// assert_eq!(sum.to_string(), "9.0111387434645991");
9463 /// assert_eq!(o, Greater);
9464 ///
9465 /// let (sum, o) =
9466 /// x.clone()
9467 /// .mul_add_mul_rational_round_val_val_ref_val(y.clone(), &z, w.clone(), Nearest);
9468 /// assert_eq!(sum.to_string(), "9.0111387434645973");
9469 /// assert_eq!(o, Less);
9470 /// ```
9471 #[allow(clippy::needless_pass_by_value)]
9472 #[inline]
9473 pub fn mul_add_mul_rational_round_val_val_ref_val(
9474 self,
9475 y: Self,
9476 z: &Self,
9477 w: Rational,
9478 rm: RoundingMode,
9479 ) -> (Self, Ordering) {
9480 let prec = max!(
9481 self.significant_bits(),
9482 y.significant_bits(),
9483 z.significant_bits()
9484 );
9485 self.mul_add_mul_rational_prec_round_val_val_ref_val(y, z, w, prec, rm)
9486 }
9487
9488 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
9489 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9490 /// exactly and the products are not rounded before the final addition, so there is a single
9491 /// rounding. The first two [`Float`]s are taken by value and the third [`Float`] and the
9492 /// [`Rational`] by reference. An [`Ordering`] is also returned, indicating whether the rounded
9493 /// sum is less than, equal to, or greater than the exact sum. Although `NaN`s are not
9494 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
9495 ///
9496 /// The precision of the output is the maximum of the precisions of the inputs. See
9497 /// [`RoundingMode`] for a description of the possible rounding modes.
9498 ///
9499 /// $$
9500 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
9501 /// $$
9502 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9503 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
9504 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
9505 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
9506 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
9507 ///
9508 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9509 ///
9510 /// Special cases:
9511 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9512 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9513 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9514 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9515 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
9516 /// [`Rational`] counts as an unsigned zero and a positive sign.
9517 /// - If exactly one product is infinite, the result is that product's infinity.
9518 /// - If both products are infinite, the result is their common infinity if their signs agree,
9519 /// and `NaN` otherwise.
9520 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
9521 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
9522 /// `Floor`
9523 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
9524 ///
9525 /// Overflow and underflow:
9526 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
9527 /// returned instead.
9528 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
9529 /// is returned instead, where `p` is the precision of the output.
9530 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
9531 /// returned instead.
9532 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
9533 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
9534 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
9535 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
9536 /// instead.
9537 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
9538 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
9539 /// returned instead.
9540 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
9541 /// instead.
9542 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
9543 /// instead.
9544 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
9545 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
9546 /// returned instead.
9547 ///
9548 /// If you want to specify an output precision, consider using
9549 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know you'll be using the
9550 /// `Nearest` rounding mode, consider using
9551 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
9552 ///
9553 /// # Worst-case complexity
9554 /// $T(n, m) = O(n \log n \log\log n + m)$
9555 ///
9556 /// $M(n, m) = O(n \log n + m)$
9557 ///
9558 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9559 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9560 /// `self.significant_bits()`.
9561 ///
9562 /// # Panics
9563 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
9564 /// represent the output.
9565 ///
9566 /// # Examples
9567 /// ```
9568 /// use core::f64::consts::{E, PI, SQRT_2};
9569 /// use malachite_base::rounding_modes::RoundingMode::*;
9570 /// use malachite_float::Float;
9571 /// use malachite_q::Rational;
9572 /// use std::cmp::Ordering::*;
9573 ///
9574 /// let x = Float::from(PI);
9575 /// let y = Float::from(E);
9576 /// let z = Float::from(SQRT_2);
9577 /// let w = Rational::from_signeds(1, 3);
9578 ///
9579 /// let (sum, o) =
9580 /// x.clone()
9581 /// .mul_add_mul_rational_round_val_val_ref_ref(y.clone(), &z, &w, Floor);
9582 /// assert_eq!(sum.to_string(), "9.0111387434645973");
9583 /// assert_eq!(o, Less);
9584 ///
9585 /// let (sum, o) =
9586 /// x.clone()
9587 /// .mul_add_mul_rational_round_val_val_ref_ref(y.clone(), &z, &w, Ceiling);
9588 /// assert_eq!(sum.to_string(), "9.0111387434645991");
9589 /// assert_eq!(o, Greater);
9590 ///
9591 /// let (sum, o) =
9592 /// x.clone()
9593 /// .mul_add_mul_rational_round_val_val_ref_ref(y.clone(), &z, &w, Nearest);
9594 /// assert_eq!(sum.to_string(), "9.0111387434645973");
9595 /// assert_eq!(o, Less);
9596 /// ```
9597 #[allow(clippy::needless_pass_by_value)]
9598 #[inline]
9599 pub fn mul_add_mul_rational_round_val_val_ref_ref(
9600 self,
9601 y: Self,
9602 z: &Self,
9603 w: &Rational,
9604 rm: RoundingMode,
9605 ) -> (Self, Ordering) {
9606 let prec = max!(
9607 self.significant_bits(),
9608 y.significant_bits(),
9609 z.significant_bits()
9610 );
9611 self.mul_add_mul_rational_prec_round_val_val_ref_ref(y, z, w, prec, rm)
9612 }
9613
9614 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
9615 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9616 /// exactly and the products are not rounded before the final addition, so there is a single
9617 /// rounding. The second [`Float`] is taken by reference and the other operands by value. An
9618 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
9619 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
9620 /// this function returns a `NaN` it also returns `Equal`.
9621 ///
9622 /// The precision of the output is the maximum of the precisions of the inputs. See
9623 /// [`RoundingMode`] for a description of the possible rounding modes.
9624 ///
9625 /// $$
9626 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
9627 /// $$
9628 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9629 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
9630 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
9631 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
9632 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
9633 ///
9634 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9635 ///
9636 /// Special cases:
9637 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9638 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9639 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9640 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9641 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
9642 /// [`Rational`] counts as an unsigned zero and a positive sign.
9643 /// - If exactly one product is infinite, the result is that product's infinity.
9644 /// - If both products are infinite, the result is their common infinity if their signs agree,
9645 /// and `NaN` otherwise.
9646 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
9647 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
9648 /// `Floor`
9649 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
9650 ///
9651 /// Overflow and underflow:
9652 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
9653 /// returned instead.
9654 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
9655 /// is returned instead, where `p` is the precision of the output.
9656 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
9657 /// returned instead.
9658 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
9659 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
9660 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
9661 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
9662 /// instead.
9663 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
9664 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
9665 /// returned instead.
9666 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
9667 /// instead.
9668 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
9669 /// instead.
9670 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
9671 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
9672 /// returned instead.
9673 ///
9674 /// If you want to specify an output precision, consider using
9675 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know you'll be using the
9676 /// `Nearest` rounding mode, consider using
9677 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
9678 ///
9679 /// # Worst-case complexity
9680 /// $T(n, m) = O(n \log n \log\log n + m)$
9681 ///
9682 /// $M(n, m) = O(n \log n + m)$
9683 ///
9684 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9685 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9686 /// `self.significant_bits()`.
9687 ///
9688 /// # Panics
9689 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
9690 /// represent the output.
9691 ///
9692 /// # Examples
9693 /// ```
9694 /// use core::f64::consts::{E, PI, SQRT_2};
9695 /// use malachite_base::rounding_modes::RoundingMode::*;
9696 /// use malachite_float::Float;
9697 /// use malachite_q::Rational;
9698 /// use std::cmp::Ordering::*;
9699 ///
9700 /// let x = Float::from(PI);
9701 /// let y = Float::from(E);
9702 /// let z = Float::from(SQRT_2);
9703 /// let w = Rational::from_signeds(1, 3);
9704 ///
9705 /// let (sum, o) =
9706 /// x.clone()
9707 /// .mul_add_mul_rational_round_val_ref_val_val(&y, z.clone(), w.clone(), Floor);
9708 /// assert_eq!(sum.to_string(), "9.0111387434645973");
9709 /// assert_eq!(o, Less);
9710 ///
9711 /// let (sum, o) =
9712 /// x.clone()
9713 /// .mul_add_mul_rational_round_val_ref_val_val(&y, z.clone(), w.clone(), Ceiling);
9714 /// assert_eq!(sum.to_string(), "9.0111387434645991");
9715 /// assert_eq!(o, Greater);
9716 ///
9717 /// let (sum, o) =
9718 /// x.clone()
9719 /// .mul_add_mul_rational_round_val_ref_val_val(&y, z.clone(), w.clone(), Nearest);
9720 /// assert_eq!(sum.to_string(), "9.0111387434645973");
9721 /// assert_eq!(o, Less);
9722 /// ```
9723 #[allow(clippy::needless_pass_by_value)]
9724 #[inline]
9725 pub fn mul_add_mul_rational_round_val_ref_val_val(
9726 self,
9727 y: &Self,
9728 z: Self,
9729 w: Rational,
9730 rm: RoundingMode,
9731 ) -> (Self, Ordering) {
9732 let prec = max!(
9733 self.significant_bits(),
9734 y.significant_bits(),
9735 z.significant_bits()
9736 );
9737 self.mul_add_mul_rational_prec_round_val_ref_val_val(y, z, w, prec, rm)
9738 }
9739
9740 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
9741 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9742 /// exactly and the products are not rounded before the final addition, so there is a single
9743 /// rounding. The second [`Float`] and the [`Rational`] are taken by reference and the other
9744 /// operands by value. An [`Ordering`] is also returned, indicating whether the rounded sum is
9745 /// less than, equal to, or greater than the exact sum. Although `NaN`s are not comparable to
9746 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
9747 ///
9748 /// The precision of the output is the maximum of the precisions of the inputs. See
9749 /// [`RoundingMode`] for a description of the possible rounding modes.
9750 ///
9751 /// $$
9752 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
9753 /// $$
9754 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9755 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
9756 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
9757 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
9758 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
9759 ///
9760 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9761 ///
9762 /// Special cases:
9763 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9764 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9765 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9766 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9767 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
9768 /// [`Rational`] counts as an unsigned zero and a positive sign.
9769 /// - If exactly one product is infinite, the result is that product's infinity.
9770 /// - If both products are infinite, the result is their common infinity if their signs agree,
9771 /// and `NaN` otherwise.
9772 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
9773 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
9774 /// `Floor`
9775 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
9776 ///
9777 /// Overflow and underflow:
9778 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
9779 /// returned instead.
9780 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
9781 /// is returned instead, where `p` is the precision of the output.
9782 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
9783 /// returned instead.
9784 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
9785 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
9786 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
9787 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
9788 /// instead.
9789 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
9790 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
9791 /// returned instead.
9792 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
9793 /// instead.
9794 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
9795 /// instead.
9796 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
9797 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
9798 /// returned instead.
9799 ///
9800 /// If you want to specify an output precision, consider using
9801 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know you'll be using the
9802 /// `Nearest` rounding mode, consider using
9803 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
9804 ///
9805 /// # Worst-case complexity
9806 /// $T(n, m) = O(n \log n \log\log n + m)$
9807 ///
9808 /// $M(n, m) = O(n \log n + m)$
9809 ///
9810 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9811 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9812 /// `self.significant_bits()`.
9813 ///
9814 /// # Panics
9815 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
9816 /// represent the output.
9817 ///
9818 /// # Examples
9819 /// ```
9820 /// use core::f64::consts::{E, PI, SQRT_2};
9821 /// use malachite_base::rounding_modes::RoundingMode::*;
9822 /// use malachite_float::Float;
9823 /// use malachite_q::Rational;
9824 /// use std::cmp::Ordering::*;
9825 ///
9826 /// let x = Float::from(PI);
9827 /// let y = Float::from(E);
9828 /// let z = Float::from(SQRT_2);
9829 /// let w = Rational::from_signeds(1, 3);
9830 ///
9831 /// let (sum, o) =
9832 /// x.clone()
9833 /// .mul_add_mul_rational_round_val_ref_val_ref(&y, z.clone(), &w, Floor);
9834 /// assert_eq!(sum.to_string(), "9.0111387434645973");
9835 /// assert_eq!(o, Less);
9836 ///
9837 /// let (sum, o) =
9838 /// x.clone()
9839 /// .mul_add_mul_rational_round_val_ref_val_ref(&y, z.clone(), &w, Ceiling);
9840 /// assert_eq!(sum.to_string(), "9.0111387434645991");
9841 /// assert_eq!(o, Greater);
9842 ///
9843 /// let (sum, o) =
9844 /// x.clone()
9845 /// .mul_add_mul_rational_round_val_ref_val_ref(&y, z.clone(), &w, Nearest);
9846 /// assert_eq!(sum.to_string(), "9.0111387434645973");
9847 /// assert_eq!(o, Less);
9848 /// ```
9849 #[allow(clippy::needless_pass_by_value)]
9850 #[inline]
9851 pub fn mul_add_mul_rational_round_val_ref_val_ref(
9852 self,
9853 y: &Self,
9854 z: Self,
9855 w: &Rational,
9856 rm: RoundingMode,
9857 ) -> (Self, Ordering) {
9858 let prec = max!(
9859 self.significant_bits(),
9860 y.significant_bits(),
9861 z.significant_bits()
9862 );
9863 self.mul_add_mul_rational_prec_round_val_ref_val_ref(y, z, w, prec, rm)
9864 }
9865
9866 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
9867 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9868 /// exactly and the products are not rounded before the final addition, so there is a single
9869 /// rounding. The second and third [`Float`]s are taken by reference and the other operands by
9870 /// value. An [`Ordering`] is also returned, indicating whether the rounded sum is less than,
9871 /// equal to, or greater than the exact sum. Although `NaN`s are not comparable to any
9872 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
9873 ///
9874 /// The precision of the output is the maximum of the precisions of the inputs. See
9875 /// [`RoundingMode`] for a description of the possible rounding modes.
9876 ///
9877 /// $$
9878 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
9879 /// $$
9880 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9881 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
9882 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
9883 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
9884 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
9885 ///
9886 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9887 ///
9888 /// Special cases:
9889 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9890 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9891 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9892 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9893 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
9894 /// [`Rational`] counts as an unsigned zero and a positive sign.
9895 /// - If exactly one product is infinite, the result is that product's infinity.
9896 /// - If both products are infinite, the result is their common infinity if their signs agree,
9897 /// and `NaN` otherwise.
9898 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
9899 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
9900 /// `Floor`
9901 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
9902 ///
9903 /// Overflow and underflow:
9904 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
9905 /// returned instead.
9906 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
9907 /// is returned instead, where `p` is the precision of the output.
9908 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
9909 /// returned instead.
9910 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
9911 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
9912 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
9913 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
9914 /// instead.
9915 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
9916 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
9917 /// returned instead.
9918 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
9919 /// instead.
9920 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
9921 /// instead.
9922 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
9923 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
9924 /// returned instead.
9925 ///
9926 /// If you want to specify an output precision, consider using
9927 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know you'll be using the
9928 /// `Nearest` rounding mode, consider using
9929 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
9930 ///
9931 /// # Worst-case complexity
9932 /// $T(n, m) = O(n \log n \log\log n + m)$
9933 ///
9934 /// $M(n, m) = O(n \log n + m)$
9935 ///
9936 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9937 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9938 /// `self.significant_bits()`.
9939 ///
9940 /// # Panics
9941 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
9942 /// represent the output.
9943 ///
9944 /// # Examples
9945 /// ```
9946 /// use core::f64::consts::{E, PI, SQRT_2};
9947 /// use malachite_base::rounding_modes::RoundingMode::*;
9948 /// use malachite_float::Float;
9949 /// use malachite_q::Rational;
9950 /// use std::cmp::Ordering::*;
9951 ///
9952 /// let x = Float::from(PI);
9953 /// let y = Float::from(E);
9954 /// let z = Float::from(SQRT_2);
9955 /// let w = Rational::from_signeds(1, 3);
9956 ///
9957 /// let (sum, o) =
9958 /// x.clone()
9959 /// .mul_add_mul_rational_round_val_ref_ref_val(&y, &z, w.clone(), Floor);
9960 /// assert_eq!(sum.to_string(), "9.0111387434645973");
9961 /// assert_eq!(o, Less);
9962 ///
9963 /// let (sum, o) =
9964 /// x.clone()
9965 /// .mul_add_mul_rational_round_val_ref_ref_val(&y, &z, w.clone(), Ceiling);
9966 /// assert_eq!(sum.to_string(), "9.0111387434645991");
9967 /// assert_eq!(o, Greater);
9968 ///
9969 /// let (sum, o) =
9970 /// x.clone()
9971 /// .mul_add_mul_rational_round_val_ref_ref_val(&y, &z, w.clone(), Nearest);
9972 /// assert_eq!(sum.to_string(), "9.0111387434645973");
9973 /// assert_eq!(o, Less);
9974 /// ```
9975 #[allow(clippy::needless_pass_by_value)]
9976 #[inline]
9977 pub fn mul_add_mul_rational_round_val_ref_ref_val(
9978 self,
9979 y: &Self,
9980 z: &Self,
9981 w: Rational,
9982 rm: RoundingMode,
9983 ) -> (Self, Ordering) {
9984 let prec = max!(
9985 self.significant_bits(),
9986 y.significant_bits(),
9987 z.significant_bits()
9988 );
9989 self.mul_add_mul_rational_prec_round_val_ref_ref_val(y, z, w, prec, rm)
9990 }
9991
9992 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
9993 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9994 /// exactly and the products are not rounded before the final addition, so there is a single
9995 /// rounding. The first [`Float`] is taken by value and the other operands by reference. An
9996 /// [`Ordering`] is also returned, indicating whether the rounded sum is less than, equal to, or
9997 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
9998 /// this function returns a `NaN` it also returns `Equal`.
9999 ///
10000 /// The precision of the output is the maximum of the precisions of the inputs. See
10001 /// [`RoundingMode`] for a description of the possible rounding modes.
10002 ///
10003 /// $$
10004 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
10005 /// $$
10006 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10007 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10008 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10009 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10010 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10011 ///
10012 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
10013 ///
10014 /// Special cases:
10015 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
10016 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
10017 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
10018 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
10019 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
10020 /// [`Rational`] counts as an unsigned zero and a positive sign.
10021 /// - If exactly one product is infinite, the result is that product's infinity.
10022 /// - If both products are infinite, the result is their common infinity if their signs agree,
10023 /// and `NaN` otherwise.
10024 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
10025 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
10026 /// `Floor`
10027 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
10028 ///
10029 /// Overflow and underflow:
10030 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
10031 /// returned instead.
10032 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
10033 /// is returned instead, where `p` is the precision of the output.
10034 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
10035 /// returned instead.
10036 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
10037 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
10038 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
10039 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
10040 /// instead.
10041 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
10042 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
10043 /// returned instead.
10044 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
10045 /// instead.
10046 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
10047 /// instead.
10048 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
10049 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
10050 /// returned instead.
10051 ///
10052 /// If you want to specify an output precision, consider using
10053 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know you'll be using the
10054 /// `Nearest` rounding mode, consider using
10055 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
10056 ///
10057 /// # Worst-case complexity
10058 /// $T(n, m) = O(n \log n \log\log n + m)$
10059 ///
10060 /// $M(n, m) = O(n \log n + m)$
10061 ///
10062 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10063 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10064 /// `self.significant_bits()`.
10065 ///
10066 /// # Panics
10067 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10068 /// represent the output.
10069 ///
10070 /// # Examples
10071 /// ```
10072 /// use core::f64::consts::{E, PI, SQRT_2};
10073 /// use malachite_base::rounding_modes::RoundingMode::*;
10074 /// use malachite_float::Float;
10075 /// use malachite_q::Rational;
10076 /// use std::cmp::Ordering::*;
10077 ///
10078 /// let x = Float::from(PI);
10079 /// let y = Float::from(E);
10080 /// let z = Float::from(SQRT_2);
10081 /// let w = Rational::from_signeds(1, 3);
10082 ///
10083 /// let (sum, o) = x
10084 /// .clone()
10085 /// .mul_add_mul_rational_round_val_ref_ref_ref(&y, &z, &w, Floor);
10086 /// assert_eq!(sum.to_string(), "9.0111387434645973");
10087 /// assert_eq!(o, Less);
10088 ///
10089 /// let (sum, o) = x
10090 /// .clone()
10091 /// .mul_add_mul_rational_round_val_ref_ref_ref(&y, &z, &w, Ceiling);
10092 /// assert_eq!(sum.to_string(), "9.0111387434645991");
10093 /// assert_eq!(o, Greater);
10094 ///
10095 /// let (sum, o) = x
10096 /// .clone()
10097 /// .mul_add_mul_rational_round_val_ref_ref_ref(&y, &z, &w, Nearest);
10098 /// assert_eq!(sum.to_string(), "9.0111387434645973");
10099 /// assert_eq!(o, Less);
10100 /// ```
10101 #[allow(clippy::needless_pass_by_value)]
10102 #[inline]
10103 pub fn mul_add_mul_rational_round_val_ref_ref_ref(
10104 self,
10105 y: &Self,
10106 z: &Self,
10107 w: &Rational,
10108 rm: RoundingMode,
10109 ) -> (Self, Ordering) {
10110 let prec = max!(
10111 self.significant_bits(),
10112 y.significant_bits(),
10113 z.significant_bits()
10114 );
10115 self.mul_add_mul_rational_prec_round_val_ref_ref_ref(y, z, w, prec, rm)
10116 }
10117
10118 /// Adds the product of two [`Float`]s and the product of a [`Float`] and a [`Rational`],
10119 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
10120 /// exactly and the products are not rounded before the final addition, so there is a single
10121 /// rounding. The [`Float`]s and the [`Rational`] are all taken by reference. An [`Ordering`] is
10122 /// also returned, indicating whether the rounded sum is less than, equal to, or greater than
10123 /// the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
10124 /// returns a `NaN` it also returns `Equal`.
10125 ///
10126 /// The precision of the output is the maximum of the precisions of the inputs. See
10127 /// [`RoundingMode`] for a description of the possible rounding modes.
10128 ///
10129 /// $$
10130 /// f(x,y,z,w,m) = xy+zw+\varepsilon.
10131 /// $$
10132 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10133 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10134 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10135 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10136 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10137 ///
10138 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
10139 ///
10140 /// Special cases:
10141 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
10142 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
10143 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
10144 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
10145 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
10146 /// [`Rational`] counts as an unsigned zero and a positive sign.
10147 /// - If exactly one product is infinite, the result is that product's infinity.
10148 /// - If both products are infinite, the result is their common infinity if their signs agree,
10149 /// and `NaN` otherwise.
10150 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
10151 /// - $f(x,y,z,w,m)=0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is not
10152 /// `Floor`
10153 /// - $f(x,y,z,w,m)=-0.0$ if $xy=-zw$, the products are finite and nonzero, and $m$ is `Floor`
10154 ///
10155 /// Overflow and underflow:
10156 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
10157 /// returned instead.
10158 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
10159 /// is returned instead, where `p` is the precision of the output.
10160 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
10161 /// returned instead.
10162 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
10163 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
10164 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
10165 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
10166 /// instead.
10167 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
10168 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
10169 /// returned instead.
10170 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
10171 /// instead.
10172 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
10173 /// instead.
10174 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
10175 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
10176 /// returned instead.
10177 ///
10178 /// If you want to specify an output precision, consider using
10179 /// [`Float::mul_add_mul_rational_prec_round`] instead. If you know you'll be using the
10180 /// `Nearest` rounding mode, consider using
10181 /// [`mul_add_mul`](malachite_base::num::arithmetic::traits::MulAddMul::mul_add_mul) instead.
10182 ///
10183 /// # Worst-case complexity
10184 /// $T(n, m) = O(n \log n \log\log n + m)$
10185 ///
10186 /// $M(n, m) = O(n \log n + m)$
10187 ///
10188 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10189 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10190 /// `self.significant_bits()`.
10191 ///
10192 /// # Panics
10193 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10194 /// represent the output.
10195 ///
10196 /// # Examples
10197 /// ```
10198 /// use core::f64::consts::{E, PI, SQRT_2};
10199 /// use malachite_base::rounding_modes::RoundingMode::*;
10200 /// use malachite_float::Float;
10201 /// use malachite_q::Rational;
10202 /// use std::cmp::Ordering::*;
10203 ///
10204 /// let x = Float::from(PI);
10205 /// let y = Float::from(E);
10206 /// let z = Float::from(SQRT_2);
10207 /// let w = Rational::from_signeds(1, 3);
10208 ///
10209 /// let (sum, o) = x.mul_add_mul_rational_round_ref_ref_ref_ref(&y, &z, &w, Floor);
10210 /// assert_eq!(sum.to_string(), "9.0111387434645973");
10211 /// assert_eq!(o, Less);
10212 ///
10213 /// let (sum, o) = x.mul_add_mul_rational_round_ref_ref_ref_ref(&y, &z, &w, Ceiling);
10214 /// assert_eq!(sum.to_string(), "9.0111387434645991");
10215 /// assert_eq!(o, Greater);
10216 ///
10217 /// let (sum, o) = x.mul_add_mul_rational_round_ref_ref_ref_ref(&y, &z, &w, Nearest);
10218 /// assert_eq!(sum.to_string(), "9.0111387434645973");
10219 /// assert_eq!(o, Less);
10220 /// ```
10221 #[allow(clippy::needless_pass_by_value)]
10222 #[inline]
10223 pub fn mul_add_mul_rational_round_ref_ref_ref_ref(
10224 &self,
10225 y: &Self,
10226 z: &Self,
10227 w: &Rational,
10228 rm: RoundingMode,
10229 ) -> (Self, Ordering) {
10230 let prec = max!(
10231 self.significant_bits(),
10232 y.significant_bits(),
10233 z.significant_bits()
10234 );
10235 self.mul_add_mul_rational_prec_round_ref_ref_ref_ref(y, z, w, prec, rm)
10236 }
10237
10238 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
10239 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10240 /// The [`Float`]s on the right-hand side are all taken by value. An [`Ordering`] is returned,
10241 /// indicating whether the rounded sum is less than, equal to, or greater than the exact sum.
10242 /// Although `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN`
10243 /// it also returns `Equal`.
10244 ///
10245 /// The precision of the output is the maximum of the precisions of the inputs. See
10246 /// [`RoundingMode`] for a description of the possible rounding modes.
10247 ///
10248 /// $$
10249 /// x \gets xy+zw+\varepsilon.
10250 /// $$
10251 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10252 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10253 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10254 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10255 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10256 ///
10257 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
10258 /// overflow, and underflow.
10259 ///
10260 /// If you want to specify an output precision, consider using
10261 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10262 /// `Nearest` rounding mode, consider using
10263 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
10264 ///
10265 /// # Worst-case complexity
10266 /// $T(n, m) = O(n \log n \log\log n + m)$
10267 ///
10268 /// $M(n, m) = O(n \log n + m)$
10269 ///
10270 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10271 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10272 /// `self.significant_bits()`.
10273 ///
10274 /// # Panics
10275 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10276 /// represent the output.
10277 ///
10278 /// # Examples
10279 /// ```
10280 /// use core::f64::consts::{E, PI, SQRT_2};
10281 /// use malachite_base::rounding_modes::RoundingMode::*;
10282 /// use malachite_float::Float;
10283 /// use malachite_q::Rational;
10284 /// use std::cmp::Ordering::*;
10285 ///
10286 /// let y = Float::from(E);
10287 /// let z = Float::from(SQRT_2);
10288 /// let w = Rational::from_signeds(1, 3);
10289 ///
10290 /// let mut x = Float::from(PI);
10291 /// assert_eq!(
10292 /// x.mul_add_mul_rational_round_assign(y.clone(), z.clone(), w.clone(), Floor),
10293 /// Less
10294 /// );
10295 /// assert_eq!(x.to_string(), "9.0111387434645973");
10296 ///
10297 /// let mut x = Float::from(PI);
10298 /// assert_eq!(
10299 /// x.mul_add_mul_rational_round_assign(y.clone(), z.clone(), w.clone(), Ceiling),
10300 /// Greater
10301 /// );
10302 /// assert_eq!(x.to_string(), "9.0111387434645991");
10303 ///
10304 /// let mut x = Float::from(PI);
10305 /// assert_eq!(
10306 /// x.mul_add_mul_rational_round_assign(y.clone(), z.clone(), w.clone(), Nearest),
10307 /// Less
10308 /// );
10309 /// assert_eq!(x.to_string(), "9.0111387434645973");
10310 /// ```
10311 #[allow(clippy::needless_pass_by_value)]
10312 #[inline]
10313 pub fn mul_add_mul_rational_round_assign(
10314 &mut self,
10315 y: Self,
10316 z: Self,
10317 w: Rational,
10318 rm: RoundingMode,
10319 ) -> Ordering {
10320 let prec = max!(
10321 self.significant_bits(),
10322 y.significant_bits(),
10323 z.significant_bits()
10324 );
10325 self.mul_add_mul_rational_prec_round_assign(y, z, w, prec, rm)
10326 }
10327
10328 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
10329 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10330 /// The last [`Float`] on the right-hand side is taken by reference and the others by value. An
10331 /// [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
10332 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
10333 /// this function assigns a `NaN` it also returns `Equal`.
10334 ///
10335 /// The precision of the output is the maximum of the precisions of the inputs. See
10336 /// [`RoundingMode`] for a description of the possible rounding modes.
10337 ///
10338 /// $$
10339 /// x \gets xy+zw+\varepsilon.
10340 /// $$
10341 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10342 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10343 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10344 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10345 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10346 ///
10347 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
10348 /// overflow, and underflow.
10349 ///
10350 /// If you want to specify an output precision, consider using
10351 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10352 /// `Nearest` rounding mode, consider using
10353 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
10354 ///
10355 /// # Worst-case complexity
10356 /// $T(n, m) = O(n \log n \log\log n + m)$
10357 ///
10358 /// $M(n, m) = O(n \log n + m)$
10359 ///
10360 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10361 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10362 /// `self.significant_bits()`.
10363 ///
10364 /// # Panics
10365 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10366 /// represent the output.
10367 ///
10368 /// # Examples
10369 /// ```
10370 /// use core::f64::consts::{E, PI, SQRT_2};
10371 /// use malachite_base::rounding_modes::RoundingMode::*;
10372 /// use malachite_float::Float;
10373 /// use malachite_q::Rational;
10374 /// use std::cmp::Ordering::*;
10375 ///
10376 /// let y = Float::from(E);
10377 /// let z = Float::from(SQRT_2);
10378 /// let w = Rational::from_signeds(1, 3);
10379 ///
10380 /// let mut x = Float::from(PI);
10381 /// assert_eq!(
10382 /// x.mul_add_mul_rational_round_assign_val_val_ref(y.clone(), z.clone(), &w, Floor),
10383 /// Less
10384 /// );
10385 /// assert_eq!(x.to_string(), "9.0111387434645973");
10386 ///
10387 /// let mut x = Float::from(PI);
10388 /// assert_eq!(
10389 /// x.mul_add_mul_rational_round_assign_val_val_ref(y.clone(), z.clone(), &w, Ceiling),
10390 /// Greater
10391 /// );
10392 /// assert_eq!(x.to_string(), "9.0111387434645991");
10393 ///
10394 /// let mut x = Float::from(PI);
10395 /// assert_eq!(
10396 /// x.mul_add_mul_rational_round_assign_val_val_ref(y.clone(), z.clone(), &w, Nearest),
10397 /// Less
10398 /// );
10399 /// assert_eq!(x.to_string(), "9.0111387434645973");
10400 /// ```
10401 #[allow(clippy::needless_pass_by_value)]
10402 #[inline]
10403 pub fn mul_add_mul_rational_round_assign_val_val_ref(
10404 &mut self,
10405 y: Self,
10406 z: Self,
10407 w: &Rational,
10408 rm: RoundingMode,
10409 ) -> Ordering {
10410 let prec = max!(
10411 self.significant_bits(),
10412 y.significant_bits(),
10413 z.significant_bits()
10414 );
10415 self.mul_add_mul_rational_prec_round_assign_val_val_ref(y, z, w, prec, rm)
10416 }
10417
10418 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
10419 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10420 /// The middle [`Float`] on the right-hand side is taken by reference and the others by value.
10421 /// An [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
10422 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
10423 /// this function assigns a `NaN` it also returns `Equal`.
10424 ///
10425 /// The precision of the output is the maximum of the precisions of the inputs. See
10426 /// [`RoundingMode`] for a description of the possible rounding modes.
10427 ///
10428 /// $$
10429 /// x \gets xy+zw+\varepsilon.
10430 /// $$
10431 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10432 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10433 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10434 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10435 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10436 ///
10437 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
10438 /// overflow, and underflow.
10439 ///
10440 /// If you want to specify an output precision, consider using
10441 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10442 /// `Nearest` rounding mode, consider using
10443 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
10444 ///
10445 /// # Worst-case complexity
10446 /// $T(n, m) = O(n \log n \log\log n + m)$
10447 ///
10448 /// $M(n, m) = O(n \log n + m)$
10449 ///
10450 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10451 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10452 /// `self.significant_bits()`.
10453 ///
10454 /// # Panics
10455 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10456 /// represent the output.
10457 ///
10458 /// # Examples
10459 /// ```
10460 /// use core::f64::consts::{E, PI, SQRT_2};
10461 /// use malachite_base::rounding_modes::RoundingMode::*;
10462 /// use malachite_float::Float;
10463 /// use malachite_q::Rational;
10464 /// use std::cmp::Ordering::*;
10465 ///
10466 /// let y = Float::from(E);
10467 /// let z = Float::from(SQRT_2);
10468 /// let w = Rational::from_signeds(1, 3);
10469 ///
10470 /// let mut x = Float::from(PI);
10471 /// assert_eq!(
10472 /// x.mul_add_mul_rational_round_assign_val_ref_val(y.clone(), &z, w.clone(), Floor),
10473 /// Less
10474 /// );
10475 /// assert_eq!(x.to_string(), "9.0111387434645973");
10476 ///
10477 /// let mut x = Float::from(PI);
10478 /// assert_eq!(
10479 /// x.mul_add_mul_rational_round_assign_val_ref_val(y.clone(), &z, w.clone(), Ceiling),
10480 /// Greater
10481 /// );
10482 /// assert_eq!(x.to_string(), "9.0111387434645991");
10483 ///
10484 /// let mut x = Float::from(PI);
10485 /// assert_eq!(
10486 /// x.mul_add_mul_rational_round_assign_val_ref_val(y.clone(), &z, w.clone(), Nearest),
10487 /// Less
10488 /// );
10489 /// assert_eq!(x.to_string(), "9.0111387434645973");
10490 /// ```
10491 #[allow(clippy::needless_pass_by_value)]
10492 #[inline]
10493 pub fn mul_add_mul_rational_round_assign_val_ref_val(
10494 &mut self,
10495 y: Self,
10496 z: &Self,
10497 w: Rational,
10498 rm: RoundingMode,
10499 ) -> Ordering {
10500 let prec = max!(
10501 self.significant_bits(),
10502 y.significant_bits(),
10503 z.significant_bits()
10504 );
10505 self.mul_add_mul_rational_prec_round_assign_val_ref_val(y, z, w, prec, rm)
10506 }
10507
10508 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
10509 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10510 /// The first [`Float`] on the right-hand side is taken by value and the others by reference. An
10511 /// [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
10512 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
10513 /// this function assigns a `NaN` it also returns `Equal`.
10514 ///
10515 /// The precision of the output is the maximum of the precisions of the inputs. See
10516 /// [`RoundingMode`] for a description of the possible rounding modes.
10517 ///
10518 /// $$
10519 /// x \gets xy+zw+\varepsilon.
10520 /// $$
10521 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10522 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10523 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10524 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10525 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10526 ///
10527 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
10528 /// overflow, and underflow.
10529 ///
10530 /// If you want to specify an output precision, consider using
10531 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10532 /// `Nearest` rounding mode, consider using
10533 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
10534 ///
10535 /// # Worst-case complexity
10536 /// $T(n, m) = O(n \log n \log\log n + m)$
10537 ///
10538 /// $M(n, m) = O(n \log n + m)$
10539 ///
10540 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10541 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10542 /// `self.significant_bits()`.
10543 ///
10544 /// # Panics
10545 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10546 /// represent the output.
10547 ///
10548 /// # Examples
10549 /// ```
10550 /// use core::f64::consts::{E, PI, SQRT_2};
10551 /// use malachite_base::rounding_modes::RoundingMode::*;
10552 /// use malachite_float::Float;
10553 /// use malachite_q::Rational;
10554 /// use std::cmp::Ordering::*;
10555 ///
10556 /// let y = Float::from(E);
10557 /// let z = Float::from(SQRT_2);
10558 /// let w = Rational::from_signeds(1, 3);
10559 ///
10560 /// let mut x = Float::from(PI);
10561 /// assert_eq!(
10562 /// x.mul_add_mul_rational_round_assign_val_ref_ref(y.clone(), &z, &w, Floor),
10563 /// Less
10564 /// );
10565 /// assert_eq!(x.to_string(), "9.0111387434645973");
10566 ///
10567 /// let mut x = Float::from(PI);
10568 /// assert_eq!(
10569 /// x.mul_add_mul_rational_round_assign_val_ref_ref(y.clone(), &z, &w, Ceiling),
10570 /// Greater
10571 /// );
10572 /// assert_eq!(x.to_string(), "9.0111387434645991");
10573 ///
10574 /// let mut x = Float::from(PI);
10575 /// assert_eq!(
10576 /// x.mul_add_mul_rational_round_assign_val_ref_ref(y.clone(), &z, &w, Nearest),
10577 /// Less
10578 /// );
10579 /// assert_eq!(x.to_string(), "9.0111387434645973");
10580 /// ```
10581 #[allow(clippy::needless_pass_by_value)]
10582 #[inline]
10583 pub fn mul_add_mul_rational_round_assign_val_ref_ref(
10584 &mut self,
10585 y: Self,
10586 z: &Self,
10587 w: &Rational,
10588 rm: RoundingMode,
10589 ) -> Ordering {
10590 let prec = max!(
10591 self.significant_bits(),
10592 y.significant_bits(),
10593 z.significant_bits()
10594 );
10595 self.mul_add_mul_rational_prec_round_assign_val_ref_ref(y, z, w, prec, rm)
10596 }
10597
10598 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
10599 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10600 /// The first [`Float`] on the right-hand side is taken by reference and the others by value. An
10601 /// [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
10602 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
10603 /// this function assigns a `NaN` it also returns `Equal`.
10604 ///
10605 /// The precision of the output is the maximum of the precisions of the inputs. See
10606 /// [`RoundingMode`] for a description of the possible rounding modes.
10607 ///
10608 /// $$
10609 /// x \gets xy+zw+\varepsilon.
10610 /// $$
10611 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10612 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10613 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10614 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10615 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10616 ///
10617 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
10618 /// overflow, and underflow.
10619 ///
10620 /// If you want to specify an output precision, consider using
10621 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10622 /// `Nearest` rounding mode, consider using
10623 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
10624 ///
10625 /// # Worst-case complexity
10626 /// $T(n, m) = O(n \log n \log\log n + m)$
10627 ///
10628 /// $M(n, m) = O(n \log n + m)$
10629 ///
10630 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10631 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10632 /// `self.significant_bits()`.
10633 ///
10634 /// # Panics
10635 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10636 /// represent the output.
10637 ///
10638 /// # Examples
10639 /// ```
10640 /// use core::f64::consts::{E, PI, SQRT_2};
10641 /// use malachite_base::rounding_modes::RoundingMode::*;
10642 /// use malachite_float::Float;
10643 /// use malachite_q::Rational;
10644 /// use std::cmp::Ordering::*;
10645 ///
10646 /// let y = Float::from(E);
10647 /// let z = Float::from(SQRT_2);
10648 /// let w = Rational::from_signeds(1, 3);
10649 ///
10650 /// let mut x = Float::from(PI);
10651 /// assert_eq!(
10652 /// x.mul_add_mul_rational_round_assign_ref_val_val(&y, z.clone(), w.clone(), Floor),
10653 /// Less
10654 /// );
10655 /// assert_eq!(x.to_string(), "9.0111387434645973");
10656 ///
10657 /// let mut x = Float::from(PI);
10658 /// assert_eq!(
10659 /// x.mul_add_mul_rational_round_assign_ref_val_val(&y, z.clone(), w.clone(), Ceiling),
10660 /// Greater
10661 /// );
10662 /// assert_eq!(x.to_string(), "9.0111387434645991");
10663 ///
10664 /// let mut x = Float::from(PI);
10665 /// assert_eq!(
10666 /// x.mul_add_mul_rational_round_assign_ref_val_val(&y, z.clone(), w.clone(), Nearest),
10667 /// Less
10668 /// );
10669 /// assert_eq!(x.to_string(), "9.0111387434645973");
10670 /// ```
10671 #[allow(clippy::needless_pass_by_value)]
10672 #[inline]
10673 pub fn mul_add_mul_rational_round_assign_ref_val_val(
10674 &mut self,
10675 y: &Self,
10676 z: Self,
10677 w: Rational,
10678 rm: RoundingMode,
10679 ) -> Ordering {
10680 let prec = max!(
10681 self.significant_bits(),
10682 y.significant_bits(),
10683 z.significant_bits()
10684 );
10685 self.mul_add_mul_rational_prec_round_assign_ref_val_val(y, z, w, prec, rm)
10686 }
10687
10688 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
10689 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10690 /// The middle [`Float`] on the right-hand side is taken by value and the others by reference.
10691 /// An [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
10692 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
10693 /// this function assigns a `NaN` it also returns `Equal`.
10694 ///
10695 /// The precision of the output is the maximum of the precisions of the inputs. See
10696 /// [`RoundingMode`] for a description of the possible rounding modes.
10697 ///
10698 /// $$
10699 /// x \gets xy+zw+\varepsilon.
10700 /// $$
10701 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10702 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10703 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10704 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10705 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10706 ///
10707 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
10708 /// overflow, and underflow.
10709 ///
10710 /// If you want to specify an output precision, consider using
10711 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10712 /// `Nearest` rounding mode, consider using
10713 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
10714 ///
10715 /// # Worst-case complexity
10716 /// $T(n, m) = O(n \log n \log\log n + m)$
10717 ///
10718 /// $M(n, m) = O(n \log n + m)$
10719 ///
10720 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10721 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10722 /// `self.significant_bits()`.
10723 ///
10724 /// # Panics
10725 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10726 /// represent the output.
10727 ///
10728 /// # Examples
10729 /// ```
10730 /// use core::f64::consts::{E, PI, SQRT_2};
10731 /// use malachite_base::rounding_modes::RoundingMode::*;
10732 /// use malachite_float::Float;
10733 /// use malachite_q::Rational;
10734 /// use std::cmp::Ordering::*;
10735 ///
10736 /// let y = Float::from(E);
10737 /// let z = Float::from(SQRT_2);
10738 /// let w = Rational::from_signeds(1, 3);
10739 ///
10740 /// let mut x = Float::from(PI);
10741 /// assert_eq!(
10742 /// x.mul_add_mul_rational_round_assign_ref_val_ref(&y, z.clone(), &w, Floor),
10743 /// Less
10744 /// );
10745 /// assert_eq!(x.to_string(), "9.0111387434645973");
10746 ///
10747 /// let mut x = Float::from(PI);
10748 /// assert_eq!(
10749 /// x.mul_add_mul_rational_round_assign_ref_val_ref(&y, z.clone(), &w, Ceiling),
10750 /// Greater
10751 /// );
10752 /// assert_eq!(x.to_string(), "9.0111387434645991");
10753 ///
10754 /// let mut x = Float::from(PI);
10755 /// assert_eq!(
10756 /// x.mul_add_mul_rational_round_assign_ref_val_ref(&y, z.clone(), &w, Nearest),
10757 /// Less
10758 /// );
10759 /// assert_eq!(x.to_string(), "9.0111387434645973");
10760 /// ```
10761 #[allow(clippy::needless_pass_by_value)]
10762 #[inline]
10763 pub fn mul_add_mul_rational_round_assign_ref_val_ref(
10764 &mut self,
10765 y: &Self,
10766 z: Self,
10767 w: &Rational,
10768 rm: RoundingMode,
10769 ) -> Ordering {
10770 let prec = max!(
10771 self.significant_bits(),
10772 y.significant_bits(),
10773 z.significant_bits()
10774 );
10775 self.mul_add_mul_rational_prec_round_assign_ref_val_ref(y, z, w, prec, rm)
10776 }
10777
10778 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
10779 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10780 /// The last [`Float`] on the right-hand side is taken by value and the others by reference. An
10781 /// [`Ordering`] is returned, indicating whether the rounded sum is less than, equal to, or
10782 /// greater than the exact sum. Although `NaN`s are not comparable to any [`Float`], whenever
10783 /// this function assigns a `NaN` it also returns `Equal`.
10784 ///
10785 /// The precision of the output is the maximum of the precisions of the inputs. See
10786 /// [`RoundingMode`] for a description of the possible rounding modes.
10787 ///
10788 /// $$
10789 /// x \gets xy+zw+\varepsilon.
10790 /// $$
10791 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10792 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10793 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10794 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10795 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10796 ///
10797 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
10798 /// overflow, and underflow.
10799 ///
10800 /// If you want to specify an output precision, consider using
10801 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10802 /// `Nearest` rounding mode, consider using
10803 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
10804 ///
10805 /// # Worst-case complexity
10806 /// $T(n, m) = O(n \log n \log\log n + m)$
10807 ///
10808 /// $M(n, m) = O(n \log n + m)$
10809 ///
10810 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10811 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10812 /// `self.significant_bits()`.
10813 ///
10814 /// # Panics
10815 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10816 /// represent the output.
10817 ///
10818 /// # Examples
10819 /// ```
10820 /// use core::f64::consts::{E, PI, SQRT_2};
10821 /// use malachite_base::rounding_modes::RoundingMode::*;
10822 /// use malachite_float::Float;
10823 /// use malachite_q::Rational;
10824 /// use std::cmp::Ordering::*;
10825 ///
10826 /// let y = Float::from(E);
10827 /// let z = Float::from(SQRT_2);
10828 /// let w = Rational::from_signeds(1, 3);
10829 ///
10830 /// let mut x = Float::from(PI);
10831 /// assert_eq!(
10832 /// x.mul_add_mul_rational_round_assign_ref_ref_val(&y, &z, w.clone(), Floor),
10833 /// Less
10834 /// );
10835 /// assert_eq!(x.to_string(), "9.0111387434645973");
10836 ///
10837 /// let mut x = Float::from(PI);
10838 /// assert_eq!(
10839 /// x.mul_add_mul_rational_round_assign_ref_ref_val(&y, &z, w.clone(), Ceiling),
10840 /// Greater
10841 /// );
10842 /// assert_eq!(x.to_string(), "9.0111387434645991");
10843 ///
10844 /// let mut x = Float::from(PI);
10845 /// assert_eq!(
10846 /// x.mul_add_mul_rational_round_assign_ref_ref_val(&y, &z, w.clone(), Nearest),
10847 /// Less
10848 /// );
10849 /// assert_eq!(x.to_string(), "9.0111387434645973");
10850 /// ```
10851 #[allow(clippy::needless_pass_by_value)]
10852 #[inline]
10853 pub fn mul_add_mul_rational_round_assign_ref_ref_val(
10854 &mut self,
10855 y: &Self,
10856 z: &Self,
10857 w: Rational,
10858 rm: RoundingMode,
10859 ) -> Ordering {
10860 let prec = max!(
10861 self.significant_bits(),
10862 y.significant_bits(),
10863 z.significant_bits()
10864 );
10865 self.mul_add_mul_rational_prec_round_assign_ref_ref_val(y, z, w, prec, rm)
10866 }
10867
10868 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
10869 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10870 /// The [`Float`]s on the right-hand side are all taken by reference. An [`Ordering`] is
10871 /// returned, indicating whether the rounded sum is less than, equal to, or greater than the
10872 /// exact sum. Although `NaN`s are not comparable to any [`Float`], whenever this function
10873 /// assigns a `NaN` it also returns `Equal`.
10874 ///
10875 /// The precision of the output is the maximum of the precisions of the inputs. See
10876 /// [`RoundingMode`] for a description of the possible rounding modes.
10877 ///
10878 /// $$
10879 /// x \gets xy+zw+\varepsilon.
10880 /// $$
10881 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10882 /// - If $xy+zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10883 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10884 /// - If $xy+zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10885 /// 2^{\lfloor\log_2 |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10886 ///
10887 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
10888 /// overflow, and underflow.
10889 ///
10890 /// If you want to specify an output precision, consider using
10891 /// [`Float::mul_add_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10892 /// `Nearest` rounding mode, consider using
10893 /// [`mul_add_mul_assign`](malachite_base::num::arithmetic::traits::MulAddMulAssign) instead.
10894 ///
10895 /// # Worst-case complexity
10896 /// $T(n, m) = O(n \log n \log\log n + m)$
10897 ///
10898 /// $M(n, m) = O(n \log n + m)$
10899 ///
10900 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10901 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10902 /// `self.significant_bits()`.
10903 ///
10904 /// # Panics
10905 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10906 /// represent the output.
10907 ///
10908 /// # Examples
10909 /// ```
10910 /// use core::f64::consts::{E, PI, SQRT_2};
10911 /// use malachite_base::rounding_modes::RoundingMode::*;
10912 /// use malachite_float::Float;
10913 /// use malachite_q::Rational;
10914 /// use std::cmp::Ordering::*;
10915 ///
10916 /// let y = Float::from(E);
10917 /// let z = Float::from(SQRT_2);
10918 /// let w = Rational::from_signeds(1, 3);
10919 ///
10920 /// let mut x = Float::from(PI);
10921 /// assert_eq!(
10922 /// x.mul_add_mul_rational_round_assign_ref_ref_ref(&y, &z, &w, Floor),
10923 /// Less
10924 /// );
10925 /// assert_eq!(x.to_string(), "9.0111387434645973");
10926 ///
10927 /// let mut x = Float::from(PI);
10928 /// assert_eq!(
10929 /// x.mul_add_mul_rational_round_assign_ref_ref_ref(&y, &z, &w, Ceiling),
10930 /// Greater
10931 /// );
10932 /// assert_eq!(x.to_string(), "9.0111387434645991");
10933 ///
10934 /// let mut x = Float::from(PI);
10935 /// assert_eq!(
10936 /// x.mul_add_mul_rational_round_assign_ref_ref_ref(&y, &z, &w, Nearest),
10937 /// Less
10938 /// );
10939 /// assert_eq!(x.to_string(), "9.0111387434645973");
10940 /// ```
10941 #[allow(clippy::needless_pass_by_value)]
10942 #[inline]
10943 pub fn mul_add_mul_rational_round_assign_ref_ref_ref(
10944 &mut self,
10945 y: &Self,
10946 z: &Self,
10947 w: &Rational,
10948 rm: RoundingMode,
10949 ) -> Ordering {
10950 let prec = max!(
10951 self.significant_bits(),
10952 y.significant_bits(),
10953 z.significant_bits()
10954 );
10955 self.mul_add_mul_rational_prec_round_assign_ref_ref_ref(y, z, w, prec, rm)
10956 }
10957}
10958
10959impl MulAddMul<Self, Self, Rational> for Float {
10960 type Output = Self;
10961 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking all four by
10962 /// value.
10963 ///
10964 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
10965 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
10966 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
10967 /// the `Nearest` rounding mode.
10968 ///
10969 /// $$
10970 /// f(x,y,z,w) = xy+zw+\varepsilon.
10971 /// $$
10972 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10973 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
10974 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10975 ///
10976 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
10977 ///
10978 /// Special cases:
10979 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
10980 /// f(x,y,z,\text{NaN})=\text{NaN}$
10981 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
10982 /// f(x,y,z,\text{NaN})=\text{NaN}$
10983 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
10984 /// [`Rational`] counts as an unsigned zero and a positive sign.
10985 /// - If exactly one product is infinite, the result is that product's infinity.
10986 /// - If both products are infinite, the result is their common infinity if their signs agree,
10987 /// and `NaN` otherwise.
10988 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
10989 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
10990 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
10991 ///
10992 /// Overflow and underflow:
10993 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
10994 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
10995 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
10996 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
10997 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
10998 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
10999 ///
11000 /// If you want to use a rounding mode other than `Nearest`, consider using
11001 /// [`Float::mul_add_mul_rational_round`]. If you want to specify the output precision, consider
11002 /// using [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
11003 /// [`Float::mul_add_mul_prec_round`].
11004 ///
11005 /// # Worst-case complexity
11006 /// $T(n, m) = O(n \log n \log\log n + m)$
11007 ///
11008 /// $M(n, m) = O(n \log n + m)$
11009 ///
11010 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11011 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11012 /// `self.significant_bits()`.
11013 ///
11014 /// # Examples
11015 /// ```
11016 /// use core::f64::consts::{E, PI, SQRT_2};
11017 /// use malachite_base::num::arithmetic::traits::MulAddMul;
11018 /// use malachite_float::Float;
11019 /// use malachite_q::Rational;
11020 ///
11021 /// let x = Float::from(PI);
11022 /// let y = Float::from(E);
11023 /// let z = Float::from(SQRT_2);
11024 /// let w = Rational::from_signeds(1, 3);
11025 /// assert_eq!(x.mul_add_mul(y, z, w).to_string(), "9.0111387434645973");
11026 /// ```
11027 #[inline]
11028 fn mul_add_mul(self, y: Self, z: Self, w: Rational) -> Self {
11029 let prec = max!(
11030 self.significant_bits(),
11031 y.significant_bits(),
11032 z.significant_bits()
11033 );
11034 self.mul_add_mul_rational_prec(y, z, w, prec).0
11035 }
11036}
11037
11038impl MulAddMul<Self, Self, &Rational> for Float {
11039 type Output = Self;
11040 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking the first three
11041 /// by value and the fourth by reference.
11042 ///
11043 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11044 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11045 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11046 /// the `Nearest` rounding mode.
11047 ///
11048 /// $$
11049 /// f(x,y,z,w) = xy+zw+\varepsilon.
11050 /// $$
11051 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11052 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11053 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11054 ///
11055 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11056 ///
11057 /// Special cases:
11058 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11059 /// f(x,y,z,\text{NaN})=\text{NaN}$
11060 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11061 /// f(x,y,z,\text{NaN})=\text{NaN}$
11062 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
11063 /// [`Rational`] counts as an unsigned zero and a positive sign.
11064 /// - If exactly one product is infinite, the result is that product's infinity.
11065 /// - If both products are infinite, the result is their common infinity if their signs agree,
11066 /// and `NaN` otherwise.
11067 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
11068 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
11069 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
11070 ///
11071 /// Overflow and underflow:
11072 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
11073 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
11074 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
11075 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
11076 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
11077 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
11078 ///
11079 /// If you want to use a rounding mode other than `Nearest`, consider using
11080 /// [`Float::mul_add_mul_rational_round`]. If you want to specify the output precision, consider
11081 /// using [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
11082 /// [`Float::mul_add_mul_prec_round`].
11083 ///
11084 /// # Worst-case complexity
11085 /// $T(n, m) = O(n \log n \log\log n + m)$
11086 ///
11087 /// $M(n, m) = O(n \log n + m)$
11088 ///
11089 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11090 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11091 /// `self.significant_bits()`.
11092 ///
11093 /// # Examples
11094 /// ```
11095 /// use core::f64::consts::{E, PI, SQRT_2};
11096 /// use malachite_base::num::arithmetic::traits::MulAddMul;
11097 /// use malachite_float::Float;
11098 /// use malachite_q::Rational;
11099 ///
11100 /// let x = Float::from(PI);
11101 /// let y = Float::from(E);
11102 /// let z = Float::from(SQRT_2);
11103 /// let w = Rational::from_signeds(1, 3);
11104 /// assert_eq!(x.mul_add_mul(y, z, &w).to_string(), "9.0111387434645973");
11105 /// ```
11106 #[inline]
11107 fn mul_add_mul(self, y: Self, z: Self, w: &Rational) -> Self {
11108 let prec = max!(
11109 self.significant_bits(),
11110 y.significant_bits(),
11111 z.significant_bits()
11112 );
11113 self.mul_add_mul_rational_prec_val_val_val_ref(y, z, w, prec)
11114 .0
11115 }
11116}
11117
11118impl MulAddMul<Self, &Self, Rational> for Float {
11119 type Output = Self;
11120 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking the third by
11121 /// reference and the others by value.
11122 ///
11123 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11124 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11125 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11126 /// the `Nearest` rounding mode.
11127 ///
11128 /// $$
11129 /// f(x,y,z,w) = xy+zw+\varepsilon.
11130 /// $$
11131 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11132 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11133 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11134 ///
11135 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11136 ///
11137 /// Special cases:
11138 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11139 /// f(x,y,z,\text{NaN})=\text{NaN}$
11140 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11141 /// f(x,y,z,\text{NaN})=\text{NaN}$
11142 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
11143 /// [`Rational`] counts as an unsigned zero and a positive sign.
11144 /// - If exactly one product is infinite, the result is that product's infinity.
11145 /// - If both products are infinite, the result is their common infinity if their signs agree,
11146 /// and `NaN` otherwise.
11147 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
11148 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
11149 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
11150 ///
11151 /// Overflow and underflow:
11152 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
11153 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
11154 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
11155 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
11156 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
11157 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
11158 ///
11159 /// If you want to use a rounding mode other than `Nearest`, consider using
11160 /// [`Float::mul_add_mul_rational_round`]. If you want to specify the output precision, consider
11161 /// using [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
11162 /// [`Float::mul_add_mul_prec_round`].
11163 ///
11164 /// # Worst-case complexity
11165 /// $T(n, m) = O(n \log n \log\log n + m)$
11166 ///
11167 /// $M(n, m) = O(n \log n + m)$
11168 ///
11169 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11170 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11171 /// `self.significant_bits()`.
11172 ///
11173 /// # Examples
11174 /// ```
11175 /// use core::f64::consts::{E, PI, SQRT_2};
11176 /// use malachite_base::num::arithmetic::traits::MulAddMul;
11177 /// use malachite_float::Float;
11178 /// use malachite_q::Rational;
11179 ///
11180 /// let x = Float::from(PI);
11181 /// let y = Float::from(E);
11182 /// let z = Float::from(SQRT_2);
11183 /// let w = Rational::from_signeds(1, 3);
11184 /// assert_eq!(x.mul_add_mul(y, &z, w).to_string(), "9.0111387434645973");
11185 /// ```
11186 #[inline]
11187 fn mul_add_mul(self, y: Self, z: &Self, w: Rational) -> Self {
11188 let prec = max!(
11189 self.significant_bits(),
11190 y.significant_bits(),
11191 z.significant_bits()
11192 );
11193 self.mul_add_mul_rational_prec_val_val_ref_val(y, z, w, prec)
11194 .0
11195 }
11196}
11197
11198impl MulAddMul<Self, &Self, &Rational> for Float {
11199 type Output = Self;
11200 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking the first two by
11201 /// value and the last two by reference.
11202 ///
11203 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11204 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11205 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11206 /// the `Nearest` rounding mode.
11207 ///
11208 /// $$
11209 /// f(x,y,z,w) = xy+zw+\varepsilon.
11210 /// $$
11211 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11212 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11213 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11214 ///
11215 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11216 ///
11217 /// Special cases:
11218 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11219 /// f(x,y,z,\text{NaN})=\text{NaN}$
11220 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11221 /// f(x,y,z,\text{NaN})=\text{NaN}$
11222 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
11223 /// [`Rational`] counts as an unsigned zero and a positive sign.
11224 /// - If exactly one product is infinite, the result is that product's infinity.
11225 /// - If both products are infinite, the result is their common infinity if their signs agree,
11226 /// and `NaN` otherwise.
11227 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
11228 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
11229 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
11230 ///
11231 /// Overflow and underflow:
11232 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
11233 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
11234 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
11235 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
11236 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
11237 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
11238 ///
11239 /// If you want to use a rounding mode other than `Nearest`, consider using
11240 /// [`Float::mul_add_mul_rational_round`]. If you want to specify the output precision, consider
11241 /// using [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
11242 /// [`Float::mul_add_mul_prec_round`].
11243 ///
11244 /// # Worst-case complexity
11245 /// $T(n, m) = O(n \log n \log\log n + m)$
11246 ///
11247 /// $M(n, m) = O(n \log n + m)$
11248 ///
11249 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11250 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11251 /// `self.significant_bits()`.
11252 ///
11253 /// # Examples
11254 /// ```
11255 /// use core::f64::consts::{E, PI, SQRT_2};
11256 /// use malachite_base::num::arithmetic::traits::MulAddMul;
11257 /// use malachite_float::Float;
11258 /// use malachite_q::Rational;
11259 ///
11260 /// let x = Float::from(PI);
11261 /// let y = Float::from(E);
11262 /// let z = Float::from(SQRT_2);
11263 /// let w = Rational::from_signeds(1, 3);
11264 /// assert_eq!(x.mul_add_mul(y, &z, &w).to_string(), "9.0111387434645973");
11265 /// ```
11266 #[inline]
11267 fn mul_add_mul(self, y: Self, z: &Self, w: &Rational) -> Self {
11268 let prec = max!(
11269 self.significant_bits(),
11270 y.significant_bits(),
11271 z.significant_bits()
11272 );
11273 self.mul_add_mul_rational_prec_val_val_ref_ref(y, z, w, prec)
11274 .0
11275 }
11276}
11277
11278impl MulAddMul<&Self, Self, Rational> for Float {
11279 type Output = Self;
11280 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking the second by
11281 /// reference and the others by value.
11282 ///
11283 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11284 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11285 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11286 /// the `Nearest` rounding mode.
11287 ///
11288 /// $$
11289 /// f(x,y,z,w) = xy+zw+\varepsilon.
11290 /// $$
11291 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11292 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11293 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11294 ///
11295 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11296 ///
11297 /// Special cases:
11298 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11299 /// f(x,y,z,\text{NaN})=\text{NaN}$
11300 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11301 /// f(x,y,z,\text{NaN})=\text{NaN}$
11302 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
11303 /// [`Rational`] counts as an unsigned zero and a positive sign.
11304 /// - If exactly one product is infinite, the result is that product's infinity.
11305 /// - If both products are infinite, the result is their common infinity if their signs agree,
11306 /// and `NaN` otherwise.
11307 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
11308 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
11309 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
11310 ///
11311 /// Overflow and underflow:
11312 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
11313 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
11314 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
11315 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
11316 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
11317 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
11318 ///
11319 /// If you want to use a rounding mode other than `Nearest`, consider using
11320 /// [`Float::mul_add_mul_rational_round`]. If you want to specify the output precision, consider
11321 /// using [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
11322 /// [`Float::mul_add_mul_prec_round`].
11323 ///
11324 /// # Worst-case complexity
11325 /// $T(n, m) = O(n \log n \log\log n + m)$
11326 ///
11327 /// $M(n, m) = O(n \log n + m)$
11328 ///
11329 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11330 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11331 /// `self.significant_bits()`.
11332 ///
11333 /// # Examples
11334 /// ```
11335 /// use core::f64::consts::{E, PI, SQRT_2};
11336 /// use malachite_base::num::arithmetic::traits::MulAddMul;
11337 /// use malachite_float::Float;
11338 /// use malachite_q::Rational;
11339 ///
11340 /// let x = Float::from(PI);
11341 /// let y = Float::from(E);
11342 /// let z = Float::from(SQRT_2);
11343 /// let w = Rational::from_signeds(1, 3);
11344 /// assert_eq!(x.mul_add_mul(&y, z, w).to_string(), "9.0111387434645973");
11345 /// ```
11346 #[inline]
11347 fn mul_add_mul(self, y: &Self, z: Self, w: Rational) -> Self {
11348 let prec = max!(
11349 self.significant_bits(),
11350 y.significant_bits(),
11351 z.significant_bits()
11352 );
11353 self.mul_add_mul_rational_prec_val_ref_val_val(y, z, w, prec)
11354 .0
11355 }
11356}
11357
11358impl MulAddMul<&Self, Self, &Rational> for Float {
11359 type Output = Self;
11360 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking the second and
11361 /// fourth by reference and the others by value.
11362 ///
11363 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11364 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11365 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11366 /// the `Nearest` rounding mode.
11367 ///
11368 /// $$
11369 /// f(x,y,z,w) = xy+zw+\varepsilon.
11370 /// $$
11371 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11372 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11373 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11374 ///
11375 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11376 ///
11377 /// Special cases:
11378 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11379 /// f(x,y,z,\text{NaN})=\text{NaN}$
11380 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11381 /// f(x,y,z,\text{NaN})=\text{NaN}$
11382 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
11383 /// [`Rational`] counts as an unsigned zero and a positive sign.
11384 /// - If exactly one product is infinite, the result is that product's infinity.
11385 /// - If both products are infinite, the result is their common infinity if their signs agree,
11386 /// and `NaN` otherwise.
11387 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
11388 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
11389 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
11390 ///
11391 /// Overflow and underflow:
11392 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
11393 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
11394 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
11395 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
11396 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
11397 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
11398 ///
11399 /// If you want to use a rounding mode other than `Nearest`, consider using
11400 /// [`Float::mul_add_mul_rational_round`]. If you want to specify the output precision, consider
11401 /// using [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
11402 /// [`Float::mul_add_mul_prec_round`].
11403 ///
11404 /// # Worst-case complexity
11405 /// $T(n, m) = O(n \log n \log\log n + m)$
11406 ///
11407 /// $M(n, m) = O(n \log n + m)$
11408 ///
11409 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11410 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11411 /// `self.significant_bits()`.
11412 ///
11413 /// # Examples
11414 /// ```
11415 /// use core::f64::consts::{E, PI, SQRT_2};
11416 /// use malachite_base::num::arithmetic::traits::MulAddMul;
11417 /// use malachite_float::Float;
11418 /// use malachite_q::Rational;
11419 ///
11420 /// let x = Float::from(PI);
11421 /// let y = Float::from(E);
11422 /// let z = Float::from(SQRT_2);
11423 /// let w = Rational::from_signeds(1, 3);
11424 /// assert_eq!(x.mul_add_mul(&y, z, &w).to_string(), "9.0111387434645973");
11425 /// ```
11426 #[inline]
11427 fn mul_add_mul(self, y: &Self, z: Self, w: &Rational) -> Self {
11428 let prec = max!(
11429 self.significant_bits(),
11430 y.significant_bits(),
11431 z.significant_bits()
11432 );
11433 self.mul_add_mul_rational_prec_val_ref_val_ref(y, z, w, prec)
11434 .0
11435 }
11436}
11437
11438impl MulAddMul<&Self, &Self, Rational> for Float {
11439 type Output = Self;
11440 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking the second and
11441 /// third by reference and the others by value.
11442 ///
11443 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11444 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11445 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11446 /// the `Nearest` rounding mode.
11447 ///
11448 /// $$
11449 /// f(x,y,z,w) = xy+zw+\varepsilon.
11450 /// $$
11451 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11452 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11453 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11454 ///
11455 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11456 ///
11457 /// Special cases:
11458 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11459 /// f(x,y,z,\text{NaN})=\text{NaN}$
11460 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11461 /// f(x,y,z,\text{NaN})=\text{NaN}$
11462 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
11463 /// [`Rational`] counts as an unsigned zero and a positive sign.
11464 /// - If exactly one product is infinite, the result is that product's infinity.
11465 /// - If both products are infinite, the result is their common infinity if their signs agree,
11466 /// and `NaN` otherwise.
11467 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
11468 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
11469 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
11470 ///
11471 /// Overflow and underflow:
11472 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
11473 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
11474 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
11475 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
11476 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
11477 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
11478 ///
11479 /// If you want to use a rounding mode other than `Nearest`, consider using
11480 /// [`Float::mul_add_mul_rational_round`]. If you want to specify the output precision, consider
11481 /// using [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
11482 /// [`Float::mul_add_mul_prec_round`].
11483 ///
11484 /// # Worst-case complexity
11485 /// $T(n, m) = O(n \log n \log\log n + m)$
11486 ///
11487 /// $M(n, m) = O(n \log n + m)$
11488 ///
11489 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11490 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11491 /// `self.significant_bits()`.
11492 ///
11493 /// # Examples
11494 /// ```
11495 /// use core::f64::consts::{E, PI, SQRT_2};
11496 /// use malachite_base::num::arithmetic::traits::MulAddMul;
11497 /// use malachite_float::Float;
11498 /// use malachite_q::Rational;
11499 ///
11500 /// let x = Float::from(PI);
11501 /// let y = Float::from(E);
11502 /// let z = Float::from(SQRT_2);
11503 /// let w = Rational::from_signeds(1, 3);
11504 /// assert_eq!(x.mul_add_mul(&y, &z, w).to_string(), "9.0111387434645973");
11505 /// ```
11506 #[inline]
11507 fn mul_add_mul(self, y: &Self, z: &Self, w: Rational) -> Self {
11508 let prec = max!(
11509 self.significant_bits(),
11510 y.significant_bits(),
11511 z.significant_bits()
11512 );
11513 self.mul_add_mul_rational_prec_val_ref_ref_val(y, z, w, prec)
11514 .0
11515 }
11516}
11517
11518impl MulAddMul<&Self, &Self, &Rational> for Float {
11519 type Output = Self;
11520 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking the first by
11521 /// value and the others by reference.
11522 ///
11523 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11524 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11525 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11526 /// the `Nearest` rounding mode.
11527 ///
11528 /// $$
11529 /// f(x,y,z,w) = xy+zw+\varepsilon.
11530 /// $$
11531 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11532 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11533 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11534 ///
11535 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11536 ///
11537 /// Special cases:
11538 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11539 /// f(x,y,z,\text{NaN})=\text{NaN}$
11540 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11541 /// f(x,y,z,\text{NaN})=\text{NaN}$
11542 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
11543 /// [`Rational`] counts as an unsigned zero and a positive sign.
11544 /// - If exactly one product is infinite, the result is that product's infinity.
11545 /// - If both products are infinite, the result is their common infinity if their signs agree,
11546 /// and `NaN` otherwise.
11547 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
11548 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
11549 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
11550 ///
11551 /// Overflow and underflow:
11552 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
11553 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
11554 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
11555 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
11556 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
11557 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
11558 ///
11559 /// If you want to use a rounding mode other than `Nearest`, consider using
11560 /// [`Float::mul_add_mul_rational_round`]. If you want to specify the output precision, consider
11561 /// using [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
11562 /// [`Float::mul_add_mul_prec_round`].
11563 ///
11564 /// # Worst-case complexity
11565 /// $T(n, m) = O(n \log n \log\log n + m)$
11566 ///
11567 /// $M(n, m) = O(n \log n + m)$
11568 ///
11569 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11570 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11571 /// `self.significant_bits()`.
11572 ///
11573 /// # Examples
11574 /// ```
11575 /// use core::f64::consts::{E, PI, SQRT_2};
11576 /// use malachite_base::num::arithmetic::traits::MulAddMul;
11577 /// use malachite_float::Float;
11578 /// use malachite_q::Rational;
11579 ///
11580 /// let x = Float::from(PI);
11581 /// let y = Float::from(E);
11582 /// let z = Float::from(SQRT_2);
11583 /// let w = Rational::from_signeds(1, 3);
11584 /// assert_eq!(x.mul_add_mul(&y, &z, &w).to_string(), "9.0111387434645973");
11585 /// ```
11586 #[inline]
11587 fn mul_add_mul(self, y: &Self, z: &Self, w: &Rational) -> Self {
11588 let prec = max!(
11589 self.significant_bits(),
11590 y.significant_bits(),
11591 z.significant_bits()
11592 );
11593 self.mul_add_mul_rational_prec_val_ref_ref_ref(y, z, w, prec)
11594 .0
11595 }
11596}
11597
11598impl MulAddMul<&Float, &Float, &Rational> for &Float {
11599 type Output = Float;
11600 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking all four by
11601 /// reference.
11602 ///
11603 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11604 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11605 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11606 /// the `Nearest` rounding mode.
11607 ///
11608 /// $$
11609 /// f(x,y,z,w) = xy+zw+\varepsilon.
11610 /// $$
11611 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11612 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11613 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11614 ///
11615 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11616 ///
11617 /// Special cases:
11618 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11619 /// f(x,y,z,\text{NaN})=\text{NaN}$
11620 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11621 /// f(x,y,z,\text{NaN})=\text{NaN}$
11622 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
11623 /// [`Rational`] counts as an unsigned zero and a positive sign.
11624 /// - If exactly one product is infinite, the result is that product's infinity.
11625 /// - If both products are infinite, the result is their common infinity if their signs agree,
11626 /// and `NaN` otherwise.
11627 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
11628 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
11629 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
11630 ///
11631 /// Overflow and underflow:
11632 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
11633 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
11634 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
11635 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
11636 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
11637 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
11638 ///
11639 /// If you want to use a rounding mode other than `Nearest`, consider using
11640 /// [`Float::mul_add_mul_rational_round`]. If you want to specify the output precision, consider
11641 /// using [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
11642 /// [`Float::mul_add_mul_prec_round`].
11643 ///
11644 /// # Worst-case complexity
11645 /// $T(n, m) = O(n \log n \log\log n + m)$
11646 ///
11647 /// $M(n, m) = O(n \log n + m)$
11648 ///
11649 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11650 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11651 /// `self.significant_bits()`.
11652 ///
11653 /// # Examples
11654 /// ```
11655 /// use core::f64::consts::{E, PI, SQRT_2};
11656 /// use malachite_base::num::arithmetic::traits::MulAddMul;
11657 /// use malachite_float::Float;
11658 /// use malachite_q::Rational;
11659 ///
11660 /// let x = Float::from(PI);
11661 /// let y = Float::from(E);
11662 /// let z = Float::from(SQRT_2);
11663 /// let w = Rational::from_signeds(1, 3);
11664 /// assert_eq!(&x.mul_add_mul(&y, &z, &w).to_string(), "9.0111387434645973");
11665 /// ```
11666 #[inline]
11667 fn mul_add_mul(self, y: &Float, z: &Float, w: &Rational) -> Float {
11668 let prec = max!(
11669 self.significant_bits(),
11670 y.significant_bits(),
11671 z.significant_bits()
11672 );
11673 self.mul_add_mul_rational_prec_ref_ref_ref_ref(y, z, w, prec)
11674 .0
11675 }
11676}
11677
11678impl MulAddMulAssign<Self, Self, Rational> for Float {
11679 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
11680 /// [`Float`]s, with a single rounding. The [`Float`]s on the right-hand side are all taken by
11681 /// value.
11682 ///
11683 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11684 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11685 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11686 /// the `Nearest` rounding mode.
11687 ///
11688 /// $$
11689 /// x \gets xy+zw+\varepsilon.
11690 /// $$
11691 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11692 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11693 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11694 ///
11695 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
11696 /// overflow, and underflow.
11697 ///
11698 /// If you want to use a rounding mode other than `Nearest`, consider using
11699 /// [`Float::mul_add_mul_rational_round_assign`]. If you want to specify the output precision,
11700 /// consider using [`Float::mul_add_mul_prec_assign`]. If you want both of these things,
11701 /// consider using [`Float::mul_add_mul_prec_round_assign`].
11702 ///
11703 /// # Worst-case complexity
11704 /// $T(n, m) = O(n \log n \log\log n + m)$
11705 ///
11706 /// $M(n, m) = O(n \log n + m)$
11707 ///
11708 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11709 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11710 /// `self.significant_bits()`.
11711 ///
11712 /// # Examples
11713 /// ```
11714 /// use core::f64::consts::{E, PI, SQRT_2};
11715 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
11716 /// use malachite_float::Float;
11717 /// use malachite_q::Rational;
11718 ///
11719 /// let mut x = Float::from(PI);
11720 /// let y = Float::from(E);
11721 /// let z = Float::from(SQRT_2);
11722 /// let w = Rational::from_signeds(1, 3);
11723 /// x.mul_add_mul_assign(y, z, w);
11724 /// assert_eq!(x.to_string(), "9.0111387434645973");
11725 /// ```
11726 #[inline]
11727 fn mul_add_mul_assign(&mut self, y: Self, z: Self, w: Rational) {
11728 let prec = max!(
11729 self.significant_bits(),
11730 y.significant_bits(),
11731 z.significant_bits()
11732 );
11733 self.mul_add_mul_rational_prec_assign(y, z, w, prec);
11734 }
11735}
11736
11737impl MulAddMulAssign<Self, Self, &Rational> for Float {
11738 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
11739 /// [`Float`]s, with a single rounding. The last [`Float`] on the right-hand side is taken by
11740 /// reference and the others by value.
11741 ///
11742 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11743 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11744 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11745 /// the `Nearest` rounding mode.
11746 ///
11747 /// $$
11748 /// x \gets xy+zw+\varepsilon.
11749 /// $$
11750 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11751 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11752 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11753 ///
11754 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
11755 /// overflow, and underflow.
11756 ///
11757 /// If you want to use a rounding mode other than `Nearest`, consider using
11758 /// [`Float::mul_add_mul_rational_round_assign`]. If you want to specify the output precision,
11759 /// consider using [`Float::mul_add_mul_prec_assign`]. If you want both of these things,
11760 /// consider using [`Float::mul_add_mul_prec_round_assign`].
11761 ///
11762 /// # Worst-case complexity
11763 /// $T(n, m) = O(n \log n \log\log n + m)$
11764 ///
11765 /// $M(n, m) = O(n \log n + m)$
11766 ///
11767 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11768 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11769 /// `self.significant_bits()`.
11770 ///
11771 /// # Examples
11772 /// ```
11773 /// use core::f64::consts::{E, PI, SQRT_2};
11774 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
11775 /// use malachite_float::Float;
11776 /// use malachite_q::Rational;
11777 ///
11778 /// let mut x = Float::from(PI);
11779 /// let y = Float::from(E);
11780 /// let z = Float::from(SQRT_2);
11781 /// let w = Rational::from_signeds(1, 3);
11782 /// x.mul_add_mul_assign(y, z, &w);
11783 /// assert_eq!(x.to_string(), "9.0111387434645973");
11784 /// ```
11785 #[inline]
11786 fn mul_add_mul_assign(&mut self, y: Self, z: Self, w: &Rational) {
11787 let prec = max!(
11788 self.significant_bits(),
11789 y.significant_bits(),
11790 z.significant_bits()
11791 );
11792 self.mul_add_mul_rational_prec_assign_val_val_ref(y, z, w, prec);
11793 }
11794}
11795
11796impl MulAddMulAssign<Self, &Self, Rational> for Float {
11797 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
11798 /// [`Float`]s, with a single rounding. The middle [`Float`] on the right-hand side is taken by
11799 /// reference and the others by value.
11800 ///
11801 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11802 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11803 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11804 /// the `Nearest` rounding mode.
11805 ///
11806 /// $$
11807 /// x \gets xy+zw+\varepsilon.
11808 /// $$
11809 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11810 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11811 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11812 ///
11813 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
11814 /// overflow, and underflow.
11815 ///
11816 /// If you want to use a rounding mode other than `Nearest`, consider using
11817 /// [`Float::mul_add_mul_rational_round_assign`]. If you want to specify the output precision,
11818 /// consider using [`Float::mul_add_mul_prec_assign`]. If you want both of these things,
11819 /// consider using [`Float::mul_add_mul_prec_round_assign`].
11820 ///
11821 /// # Worst-case complexity
11822 /// $T(n, m) = O(n \log n \log\log n + m)$
11823 ///
11824 /// $M(n, m) = O(n \log n + m)$
11825 ///
11826 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11827 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11828 /// `self.significant_bits()`.
11829 ///
11830 /// # Examples
11831 /// ```
11832 /// use core::f64::consts::{E, PI, SQRT_2};
11833 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
11834 /// use malachite_float::Float;
11835 /// use malachite_q::Rational;
11836 ///
11837 /// let mut x = Float::from(PI);
11838 /// let y = Float::from(E);
11839 /// let z = Float::from(SQRT_2);
11840 /// let w = Rational::from_signeds(1, 3);
11841 /// x.mul_add_mul_assign(y, &z, w);
11842 /// assert_eq!(x.to_string(), "9.0111387434645973");
11843 /// ```
11844 #[inline]
11845 fn mul_add_mul_assign(&mut self, y: Self, z: &Self, w: Rational) {
11846 let prec = max!(
11847 self.significant_bits(),
11848 y.significant_bits(),
11849 z.significant_bits()
11850 );
11851 self.mul_add_mul_rational_prec_assign_val_ref_val(y, z, w, prec);
11852 }
11853}
11854
11855impl MulAddMulAssign<Self, &Self, &Rational> for Float {
11856 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
11857 /// [`Float`]s, with a single rounding. The first [`Float`] on the right-hand side is taken by
11858 /// value and the others by reference.
11859 ///
11860 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11861 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11862 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11863 /// the `Nearest` rounding mode.
11864 ///
11865 /// $$
11866 /// x \gets xy+zw+\varepsilon.
11867 /// $$
11868 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11869 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11870 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11871 ///
11872 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
11873 /// overflow, and underflow.
11874 ///
11875 /// If you want to use a rounding mode other than `Nearest`, consider using
11876 /// [`Float::mul_add_mul_rational_round_assign`]. If you want to specify the output precision,
11877 /// consider using [`Float::mul_add_mul_prec_assign`]. If you want both of these things,
11878 /// consider using [`Float::mul_add_mul_prec_round_assign`].
11879 ///
11880 /// # Worst-case complexity
11881 /// $T(n, m) = O(n \log n \log\log n + m)$
11882 ///
11883 /// $M(n, m) = O(n \log n + m)$
11884 ///
11885 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11886 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11887 /// `self.significant_bits()`.
11888 ///
11889 /// # Examples
11890 /// ```
11891 /// use core::f64::consts::{E, PI, SQRT_2};
11892 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
11893 /// use malachite_float::Float;
11894 /// use malachite_q::Rational;
11895 ///
11896 /// let mut x = Float::from(PI);
11897 /// let y = Float::from(E);
11898 /// let z = Float::from(SQRT_2);
11899 /// let w = Rational::from_signeds(1, 3);
11900 /// x.mul_add_mul_assign(y, &z, &w);
11901 /// assert_eq!(x.to_string(), "9.0111387434645973");
11902 /// ```
11903 #[inline]
11904 fn mul_add_mul_assign(&mut self, y: Self, z: &Self, w: &Rational) {
11905 let prec = max!(
11906 self.significant_bits(),
11907 y.significant_bits(),
11908 z.significant_bits()
11909 );
11910 self.mul_add_mul_rational_prec_assign_val_ref_ref(y, z, w, prec);
11911 }
11912}
11913
11914impl MulAddMulAssign<&Self, Self, Rational> for Float {
11915 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
11916 /// [`Float`]s, with a single rounding. The first [`Float`] on the right-hand side is taken by
11917 /// reference and the others by value.
11918 ///
11919 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11920 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11921 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11922 /// the `Nearest` rounding mode.
11923 ///
11924 /// $$
11925 /// x \gets xy+zw+\varepsilon.
11926 /// $$
11927 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11928 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11929 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11930 ///
11931 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
11932 /// overflow, and underflow.
11933 ///
11934 /// If you want to use a rounding mode other than `Nearest`, consider using
11935 /// [`Float::mul_add_mul_rational_round_assign`]. If you want to specify the output precision,
11936 /// consider using [`Float::mul_add_mul_prec_assign`]. If you want both of these things,
11937 /// consider using [`Float::mul_add_mul_prec_round_assign`].
11938 ///
11939 /// # Worst-case complexity
11940 /// $T(n, m) = O(n \log n \log\log n + m)$
11941 ///
11942 /// $M(n, m) = O(n \log n + m)$
11943 ///
11944 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11945 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11946 /// `self.significant_bits()`.
11947 ///
11948 /// # Examples
11949 /// ```
11950 /// use core::f64::consts::{E, PI, SQRT_2};
11951 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
11952 /// use malachite_float::Float;
11953 /// use malachite_q::Rational;
11954 ///
11955 /// let mut x = Float::from(PI);
11956 /// let y = Float::from(E);
11957 /// let z = Float::from(SQRT_2);
11958 /// let w = Rational::from_signeds(1, 3);
11959 /// x.mul_add_mul_assign(&y, z, w);
11960 /// assert_eq!(x.to_string(), "9.0111387434645973");
11961 /// ```
11962 #[inline]
11963 fn mul_add_mul_assign(&mut self, y: &Self, z: Self, w: Rational) {
11964 let prec = max!(
11965 self.significant_bits(),
11966 y.significant_bits(),
11967 z.significant_bits()
11968 );
11969 self.mul_add_mul_rational_prec_assign_ref_val_val(y, z, w, prec);
11970 }
11971}
11972
11973impl MulAddMulAssign<&Self, Self, &Rational> for Float {
11974 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
11975 /// [`Float`]s, with a single rounding. The middle [`Float`] on the right-hand side is taken by
11976 /// value and the others by reference.
11977 ///
11978 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11979 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11980 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11981 /// the `Nearest` rounding mode.
11982 ///
11983 /// $$
11984 /// x \gets xy+zw+\varepsilon.
11985 /// $$
11986 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11987 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11988 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11989 ///
11990 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
11991 /// overflow, and underflow.
11992 ///
11993 /// If you want to use a rounding mode other than `Nearest`, consider using
11994 /// [`Float::mul_add_mul_rational_round_assign`]. If you want to specify the output precision,
11995 /// consider using [`Float::mul_add_mul_prec_assign`]. If you want both of these things,
11996 /// consider using [`Float::mul_add_mul_prec_round_assign`].
11997 ///
11998 /// # Worst-case complexity
11999 /// $T(n, m) = O(n \log n \log\log n + m)$
12000 ///
12001 /// $M(n, m) = O(n \log n + m)$
12002 ///
12003 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12004 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12005 /// `self.significant_bits()`.
12006 ///
12007 /// # Examples
12008 /// ```
12009 /// use core::f64::consts::{E, PI, SQRT_2};
12010 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
12011 /// use malachite_float::Float;
12012 /// use malachite_q::Rational;
12013 ///
12014 /// let mut x = Float::from(PI);
12015 /// let y = Float::from(E);
12016 /// let z = Float::from(SQRT_2);
12017 /// let w = Rational::from_signeds(1, 3);
12018 /// x.mul_add_mul_assign(&y, z, &w);
12019 /// assert_eq!(x.to_string(), "9.0111387434645973");
12020 /// ```
12021 #[inline]
12022 fn mul_add_mul_assign(&mut self, y: &Self, z: Self, w: &Rational) {
12023 let prec = max!(
12024 self.significant_bits(),
12025 y.significant_bits(),
12026 z.significant_bits()
12027 );
12028 self.mul_add_mul_rational_prec_assign_ref_val_ref(y, z, w, prec);
12029 }
12030}
12031
12032impl MulAddMulAssign<&Self, &Self, Rational> for Float {
12033 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
12034 /// [`Float`]s, with a single rounding. The last [`Float`] on the right-hand side is taken by
12035 /// value and the others by reference.
12036 ///
12037 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
12038 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
12039 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
12040 /// the `Nearest` rounding mode.
12041 ///
12042 /// $$
12043 /// x \gets xy+zw+\varepsilon.
12044 /// $$
12045 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12046 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12047 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12048 ///
12049 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
12050 /// overflow, and underflow.
12051 ///
12052 /// If you want to use a rounding mode other than `Nearest`, consider using
12053 /// [`Float::mul_add_mul_rational_round_assign`]. If you want to specify the output precision,
12054 /// consider using [`Float::mul_add_mul_prec_assign`]. If you want both of these things,
12055 /// consider using [`Float::mul_add_mul_prec_round_assign`].
12056 ///
12057 /// # Worst-case complexity
12058 /// $T(n, m) = O(n \log n \log\log n + m)$
12059 ///
12060 /// $M(n, m) = O(n \log n + m)$
12061 ///
12062 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12063 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12064 /// `self.significant_bits()`.
12065 ///
12066 /// # Examples
12067 /// ```
12068 /// use core::f64::consts::{E, PI, SQRT_2};
12069 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
12070 /// use malachite_float::Float;
12071 /// use malachite_q::Rational;
12072 ///
12073 /// let mut x = Float::from(PI);
12074 /// let y = Float::from(E);
12075 /// let z = Float::from(SQRT_2);
12076 /// let w = Rational::from_signeds(1, 3);
12077 /// x.mul_add_mul_assign(&y, &z, w);
12078 /// assert_eq!(x.to_string(), "9.0111387434645973");
12079 /// ```
12080 #[inline]
12081 fn mul_add_mul_assign(&mut self, y: &Self, z: &Self, w: Rational) {
12082 let prec = max!(
12083 self.significant_bits(),
12084 y.significant_bits(),
12085 z.significant_bits()
12086 );
12087 self.mul_add_mul_rational_prec_assign_ref_ref_val(y, z, w, prec);
12088 }
12089}
12090
12091impl MulAddMulAssign<&Self, &Self, &Rational> for Float {
12092 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
12093 /// [`Float`]s, with a single rounding. The [`Float`]s on the right-hand side are all taken by
12094 /// reference.
12095 ///
12096 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
12097 /// If the sum is equidistant from two [`Float`]s with the specified precision, the [`Float`]
12098 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
12099 /// the `Nearest` rounding mode.
12100 ///
12101 /// $$
12102 /// x \gets xy+zw+\varepsilon.
12103 /// $$
12104 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12105 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12106 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12107 ///
12108 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
12109 /// overflow, and underflow.
12110 ///
12111 /// If you want to use a rounding mode other than `Nearest`, consider using
12112 /// [`Float::mul_add_mul_rational_round_assign`]. If you want to specify the output precision,
12113 /// consider using [`Float::mul_add_mul_prec_assign`]. If you want both of these things,
12114 /// consider using [`Float::mul_add_mul_prec_round_assign`].
12115 ///
12116 /// # Worst-case complexity
12117 /// $T(n, m) = O(n \log n \log\log n + m)$
12118 ///
12119 /// $M(n, m) = O(n \log n + m)$
12120 ///
12121 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12122 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12123 /// `self.significant_bits()`.
12124 ///
12125 /// # Examples
12126 /// ```
12127 /// use core::f64::consts::{E, PI, SQRT_2};
12128 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
12129 /// use malachite_float::Float;
12130 /// use malachite_q::Rational;
12131 ///
12132 /// let mut x = Float::from(PI);
12133 /// let y = Float::from(E);
12134 /// let z = Float::from(SQRT_2);
12135 /// let w = Rational::from_signeds(1, 3);
12136 /// x.mul_add_mul_assign(&y, &z, &w);
12137 /// assert_eq!(x.to_string(), "9.0111387434645973");
12138 /// ```
12139 #[inline]
12140 fn mul_add_mul_assign(&mut self, y: &Self, z: &Self, w: &Rational) {
12141 let prec = max!(
12142 self.significant_bits(),
12143 y.significant_bits(),
12144 z.significant_bits()
12145 );
12146 self.mul_add_mul_rational_prec_assign_ref_ref_ref(y, z, w, prec);
12147 }
12148}
12149
12150impl MulAddMul<Self, Self, Self> for Float {
12151 type Output = Self;
12152 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking all four by
12153 /// value.
12154 ///
12155 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
12156 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
12157 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
12158 /// rounding mode.
12159 ///
12160 /// $$
12161 /// f(x,y,z,w) = xy+zw+\varepsilon.
12162 /// $$
12163 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12164 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12165 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12166 ///
12167 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12168 ///
12169 /// Special cases:
12170 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12171 /// f(x,y,z,\text{NaN})=\text{NaN}$
12172 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12173 /// f(x,y,z,\text{NaN})=\text{NaN}$
12174 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12175 /// f(x,y,z,\text{NaN})=\text{NaN}$
12176 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12177 /// - If exactly one product is infinite, the result is that product's infinity.
12178 /// - If both products are infinite, the result is their common infinity if their signs agree,
12179 /// and `NaN` otherwise.
12180 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
12181 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
12182 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
12183 ///
12184 /// Overflow and underflow:
12185 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12186 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12187 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12188 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12189 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12190 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12191 ///
12192 /// If you want to use a rounding mode other than `Nearest`, consider using
12193 /// [`Float::mul_add_mul_round`]. If you want to specify the output precision, consider using
12194 /// [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
12195 /// [`Float::mul_add_mul_prec_round`].
12196 ///
12197 /// # Worst-case complexity
12198 /// $T(n, m) = O(n \log n \log\log n + m)$
12199 ///
12200 /// $M(n, m) = O(n \log n + m)$
12201 ///
12202 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12203 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12204 /// `self.significant_bits()`.
12205 ///
12206 /// # Examples
12207 /// ```
12208 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12209 /// use malachite_base::num::arithmetic::traits::MulAddMul;
12210 /// use malachite_float::Float;
12211 ///
12212 /// let x = Float::from(PI);
12213 /// let y = Float::from(E);
12214 /// let z = Float::from(SQRT_2);
12215 /// let w = Float::from(LN_2);
12216 /// assert_eq!(x.mul_add_mul(y, z, w).to_string(), "9.5199923661421142");
12217 /// ```
12218 #[inline]
12219 fn mul_add_mul(self, y: Self, z: Self, w: Self) -> Self {
12220 let prec = max!(
12221 self.significant_bits(),
12222 y.significant_bits(),
12223 z.significant_bits(),
12224 w.significant_bits()
12225 );
12226 self.mul_add_mul_prec(y, z, w, prec).0
12227 }
12228}
12229
12230impl MulAddMul<Self, Self, &Self> for Float {
12231 type Output = Self;
12232 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking the first three
12233 /// by value and the fourth by reference.
12234 ///
12235 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
12236 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
12237 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
12238 /// rounding mode.
12239 ///
12240 /// $$
12241 /// f(x,y,z,w) = xy+zw+\varepsilon.
12242 /// $$
12243 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12244 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12245 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12246 ///
12247 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12248 ///
12249 /// Special cases:
12250 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12251 /// f(x,y,z,\text{NaN})=\text{NaN}$
12252 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12253 /// f(x,y,z,\text{NaN})=\text{NaN}$
12254 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12255 /// f(x,y,z,\text{NaN})=\text{NaN}$
12256 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12257 /// - If exactly one product is infinite, the result is that product's infinity.
12258 /// - If both products are infinite, the result is their common infinity if their signs agree,
12259 /// and `NaN` otherwise.
12260 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
12261 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
12262 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
12263 ///
12264 /// Overflow and underflow:
12265 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12266 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12267 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12268 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12269 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12270 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12271 ///
12272 /// If you want to use a rounding mode other than `Nearest`, consider using
12273 /// [`Float::mul_add_mul_round`]. If you want to specify the output precision, consider using
12274 /// [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
12275 /// [`Float::mul_add_mul_prec_round`].
12276 ///
12277 /// # Worst-case complexity
12278 /// $T(n, m) = O(n \log n \log\log n + m)$
12279 ///
12280 /// $M(n, m) = O(n \log n + m)$
12281 ///
12282 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12283 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12284 /// `self.significant_bits()`.
12285 ///
12286 /// # Examples
12287 /// ```
12288 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12289 /// use malachite_base::num::arithmetic::traits::MulAddMul;
12290 /// use malachite_float::Float;
12291 ///
12292 /// let x = Float::from(PI);
12293 /// let y = Float::from(E);
12294 /// let z = Float::from(SQRT_2);
12295 /// let w = Float::from(LN_2);
12296 /// assert_eq!(x.mul_add_mul(y, z, &w).to_string(), "9.5199923661421142");
12297 /// ```
12298 #[inline]
12299 fn mul_add_mul(self, y: Self, z: Self, w: &Self) -> Self {
12300 let prec = max!(
12301 self.significant_bits(),
12302 y.significant_bits(),
12303 z.significant_bits(),
12304 w.significant_bits()
12305 );
12306 self.mul_add_mul_prec_val_val_val_ref(y, z, w, prec).0
12307 }
12308}
12309
12310impl MulAddMul<Self, &Self, Self> for Float {
12311 type Output = Self;
12312 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking the third by
12313 /// reference and the others by value.
12314 ///
12315 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
12316 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
12317 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
12318 /// rounding mode.
12319 ///
12320 /// $$
12321 /// f(x,y,z,w) = xy+zw+\varepsilon.
12322 /// $$
12323 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12324 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12325 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12326 ///
12327 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12328 ///
12329 /// Special cases:
12330 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12331 /// f(x,y,z,\text{NaN})=\text{NaN}$
12332 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12333 /// f(x,y,z,\text{NaN})=\text{NaN}$
12334 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12335 /// f(x,y,z,\text{NaN})=\text{NaN}$
12336 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12337 /// - If exactly one product is infinite, the result is that product's infinity.
12338 /// - If both products are infinite, the result is their common infinity if their signs agree,
12339 /// and `NaN` otherwise.
12340 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
12341 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
12342 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
12343 ///
12344 /// Overflow and underflow:
12345 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12346 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12347 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12348 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12349 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12350 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12351 ///
12352 /// If you want to use a rounding mode other than `Nearest`, consider using
12353 /// [`Float::mul_add_mul_round`]. If you want to specify the output precision, consider using
12354 /// [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
12355 /// [`Float::mul_add_mul_prec_round`].
12356 ///
12357 /// # Worst-case complexity
12358 /// $T(n, m) = O(n \log n \log\log n + m)$
12359 ///
12360 /// $M(n, m) = O(n \log n + m)$
12361 ///
12362 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12363 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12364 /// `self.significant_bits()`.
12365 ///
12366 /// # Examples
12367 /// ```
12368 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12369 /// use malachite_base::num::arithmetic::traits::MulAddMul;
12370 /// use malachite_float::Float;
12371 ///
12372 /// let x = Float::from(PI);
12373 /// let y = Float::from(E);
12374 /// let z = Float::from(SQRT_2);
12375 /// let w = Float::from(LN_2);
12376 /// assert_eq!(x.mul_add_mul(y, &z, w).to_string(), "9.5199923661421142");
12377 /// ```
12378 #[inline]
12379 fn mul_add_mul(self, y: Self, z: &Self, w: Self) -> Self {
12380 let prec = max!(
12381 self.significant_bits(),
12382 y.significant_bits(),
12383 z.significant_bits(),
12384 w.significant_bits()
12385 );
12386 self.mul_add_mul_prec_val_val_ref_val(y, z, w, prec).0
12387 }
12388}
12389
12390impl MulAddMul<Self, &Self, &Self> for Float {
12391 type Output = Self;
12392 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking the first two by
12393 /// value and the last two by reference.
12394 ///
12395 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
12396 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
12397 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
12398 /// rounding mode.
12399 ///
12400 /// $$
12401 /// f(x,y,z,w) = xy+zw+\varepsilon.
12402 /// $$
12403 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12404 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12405 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12406 ///
12407 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12408 ///
12409 /// Special cases:
12410 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12411 /// f(x,y,z,\text{NaN})=\text{NaN}$
12412 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12413 /// f(x,y,z,\text{NaN})=\text{NaN}$
12414 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12415 /// f(x,y,z,\text{NaN})=\text{NaN}$
12416 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12417 /// - If exactly one product is infinite, the result is that product's infinity.
12418 /// - If both products are infinite, the result is their common infinity if their signs agree,
12419 /// and `NaN` otherwise.
12420 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
12421 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
12422 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
12423 ///
12424 /// Overflow and underflow:
12425 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12426 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12427 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12428 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12429 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12430 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12431 ///
12432 /// If you want to use a rounding mode other than `Nearest`, consider using
12433 /// [`Float::mul_add_mul_round`]. If you want to specify the output precision, consider using
12434 /// [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
12435 /// [`Float::mul_add_mul_prec_round`].
12436 ///
12437 /// # Worst-case complexity
12438 /// $T(n, m) = O(n \log n \log\log n + m)$
12439 ///
12440 /// $M(n, m) = O(n \log n + m)$
12441 ///
12442 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12443 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12444 /// `self.significant_bits()`.
12445 ///
12446 /// # Examples
12447 /// ```
12448 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12449 /// use malachite_base::num::arithmetic::traits::MulAddMul;
12450 /// use malachite_float::Float;
12451 ///
12452 /// let x = Float::from(PI);
12453 /// let y = Float::from(E);
12454 /// let z = Float::from(SQRT_2);
12455 /// let w = Float::from(LN_2);
12456 /// assert_eq!(x.mul_add_mul(y, &z, &w).to_string(), "9.5199923661421142");
12457 /// ```
12458 #[inline]
12459 fn mul_add_mul(self, y: Self, z: &Self, w: &Self) -> Self {
12460 let prec = max!(
12461 self.significant_bits(),
12462 y.significant_bits(),
12463 z.significant_bits(),
12464 w.significant_bits()
12465 );
12466 self.mul_add_mul_prec_val_val_ref_ref(y, z, w, prec).0
12467 }
12468}
12469
12470impl MulAddMul<&Self, Self, Self> for Float {
12471 type Output = Self;
12472 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking the second by
12473 /// reference and the others by value.
12474 ///
12475 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
12476 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
12477 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
12478 /// rounding mode.
12479 ///
12480 /// $$
12481 /// f(x,y,z,w) = xy+zw+\varepsilon.
12482 /// $$
12483 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12484 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12485 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12486 ///
12487 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12488 ///
12489 /// Special cases:
12490 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12491 /// f(x,y,z,\text{NaN})=\text{NaN}$
12492 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12493 /// f(x,y,z,\text{NaN})=\text{NaN}$
12494 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12495 /// f(x,y,z,\text{NaN})=\text{NaN}$
12496 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12497 /// - If exactly one product is infinite, the result is that product's infinity.
12498 /// - If both products are infinite, the result is their common infinity if their signs agree,
12499 /// and `NaN` otherwise.
12500 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
12501 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
12502 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
12503 ///
12504 /// Overflow and underflow:
12505 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12506 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12507 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12508 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12509 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12510 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12511 ///
12512 /// If you want to use a rounding mode other than `Nearest`, consider using
12513 /// [`Float::mul_add_mul_round`]. If you want to specify the output precision, consider using
12514 /// [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
12515 /// [`Float::mul_add_mul_prec_round`].
12516 ///
12517 /// # Worst-case complexity
12518 /// $T(n, m) = O(n \log n \log\log n + m)$
12519 ///
12520 /// $M(n, m) = O(n \log n + m)$
12521 ///
12522 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12523 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12524 /// `self.significant_bits()`.
12525 ///
12526 /// # Examples
12527 /// ```
12528 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12529 /// use malachite_base::num::arithmetic::traits::MulAddMul;
12530 /// use malachite_float::Float;
12531 ///
12532 /// let x = Float::from(PI);
12533 /// let y = Float::from(E);
12534 /// let z = Float::from(SQRT_2);
12535 /// let w = Float::from(LN_2);
12536 /// assert_eq!(x.mul_add_mul(&y, z, w).to_string(), "9.5199923661421142");
12537 /// ```
12538 #[inline]
12539 fn mul_add_mul(self, y: &Self, z: Self, w: Self) -> Self {
12540 let prec = max!(
12541 self.significant_bits(),
12542 y.significant_bits(),
12543 z.significant_bits(),
12544 w.significant_bits()
12545 );
12546 self.mul_add_mul_prec_val_ref_val_val(y, z, w, prec).0
12547 }
12548}
12549
12550impl MulAddMul<&Self, Self, &Self> for Float {
12551 type Output = Self;
12552 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking the second and
12553 /// fourth by reference and the others by value.
12554 ///
12555 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
12556 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
12557 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
12558 /// rounding mode.
12559 ///
12560 /// $$
12561 /// f(x,y,z,w) = xy+zw+\varepsilon.
12562 /// $$
12563 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12564 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12565 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12566 ///
12567 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12568 ///
12569 /// Special cases:
12570 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12571 /// f(x,y,z,\text{NaN})=\text{NaN}$
12572 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12573 /// f(x,y,z,\text{NaN})=\text{NaN}$
12574 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12575 /// f(x,y,z,\text{NaN})=\text{NaN}$
12576 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12577 /// - If exactly one product is infinite, the result is that product's infinity.
12578 /// - If both products are infinite, the result is their common infinity if their signs agree,
12579 /// and `NaN` otherwise.
12580 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
12581 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
12582 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
12583 ///
12584 /// Overflow and underflow:
12585 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12586 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12587 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12588 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12589 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12590 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12591 ///
12592 /// If you want to use a rounding mode other than `Nearest`, consider using
12593 /// [`Float::mul_add_mul_round`]. If you want to specify the output precision, consider using
12594 /// [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
12595 /// [`Float::mul_add_mul_prec_round`].
12596 ///
12597 /// # Worst-case complexity
12598 /// $T(n, m) = O(n \log n \log\log n + m)$
12599 ///
12600 /// $M(n, m) = O(n \log n + m)$
12601 ///
12602 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12603 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12604 /// `self.significant_bits()`.
12605 ///
12606 /// # Examples
12607 /// ```
12608 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12609 /// use malachite_base::num::arithmetic::traits::MulAddMul;
12610 /// use malachite_float::Float;
12611 ///
12612 /// let x = Float::from(PI);
12613 /// let y = Float::from(E);
12614 /// let z = Float::from(SQRT_2);
12615 /// let w = Float::from(LN_2);
12616 /// assert_eq!(x.mul_add_mul(&y, z, &w).to_string(), "9.5199923661421142");
12617 /// ```
12618 #[inline]
12619 fn mul_add_mul(self, y: &Self, z: Self, w: &Self) -> Self {
12620 let prec = max!(
12621 self.significant_bits(),
12622 y.significant_bits(),
12623 z.significant_bits(),
12624 w.significant_bits()
12625 );
12626 self.mul_add_mul_prec_val_ref_val_ref(y, z, w, prec).0
12627 }
12628}
12629
12630impl MulAddMul<&Self, &Self, Self> for Float {
12631 type Output = Self;
12632 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking the second and
12633 /// third by reference and the others by value.
12634 ///
12635 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
12636 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
12637 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
12638 /// rounding mode.
12639 ///
12640 /// $$
12641 /// f(x,y,z,w) = xy+zw+\varepsilon.
12642 /// $$
12643 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12644 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12645 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12646 ///
12647 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12648 ///
12649 /// Special cases:
12650 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12651 /// f(x,y,z,\text{NaN})=\text{NaN}$
12652 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12653 /// f(x,y,z,\text{NaN})=\text{NaN}$
12654 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12655 /// f(x,y,z,\text{NaN})=\text{NaN}$
12656 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12657 /// - If exactly one product is infinite, the result is that product's infinity.
12658 /// - If both products are infinite, the result is their common infinity if their signs agree,
12659 /// and `NaN` otherwise.
12660 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
12661 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
12662 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
12663 ///
12664 /// Overflow and underflow:
12665 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12666 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12667 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12668 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12669 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12670 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12671 ///
12672 /// If you want to use a rounding mode other than `Nearest`, consider using
12673 /// [`Float::mul_add_mul_round`]. If you want to specify the output precision, consider using
12674 /// [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
12675 /// [`Float::mul_add_mul_prec_round`].
12676 ///
12677 /// # Worst-case complexity
12678 /// $T(n, m) = O(n \log n \log\log n + m)$
12679 ///
12680 /// $M(n, m) = O(n \log n + m)$
12681 ///
12682 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12683 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12684 /// `self.significant_bits()`.
12685 ///
12686 /// # Examples
12687 /// ```
12688 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12689 /// use malachite_base::num::arithmetic::traits::MulAddMul;
12690 /// use malachite_float::Float;
12691 ///
12692 /// let x = Float::from(PI);
12693 /// let y = Float::from(E);
12694 /// let z = Float::from(SQRT_2);
12695 /// let w = Float::from(LN_2);
12696 /// assert_eq!(x.mul_add_mul(&y, &z, w).to_string(), "9.5199923661421142");
12697 /// ```
12698 #[inline]
12699 fn mul_add_mul(self, y: &Self, z: &Self, w: Self) -> Self {
12700 let prec = max!(
12701 self.significant_bits(),
12702 y.significant_bits(),
12703 z.significant_bits(),
12704 w.significant_bits()
12705 );
12706 self.mul_add_mul_prec_val_ref_ref_val(y, z, w, prec).0
12707 }
12708}
12709
12710impl MulAddMul<&Self, &Self, &Self> for Float {
12711 type Output = Self;
12712 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking the first by
12713 /// value and the others by reference.
12714 ///
12715 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
12716 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
12717 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
12718 /// rounding mode.
12719 ///
12720 /// $$
12721 /// f(x,y,z,w) = xy+zw+\varepsilon.
12722 /// $$
12723 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12724 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12725 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12726 ///
12727 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12728 ///
12729 /// Special cases:
12730 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12731 /// f(x,y,z,\text{NaN})=\text{NaN}$
12732 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12733 /// f(x,y,z,\text{NaN})=\text{NaN}$
12734 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12735 /// f(x,y,z,\text{NaN})=\text{NaN}$
12736 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12737 /// - If exactly one product is infinite, the result is that product's infinity.
12738 /// - If both products are infinite, the result is their common infinity if their signs agree,
12739 /// and `NaN` otherwise.
12740 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
12741 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
12742 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
12743 ///
12744 /// Overflow and underflow:
12745 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12746 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12747 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12748 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12749 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12750 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12751 ///
12752 /// If you want to use a rounding mode other than `Nearest`, consider using
12753 /// [`Float::mul_add_mul_round`]. If you want to specify the output precision, consider using
12754 /// [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
12755 /// [`Float::mul_add_mul_prec_round`].
12756 ///
12757 /// # Worst-case complexity
12758 /// $T(n, m) = O(n \log n \log\log n + m)$
12759 ///
12760 /// $M(n, m) = O(n \log n + m)$
12761 ///
12762 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12763 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12764 /// `self.significant_bits()`.
12765 ///
12766 /// # Examples
12767 /// ```
12768 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12769 /// use malachite_base::num::arithmetic::traits::MulAddMul;
12770 /// use malachite_float::Float;
12771 ///
12772 /// let x = Float::from(PI);
12773 /// let y = Float::from(E);
12774 /// let z = Float::from(SQRT_2);
12775 /// let w = Float::from(LN_2);
12776 /// assert_eq!(x.mul_add_mul(&y, &z, &w).to_string(), "9.5199923661421142");
12777 /// ```
12778 #[inline]
12779 fn mul_add_mul(self, y: &Self, z: &Self, w: &Self) -> Self {
12780 let prec = max!(
12781 self.significant_bits(),
12782 y.significant_bits(),
12783 z.significant_bits(),
12784 w.significant_bits()
12785 );
12786 self.mul_add_mul_prec_val_ref_ref_ref(y, z, w, prec).0
12787 }
12788}
12789
12790impl MulAddMul<&Float, &Float, &Float> for &Float {
12791 type Output = Float;
12792 /// Adds the products of two pairs of [`Float`]s with a single rounding, taking all four by
12793 /// reference.
12794 ///
12795 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
12796 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
12797 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
12798 /// rounding mode.
12799 ///
12800 /// $$
12801 /// f(x,y,z,w) = xy+zw+\varepsilon.
12802 /// $$
12803 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12804 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12805 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12806 ///
12807 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12808 ///
12809 /// Special cases:
12810 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12811 /// f(x,y,z,\text{NaN})=\text{NaN}$
12812 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12813 /// f(x,y,z,\text{NaN})=\text{NaN}$
12814 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12815 /// f(x,y,z,\text{NaN})=\text{NaN}$
12816 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12817 /// - If exactly one product is infinite, the result is that product's infinity.
12818 /// - If both products are infinite, the result is their common infinity if their signs agree,
12819 /// and `NaN` otherwise.
12820 /// - If both products are zeros, the sign rules of [`Float`] addition apply.
12821 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$, the products are
12822 /// - $f(x,y,z,w)=0.0$ if $xy=-zw$ and the products are finite and nonzero
12823 ///
12824 /// Overflow and underflow:
12825 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12826 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12827 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12828 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12829 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12830 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12831 ///
12832 /// If you want to use a rounding mode other than `Nearest`, consider using
12833 /// [`Float::mul_add_mul_round`]. If you want to specify the output precision, consider using
12834 /// [`Float::mul_add_mul_prec`]. If you want both of these things, consider using
12835 /// [`Float::mul_add_mul_prec_round`].
12836 ///
12837 /// # Worst-case complexity
12838 /// $T(n, m) = O(n \log n \log\log n + m)$
12839 ///
12840 /// $M(n, m) = O(n \log n + m)$
12841 ///
12842 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12843 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12844 /// `self.significant_bits()`.
12845 ///
12846 /// # Examples
12847 /// ```
12848 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12849 /// use malachite_base::num::arithmetic::traits::MulAddMul;
12850 /// use malachite_float::Float;
12851 ///
12852 /// let x = Float::from(PI);
12853 /// let y = Float::from(E);
12854 /// let z = Float::from(SQRT_2);
12855 /// let w = Float::from(LN_2);
12856 /// assert_eq!(&x.mul_add_mul(&y, &z, &w).to_string(), "9.5199923661421142");
12857 /// ```
12858 #[inline]
12859 fn mul_add_mul(self, y: &Float, z: &Float, w: &Float) -> Float {
12860 let prec = max!(
12861 self.significant_bits(),
12862 y.significant_bits(),
12863 z.significant_bits(),
12864 w.significant_bits()
12865 );
12866 self.mul_add_mul_prec_ref_ref_ref_ref(y, z, w, prec).0
12867 }
12868}
12869
12870impl MulAddMulAssign<Self, Self, Self> for Float {
12871 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
12872 /// [`Float`]s, with a single rounding. The [`Float`]s on the right-hand side are all taken by
12873 /// value.
12874 ///
12875 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
12876 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
12877 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
12878 /// rounding mode.
12879 ///
12880 /// $$
12881 /// x \gets xy+zw+\varepsilon.
12882 /// $$
12883 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12884 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12885 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12886 ///
12887 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
12888 /// overflow, and underflow.
12889 ///
12890 /// If you want to use a rounding mode other than `Nearest`, consider using
12891 /// [`Float::mul_add_mul_round_assign`]. If you want to specify the output precision, consider
12892 /// using [`Float::mul_add_mul_prec_assign`]. If you want both of these things, consider using
12893 /// [`Float::mul_add_mul_prec_round_assign`].
12894 ///
12895 /// # Worst-case complexity
12896 /// $T(n, m) = O(n \log n \log\log n + m)$
12897 ///
12898 /// $M(n, m) = O(n \log n + m)$
12899 ///
12900 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12901 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12902 /// `self.significant_bits()`.
12903 ///
12904 /// # Examples
12905 /// ```
12906 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12907 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
12908 /// use malachite_float::Float;
12909 ///
12910 /// let mut x = Float::from(PI);
12911 /// let y = Float::from(E);
12912 /// let z = Float::from(SQRT_2);
12913 /// let w = Float::from(LN_2);
12914 /// x.mul_add_mul_assign(y, z, w);
12915 /// assert_eq!(x.to_string(), "9.5199923661421142");
12916 /// ```
12917 #[inline]
12918 fn mul_add_mul_assign(&mut self, y: Self, z: Self, w: Self) {
12919 let prec = max!(
12920 self.significant_bits(),
12921 y.significant_bits(),
12922 z.significant_bits(),
12923 w.significant_bits()
12924 );
12925 self.mul_add_mul_prec_assign(y, z, w, prec);
12926 }
12927}
12928
12929impl MulAddMulAssign<Self, Self, &Self> for Float {
12930 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
12931 /// [`Float`]s, with a single rounding. The last [`Float`] on the right-hand side is taken by
12932 /// reference and the others by value.
12933 ///
12934 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
12935 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
12936 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
12937 /// rounding mode.
12938 ///
12939 /// $$
12940 /// x \gets xy+zw+\varepsilon.
12941 /// $$
12942 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12943 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12944 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12945 ///
12946 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
12947 /// overflow, and underflow.
12948 ///
12949 /// If you want to use a rounding mode other than `Nearest`, consider using
12950 /// [`Float::mul_add_mul_round_assign`]. If you want to specify the output precision, consider
12951 /// using [`Float::mul_add_mul_prec_assign`]. If you want both of these things, consider using
12952 /// [`Float::mul_add_mul_prec_round_assign`].
12953 ///
12954 /// # Worst-case complexity
12955 /// $T(n, m) = O(n \log n \log\log n + m)$
12956 ///
12957 /// $M(n, m) = O(n \log n + m)$
12958 ///
12959 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12960 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12961 /// `self.significant_bits()`.
12962 ///
12963 /// # Examples
12964 /// ```
12965 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12966 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
12967 /// use malachite_float::Float;
12968 ///
12969 /// let mut x = Float::from(PI);
12970 /// let y = Float::from(E);
12971 /// let z = Float::from(SQRT_2);
12972 /// let w = Float::from(LN_2);
12973 /// x.mul_add_mul_assign(y, z, &w);
12974 /// assert_eq!(x.to_string(), "9.5199923661421142");
12975 /// ```
12976 #[inline]
12977 fn mul_add_mul_assign(&mut self, y: Self, z: Self, w: &Self) {
12978 let prec = max!(
12979 self.significant_bits(),
12980 y.significant_bits(),
12981 z.significant_bits(),
12982 w.significant_bits()
12983 );
12984 self.mul_add_mul_prec_assign_val_val_ref(y, z, w, prec);
12985 }
12986}
12987
12988impl MulAddMulAssign<Self, &Self, Self> for Float {
12989 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
12990 /// [`Float`]s, with a single rounding. The middle [`Float`] on the right-hand side is taken by
12991 /// reference and the others by value.
12992 ///
12993 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
12994 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
12995 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
12996 /// rounding mode.
12997 ///
12998 /// $$
12999 /// x \gets xy+zw+\varepsilon.
13000 /// $$
13001 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
13002 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
13003 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
13004 ///
13005 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
13006 /// overflow, and underflow.
13007 ///
13008 /// If you want to use a rounding mode other than `Nearest`, consider using
13009 /// [`Float::mul_add_mul_round_assign`]. If you want to specify the output precision, consider
13010 /// using [`Float::mul_add_mul_prec_assign`]. If you want both of these things, consider using
13011 /// [`Float::mul_add_mul_prec_round_assign`].
13012 ///
13013 /// # Worst-case complexity
13014 /// $T(n, m) = O(n \log n \log\log n + m)$
13015 ///
13016 /// $M(n, m) = O(n \log n + m)$
13017 ///
13018 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
13019 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
13020 /// `self.significant_bits()`.
13021 ///
13022 /// # Examples
13023 /// ```
13024 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
13025 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
13026 /// use malachite_float::Float;
13027 ///
13028 /// let mut x = Float::from(PI);
13029 /// let y = Float::from(E);
13030 /// let z = Float::from(SQRT_2);
13031 /// let w = Float::from(LN_2);
13032 /// x.mul_add_mul_assign(y, &z, w);
13033 /// assert_eq!(x.to_string(), "9.5199923661421142");
13034 /// ```
13035 #[inline]
13036 fn mul_add_mul_assign(&mut self, y: Self, z: &Self, w: Self) {
13037 let prec = max!(
13038 self.significant_bits(),
13039 y.significant_bits(),
13040 z.significant_bits(),
13041 w.significant_bits()
13042 );
13043 self.mul_add_mul_prec_assign_val_ref_val(y, z, w, prec);
13044 }
13045}
13046
13047impl MulAddMulAssign<Self, &Self, &Self> for Float {
13048 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
13049 /// [`Float`]s, with a single rounding. The first [`Float`] on the right-hand side is taken by
13050 /// value and the others by reference.
13051 ///
13052 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
13053 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
13054 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
13055 /// rounding mode.
13056 ///
13057 /// $$
13058 /// x \gets xy+zw+\varepsilon.
13059 /// $$
13060 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
13061 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
13062 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
13063 ///
13064 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
13065 /// overflow, and underflow.
13066 ///
13067 /// If you want to use a rounding mode other than `Nearest`, consider using
13068 /// [`Float::mul_add_mul_round_assign`]. If you want to specify the output precision, consider
13069 /// using [`Float::mul_add_mul_prec_assign`]. If you want both of these things, consider using
13070 /// [`Float::mul_add_mul_prec_round_assign`].
13071 ///
13072 /// # Worst-case complexity
13073 /// $T(n, m) = O(n \log n \log\log n + m)$
13074 ///
13075 /// $M(n, m) = O(n \log n + m)$
13076 ///
13077 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
13078 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
13079 /// `self.significant_bits()`.
13080 ///
13081 /// # Examples
13082 /// ```
13083 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
13084 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
13085 /// use malachite_float::Float;
13086 ///
13087 /// let mut x = Float::from(PI);
13088 /// let y = Float::from(E);
13089 /// let z = Float::from(SQRT_2);
13090 /// let w = Float::from(LN_2);
13091 /// x.mul_add_mul_assign(y, &z, &w);
13092 /// assert_eq!(x.to_string(), "9.5199923661421142");
13093 /// ```
13094 #[inline]
13095 fn mul_add_mul_assign(&mut self, y: Self, z: &Self, w: &Self) {
13096 let prec = max!(
13097 self.significant_bits(),
13098 y.significant_bits(),
13099 z.significant_bits(),
13100 w.significant_bits()
13101 );
13102 self.mul_add_mul_prec_assign_val_ref_ref(y, z, w, prec);
13103 }
13104}
13105
13106impl MulAddMulAssign<&Self, Self, Self> for Float {
13107 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
13108 /// [`Float`]s, with a single rounding. The first [`Float`] on the right-hand side is taken by
13109 /// reference and the others by value.
13110 ///
13111 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
13112 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
13113 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
13114 /// rounding mode.
13115 ///
13116 /// $$
13117 /// x \gets xy+zw+\varepsilon.
13118 /// $$
13119 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
13120 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
13121 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
13122 ///
13123 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
13124 /// overflow, and underflow.
13125 ///
13126 /// If you want to use a rounding mode other than `Nearest`, consider using
13127 /// [`Float::mul_add_mul_round_assign`]. If you want to specify the output precision, consider
13128 /// using [`Float::mul_add_mul_prec_assign`]. If you want both of these things, consider using
13129 /// [`Float::mul_add_mul_prec_round_assign`].
13130 ///
13131 /// # Worst-case complexity
13132 /// $T(n, m) = O(n \log n \log\log n + m)$
13133 ///
13134 /// $M(n, m) = O(n \log n + m)$
13135 ///
13136 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
13137 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
13138 /// `self.significant_bits()`.
13139 ///
13140 /// # Examples
13141 /// ```
13142 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
13143 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
13144 /// use malachite_float::Float;
13145 ///
13146 /// let mut x = Float::from(PI);
13147 /// let y = Float::from(E);
13148 /// let z = Float::from(SQRT_2);
13149 /// let w = Float::from(LN_2);
13150 /// x.mul_add_mul_assign(&y, z, w);
13151 /// assert_eq!(x.to_string(), "9.5199923661421142");
13152 /// ```
13153 #[inline]
13154 fn mul_add_mul_assign(&mut self, y: &Self, z: Self, w: Self) {
13155 let prec = max!(
13156 self.significant_bits(),
13157 y.significant_bits(),
13158 z.significant_bits(),
13159 w.significant_bits()
13160 );
13161 self.mul_add_mul_prec_assign_ref_val_val(y, z, w, prec);
13162 }
13163}
13164
13165impl MulAddMulAssign<&Self, Self, &Self> for Float {
13166 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
13167 /// [`Float`]s, with a single rounding. The middle [`Float`] on the right-hand side is taken by
13168 /// value and the others by reference.
13169 ///
13170 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
13171 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
13172 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
13173 /// rounding mode.
13174 ///
13175 /// $$
13176 /// x \gets xy+zw+\varepsilon.
13177 /// $$
13178 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
13179 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
13180 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
13181 ///
13182 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
13183 /// overflow, and underflow.
13184 ///
13185 /// If you want to use a rounding mode other than `Nearest`, consider using
13186 /// [`Float::mul_add_mul_round_assign`]. If you want to specify the output precision, consider
13187 /// using [`Float::mul_add_mul_prec_assign`]. If you want both of these things, consider using
13188 /// [`Float::mul_add_mul_prec_round_assign`].
13189 ///
13190 /// # Worst-case complexity
13191 /// $T(n, m) = O(n \log n \log\log n + m)$
13192 ///
13193 /// $M(n, m) = O(n \log n + m)$
13194 ///
13195 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
13196 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
13197 /// `self.significant_bits()`.
13198 ///
13199 /// # Examples
13200 /// ```
13201 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
13202 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
13203 /// use malachite_float::Float;
13204 ///
13205 /// let mut x = Float::from(PI);
13206 /// let y = Float::from(E);
13207 /// let z = Float::from(SQRT_2);
13208 /// let w = Float::from(LN_2);
13209 /// x.mul_add_mul_assign(&y, z, &w);
13210 /// assert_eq!(x.to_string(), "9.5199923661421142");
13211 /// ```
13212 #[inline]
13213 fn mul_add_mul_assign(&mut self, y: &Self, z: Self, w: &Self) {
13214 let prec = max!(
13215 self.significant_bits(),
13216 y.significant_bits(),
13217 z.significant_bits(),
13218 w.significant_bits()
13219 );
13220 self.mul_add_mul_prec_assign_ref_val_ref(y, z, w, prec);
13221 }
13222}
13223
13224impl MulAddMulAssign<&Self, &Self, Self> for Float {
13225 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
13226 /// [`Float`]s, with a single rounding. The last [`Float`] on the right-hand side is taken by
13227 /// value and the others by reference.
13228 ///
13229 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
13230 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
13231 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
13232 /// rounding mode.
13233 ///
13234 /// $$
13235 /// x \gets xy+zw+\varepsilon.
13236 /// $$
13237 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
13238 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
13239 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
13240 ///
13241 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
13242 /// overflow, and underflow.
13243 ///
13244 /// If you want to use a rounding mode other than `Nearest`, consider using
13245 /// [`Float::mul_add_mul_round_assign`]. If you want to specify the output precision, consider
13246 /// using [`Float::mul_add_mul_prec_assign`]. If you want both of these things, consider using
13247 /// [`Float::mul_add_mul_prec_round_assign`].
13248 ///
13249 /// # Worst-case complexity
13250 /// $T(n, m) = O(n \log n \log\log n + m)$
13251 ///
13252 /// $M(n, m) = O(n \log n + m)$
13253 ///
13254 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
13255 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
13256 /// `self.significant_bits()`.
13257 ///
13258 /// # Examples
13259 /// ```
13260 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
13261 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
13262 /// use malachite_float::Float;
13263 ///
13264 /// let mut x = Float::from(PI);
13265 /// let y = Float::from(E);
13266 /// let z = Float::from(SQRT_2);
13267 /// let w = Float::from(LN_2);
13268 /// x.mul_add_mul_assign(&y, &z, w);
13269 /// assert_eq!(x.to_string(), "9.5199923661421142");
13270 /// ```
13271 #[inline]
13272 fn mul_add_mul_assign(&mut self, y: &Self, z: &Self, w: Self) {
13273 let prec = max!(
13274 self.significant_bits(),
13275 y.significant_bits(),
13276 z.significant_bits(),
13277 w.significant_bits()
13278 );
13279 self.mul_add_mul_prec_assign_ref_ref_val(y, z, w, prec);
13280 }
13281}
13282
13283impl MulAddMulAssign<&Self, &Self, &Self> for Float {
13284 /// Multiplies a [`Float`] by another [`Float`] in place and adds the product of two more
13285 /// [`Float`]s, with a single rounding. The [`Float`]s on the right-hand side are all taken by
13286 /// reference.
13287 ///
13288 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the sum
13289 /// is equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s
13290 /// in its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
13291 /// rounding mode.
13292 ///
13293 /// $$
13294 /// x \gets xy+zw+\varepsilon.
13295 /// $$
13296 /// - If $xy+zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
13297 /// - If $xy+zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
13298 /// |xy+zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
13299 ///
13300 /// See the [`Float::mul_add_mul_prec_round`] documentation for information on special cases,
13301 /// overflow, and underflow.
13302 ///
13303 /// If you want to use a rounding mode other than `Nearest`, consider using
13304 /// [`Float::mul_add_mul_round_assign`]. If you want to specify the output precision, consider
13305 /// using [`Float::mul_add_mul_prec_assign`]. If you want both of these things, consider using
13306 /// [`Float::mul_add_mul_prec_round_assign`].
13307 ///
13308 /// # Worst-case complexity
13309 /// $T(n, m) = O(n \log n \log\log n + m)$
13310 ///
13311 /// $M(n, m) = O(n \log n + m)$
13312 ///
13313 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
13314 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
13315 /// `self.significant_bits()`.
13316 ///
13317 /// # Examples
13318 /// ```
13319 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
13320 /// use malachite_base::num::arithmetic::traits::MulAddMulAssign;
13321 /// use malachite_float::Float;
13322 ///
13323 /// let mut x = Float::from(PI);
13324 /// let y = Float::from(E);
13325 /// let z = Float::from(SQRT_2);
13326 /// let w = Float::from(LN_2);
13327 /// x.mul_add_mul_assign(&y, &z, &w);
13328 /// assert_eq!(x.to_string(), "9.5199923661421142");
13329 /// ```
13330 #[inline]
13331 fn mul_add_mul_assign(&mut self, y: &Self, z: &Self, w: &Self) {
13332 let prec = max!(
13333 self.significant_bits(),
13334 y.significant_bits(),
13335 z.significant_bits(),
13336 w.significant_bits()
13337 );
13338 self.mul_add_mul_prec_assign_ref_ref_ref(y, z, w, prec);
13339 }
13340}
13341
13342/// Adds the products of two pairs of primitive floats with a single rounding, using emulated
13343/// [`Float`] arithmetic.
13344///
13345/// The products are not rounded before the addition, so the result is the true value of $xy+zw$
13346/// rounded once to the nearest representable value. No standard-library counterpart exists.
13347///
13348/// # Worst-case complexity
13349/// Constant time and additional memory.
13350///
13351/// # Examples
13352/// ```
13353/// use core::f64::consts::{E, LN_2, PI, SQRT_2};
13354/// use malachite_base::num::float::NiceFloat;
13355/// use malachite_float::float::arithmetic::mul_add_mul::*;
13356///
13357/// assert_eq!(
13358/// NiceFloat(primitive_float_mul_add_mul(PI, E, SQRT_2, LN_2)),
13359/// NiceFloat(9.519992366142114)
13360/// );
13361/// ```
13362#[allow(clippy::type_repetition_in_bounds)]
13363#[inline]
13364pub fn primitive_float_mul_add_mul<T: PrimitiveFloat>(x: T, y: T, z: T, w: T) -> T
13365where
13366 Float: From<T> + PartialOrd<T>,
13367 for<'a> T: ExactFrom<&'a Float>,
13368{
13369 emulate_float_float_float_float_to_float_fn(Float::mul_add_mul_prec, x, y, z, w)
13370}
13371
13372/// Adds the product of two primitive floats and the product of a primitive float and a
13373/// [`Rational`], with a single rounding, using emulated [`Float`] arithmetic.
13374///
13375/// The [`Rational`] enters its product exactly, the products are not rounded before the addition,
13376/// and the result is the true value of $xy+zw$ rounded once to the nearest representable value.
13377///
13378/// # Worst-case complexity
13379/// $T(n) = O(n \log n \log\log n)$
13380///
13381/// $M(n) = O(n \log n)$
13382///
13383/// where $T$ is time, $M$ is additional memory, and $n$ is `w.significant_bits()`.
13384///
13385/// # Examples
13386/// ```
13387/// use core::f64::consts::{E, PI, SQRT_2};
13388/// use malachite_base::num::float::NiceFloat;
13389/// use malachite_float::float::arithmetic::mul_add_mul::*;
13390/// use malachite_q::Rational;
13391///
13392/// assert_eq!(
13393/// NiceFloat(primitive_float_mul_add_mul_rational(
13394/// PI,
13395/// E,
13396/// SQRT_2,
13397/// &Rational::from_signeds(1, 3)
13398/// )),
13399/// NiceFloat(9.011138743464597)
13400/// );
13401/// ```
13402#[allow(clippy::type_repetition_in_bounds)]
13403#[inline]
13404pub fn primitive_float_mul_add_mul_rational<T: PrimitiveFloat>(x: T, y: T, z: T, w: &Rational) -> T
13405where
13406 Float: From<T> + PartialOrd<T>,
13407 for<'a> T: ExactFrom<&'a Float>,
13408{
13409 emulate_float_float_float_to_float_fn(
13410 |x, y, z, prec| x.mul_add_mul_rational_prec_val_val_val_ref(y, z, w, prec),
13411 x,
13412 y,
13413 z,
13414 )
13415}