malachite_float/float/arithmetic/mul_sub_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::float::arithmetic::mul_add_mul::{mul_add_mul_helper, mul_add_mul_rational_helper};
14use crate::{
15 Float, emulate_float_float_float_float_to_float_fn, emulate_float_float_float_to_float_fn,
16};
17use core::cmp::Ordering;
18use malachite_base::max;
19use malachite_base::num::arithmetic::traits::{MulSubMul, MulSubMulAssign};
20use malachite_base::num::basic::floats::PrimitiveFloat;
21use malachite_base::num::conversion::traits::ExactFrom;
22use malachite_base::num::logic::traits::SignificantBits;
23use malachite_base::rounding_modes::RoundingMode::{self, Nearest};
24use malachite_q::Rational;
25
26// This is mpfr_fms from fmma.c, MPFR 4.2.2: mul_sub_mul computes a * b - c * d, which is mpfr_fmms
27// exactly -- unlike sub_mul, no sign convention differs between the two libraries.
28impl Float {
29 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
30 /// the result to the specified precision and with the specified rounding mode; the products are
31 /// not rounded before the final subtraction, so there is a single rounding. All four [`Float`]s
32 /// are taken by value. An [`Ordering`] is also returned, indicating whether the rounded diff is
33 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
34 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
35 ///
36 /// See [`RoundingMode`] for a description of the possible rounding modes.
37 ///
38 /// $$
39 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
40 /// $$
41 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
42 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
43 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
44 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
45 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
46 ///
47 /// If the output has a precision, it is `prec`.
48 ///
49 /// Special cases:
50 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
51 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
52 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
53 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
54 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
55 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
56 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
57 /// - If exactly one product is infinite, the result is that product's infinity, the second
58 /// product's sign counting as flipped.
59 /// - If both products are infinite, the result is their common infinity if their signs differ,
60 /// and `NaN` otherwise.
61 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
62 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
63 /// `Floor`
64 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
65 ///
66 /// Overflow and underflow:
67 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
68 /// returned instead.
69 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
70 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
71 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
72 /// returned instead.
73 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
74 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
75 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
76 /// instead.
77 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
78 /// instead.
79 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
80 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
81 /// returned instead.
82 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
83 /// instead.
84 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
85 /// instead.
86 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
87 /// instead.
88 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
89 /// returned instead.
90 ///
91 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec`] instead.
92 /// If you know that your target precision is the maximum of the precisions of the inputs,
93 /// consider using [`Float::mul_sub_mul_round`] instead. If both of these things are true,
94 /// consider using
95 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
96 ///
97 /// # Worst-case complexity
98 /// $T(n, m) = O(n \log n \log\log n + m)$
99 ///
100 /// $M(n, m) = O(n \log n + m)$
101 ///
102 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
103 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
104 /// `max(self.significant_bits(), prec)`.
105 ///
106 /// # Panics
107 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
108 /// representable with `prec` bits.
109 ///
110 /// # Examples
111 /// ```
112 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
113 /// use malachite_base::rounding_modes::RoundingMode::*;
114 /// use malachite_float::Float;
115 /// use std::cmp::Ordering::*;
116 ///
117 /// let x = Float::from(PI);
118 /// let y = Float::from(E);
119 /// let z = Float::from(SQRT_2);
120 /// let w = Float::from(LN_2);
121 ///
122 /// let (diff, o) = x
123 /// .clone()
124 /// .mul_sub_mul_prec_round(y.clone(), z.clone(), w.clone(), 5, Floor);
125 /// assert_eq!(diff.to_string(), "7.50");
126 /// assert_eq!(o, Less);
127 ///
128 /// let (diff, o) =
129 /// x.clone()
130 /// .mul_sub_mul_prec_round(y.clone(), z.clone(), w.clone(), 5, Ceiling);
131 /// assert_eq!(diff.to_string(), "7.75");
132 /// assert_eq!(o, Greater);
133 ///
134 /// let (diff, o) =
135 /// x.clone()
136 /// .mul_sub_mul_prec_round(y.clone(), z.clone(), w.clone(), 5, Nearest);
137 /// assert_eq!(diff.to_string(), "7.50");
138 /// assert_eq!(o, Less);
139 ///
140 /// let (diff, o) =
141 /// x.clone()
142 /// .mul_sub_mul_prec_round(y.clone(), z.clone(), w.clone(), 20, Floor);
143 /// assert_eq!(diff.to_string(), "7.5594711");
144 /// assert_eq!(o, Less);
145 ///
146 /// let (diff, o) =
147 /// x.clone()
148 /// .mul_sub_mul_prec_round(y.clone(), z.clone(), w.clone(), 20, Ceiling);
149 /// assert_eq!(diff.to_string(), "7.5594788");
150 /// assert_eq!(o, Greater);
151 ///
152 /// let (diff, o) =
153 /// x.clone()
154 /// .mul_sub_mul_prec_round(y.clone(), z.clone(), w.clone(), 20, Nearest);
155 /// assert_eq!(diff.to_string(), "7.5594788");
156 /// assert_eq!(o, Greater);
157 /// ```
158 #[allow(clippy::needless_pass_by_value)]
159 #[inline]
160 pub fn mul_sub_mul_prec_round(
161 self,
162 y: Self,
163 z: Self,
164 w: Self,
165 prec: u64,
166 rm: RoundingMode,
167 ) -> (Self, Ordering) {
168 mul_add_mul_helper(&self, &y, &z, &w, true, prec, rm)
169 }
170
171 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
172 /// the result to the specified precision and with the specified rounding mode; the products are
173 /// not rounded before the final subtraction, so there is a single rounding. The first three
174 /// [`Float`]s are taken by value and the fourth by reference. An [`Ordering`] is also returned,
175 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
176 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
177 /// it also returns `Equal`.
178 ///
179 /// See [`RoundingMode`] for a description of the possible rounding modes.
180 ///
181 /// $$
182 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
183 /// $$
184 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
185 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
186 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
187 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
188 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
189 ///
190 /// If the output has a precision, it is `prec`.
191 ///
192 /// Special cases:
193 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
194 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
195 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
196 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
197 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
198 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
199 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
200 /// - If exactly one product is infinite, the result is that product's infinity, the second
201 /// product's sign counting as flipped.
202 /// - If both products are infinite, the result is their common infinity if their signs differ,
203 /// and `NaN` otherwise.
204 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
205 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
206 /// `Floor`
207 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
208 ///
209 /// Overflow and underflow:
210 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
211 /// returned instead.
212 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
213 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
214 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
215 /// returned instead.
216 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
217 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
218 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
219 /// instead.
220 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
221 /// instead.
222 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
223 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
224 /// returned instead.
225 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
226 /// instead.
227 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
228 /// instead.
229 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
230 /// instead.
231 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
232 /// returned instead.
233 ///
234 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec`] instead.
235 /// If you know that your target precision is the maximum of the precisions of the inputs,
236 /// consider using [`Float::mul_sub_mul_round`] instead. If both of these things are true,
237 /// consider using
238 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
239 ///
240 /// # Worst-case complexity
241 /// $T(n, m) = O(n \log n \log\log n + m)$
242 ///
243 /// $M(n, m) = O(n \log n + m)$
244 ///
245 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
246 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
247 /// `max(self.significant_bits(), prec)`.
248 ///
249 /// # Panics
250 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
251 /// representable with `prec` bits.
252 ///
253 /// # Examples
254 /// ```
255 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
256 /// use malachite_base::rounding_modes::RoundingMode::*;
257 /// use malachite_float::Float;
258 /// use std::cmp::Ordering::*;
259 ///
260 /// let x = Float::from(PI);
261 /// let y = Float::from(E);
262 /// let z = Float::from(SQRT_2);
263 /// let w = Float::from(LN_2);
264 ///
265 /// let (diff, o) =
266 /// x.clone()
267 /// .mul_sub_mul_prec_round_val_val_val_ref(y.clone(), z.clone(), &w, 5, Floor);
268 /// assert_eq!(diff.to_string(), "7.50");
269 /// assert_eq!(o, Less);
270 ///
271 /// let (diff, o) =
272 /// x.clone()
273 /// .mul_sub_mul_prec_round_val_val_val_ref(y.clone(), z.clone(), &w, 5, Ceiling);
274 /// assert_eq!(diff.to_string(), "7.75");
275 /// assert_eq!(o, Greater);
276 ///
277 /// let (diff, o) =
278 /// x.clone()
279 /// .mul_sub_mul_prec_round_val_val_val_ref(y.clone(), z.clone(), &w, 5, Nearest);
280 /// assert_eq!(diff.to_string(), "7.50");
281 /// assert_eq!(o, Less);
282 ///
283 /// let (diff, o) =
284 /// x.clone()
285 /// .mul_sub_mul_prec_round_val_val_val_ref(y.clone(), z.clone(), &w, 20, Floor);
286 /// assert_eq!(diff.to_string(), "7.5594711");
287 /// assert_eq!(o, Less);
288 ///
289 /// let (diff, o) =
290 /// x.clone()
291 /// .mul_sub_mul_prec_round_val_val_val_ref(y.clone(), z.clone(), &w, 20, Ceiling);
292 /// assert_eq!(diff.to_string(), "7.5594788");
293 /// assert_eq!(o, Greater);
294 ///
295 /// let (diff, o) =
296 /// x.clone()
297 /// .mul_sub_mul_prec_round_val_val_val_ref(y.clone(), z.clone(), &w, 20, Nearest);
298 /// assert_eq!(diff.to_string(), "7.5594788");
299 /// assert_eq!(o, Greater);
300 /// ```
301 #[allow(clippy::needless_pass_by_value)]
302 #[inline]
303 pub fn mul_sub_mul_prec_round_val_val_val_ref(
304 self,
305 y: Self,
306 z: Self,
307 w: &Self,
308 prec: u64,
309 rm: RoundingMode,
310 ) -> (Self, Ordering) {
311 mul_add_mul_helper(&self, &y, &z, w, true, prec, rm)
312 }
313
314 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
315 /// the result to the specified precision and with the specified rounding mode; the products are
316 /// not rounded before the final subtraction, so there is a single rounding. The third [`Float`]
317 /// is taken by reference and the others by value. An [`Ordering`] is also returned, indicating
318 /// whether the rounded diff is less than, equal to, or greater than the exact diff. Although
319 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
320 /// returns `Equal`.
321 ///
322 /// See [`RoundingMode`] for a description of the possible rounding modes.
323 ///
324 /// $$
325 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
326 /// $$
327 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
328 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
329 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
330 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
331 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
332 ///
333 /// If the output has a precision, it is `prec`.
334 ///
335 /// Special cases:
336 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
337 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
338 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
339 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
340 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
341 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
342 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
343 /// - If exactly one product is infinite, the result is that product's infinity, the second
344 /// product's sign counting as flipped.
345 /// - If both products are infinite, the result is their common infinity if their signs differ,
346 /// and `NaN` otherwise.
347 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
348 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
349 /// `Floor`
350 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
351 ///
352 /// Overflow and underflow:
353 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
354 /// returned instead.
355 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
356 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
357 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
358 /// returned instead.
359 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
360 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
361 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
362 /// instead.
363 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
364 /// instead.
365 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
366 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
367 /// returned instead.
368 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
369 /// instead.
370 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
371 /// instead.
372 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
373 /// instead.
374 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
375 /// returned instead.
376 ///
377 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec`] instead.
378 /// If you know that your target precision is the maximum of the precisions of the inputs,
379 /// consider using [`Float::mul_sub_mul_round`] instead. If both of these things are true,
380 /// consider using
381 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
382 ///
383 /// # Worst-case complexity
384 /// $T(n, m) = O(n \log n \log\log n + m)$
385 ///
386 /// $M(n, m) = O(n \log n + m)$
387 ///
388 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
389 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
390 /// `max(self.significant_bits(), prec)`.
391 ///
392 /// # Panics
393 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
394 /// representable with `prec` bits.
395 ///
396 /// # Examples
397 /// ```
398 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
399 /// use malachite_base::rounding_modes::RoundingMode::*;
400 /// use malachite_float::Float;
401 /// use std::cmp::Ordering::*;
402 ///
403 /// let x = Float::from(PI);
404 /// let y = Float::from(E);
405 /// let z = Float::from(SQRT_2);
406 /// let w = Float::from(LN_2);
407 ///
408 /// let (diff, o) =
409 /// x.clone()
410 /// .mul_sub_mul_prec_round_val_val_ref_val(y.clone(), &z, w.clone(), 5, Floor);
411 /// assert_eq!(diff.to_string(), "7.50");
412 /// assert_eq!(o, Less);
413 ///
414 /// let (diff, o) =
415 /// x.clone()
416 /// .mul_sub_mul_prec_round_val_val_ref_val(y.clone(), &z, w.clone(), 5, Ceiling);
417 /// assert_eq!(diff.to_string(), "7.75");
418 /// assert_eq!(o, Greater);
419 ///
420 /// let (diff, o) =
421 /// x.clone()
422 /// .mul_sub_mul_prec_round_val_val_ref_val(y.clone(), &z, w.clone(), 5, Nearest);
423 /// assert_eq!(diff.to_string(), "7.50");
424 /// assert_eq!(o, Less);
425 ///
426 /// let (diff, o) =
427 /// x.clone()
428 /// .mul_sub_mul_prec_round_val_val_ref_val(y.clone(), &z, w.clone(), 20, Floor);
429 /// assert_eq!(diff.to_string(), "7.5594711");
430 /// assert_eq!(o, Less);
431 ///
432 /// let (diff, o) =
433 /// x.clone()
434 /// .mul_sub_mul_prec_round_val_val_ref_val(y.clone(), &z, w.clone(), 20, Ceiling);
435 /// assert_eq!(diff.to_string(), "7.5594788");
436 /// assert_eq!(o, Greater);
437 ///
438 /// let (diff, o) =
439 /// x.clone()
440 /// .mul_sub_mul_prec_round_val_val_ref_val(y.clone(), &z, w.clone(), 20, Nearest);
441 /// assert_eq!(diff.to_string(), "7.5594788");
442 /// assert_eq!(o, Greater);
443 /// ```
444 #[allow(clippy::needless_pass_by_value)]
445 #[inline]
446 pub fn mul_sub_mul_prec_round_val_val_ref_val(
447 self,
448 y: Self,
449 z: &Self,
450 w: Self,
451 prec: u64,
452 rm: RoundingMode,
453 ) -> (Self, Ordering) {
454 mul_add_mul_helper(&self, &y, z, &w, true, prec, rm)
455 }
456
457 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
458 /// the result to the specified precision and with the specified rounding mode; the products are
459 /// not rounded before the final subtraction, so there is a single rounding. The first two
460 /// [`Float`]s are taken by value and the last two by reference. An [`Ordering`] is also
461 /// returned, indicating whether the rounded diff is less than, equal to, or greater than the
462 /// exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
463 /// returns a `NaN` it also returns `Equal`.
464 ///
465 /// See [`RoundingMode`] for a description of the possible rounding modes.
466 ///
467 /// $$
468 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
469 /// $$
470 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
471 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
472 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
473 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
474 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
475 ///
476 /// If the output has a precision, it is `prec`.
477 ///
478 /// Special cases:
479 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
480 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
481 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
482 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
483 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
484 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
485 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
486 /// - If exactly one product is infinite, the result is that product's infinity, the second
487 /// product's sign counting as flipped.
488 /// - If both products are infinite, the result is their common infinity if their signs differ,
489 /// and `NaN` otherwise.
490 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
491 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
492 /// `Floor`
493 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
494 ///
495 /// Overflow and underflow:
496 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
497 /// returned instead.
498 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
499 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
500 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
501 /// returned instead.
502 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
503 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
504 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
505 /// instead.
506 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
507 /// instead.
508 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
509 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
510 /// returned instead.
511 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
512 /// instead.
513 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
514 /// instead.
515 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
516 /// instead.
517 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
518 /// returned instead.
519 ///
520 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec`] instead.
521 /// If you know that your target precision is the maximum of the precisions of the inputs,
522 /// consider using [`Float::mul_sub_mul_round`] instead. If both of these things are true,
523 /// consider using
524 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
525 ///
526 /// # Worst-case complexity
527 /// $T(n, m) = O(n \log n \log\log n + m)$
528 ///
529 /// $M(n, m) = O(n \log n + m)$
530 ///
531 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
532 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
533 /// `max(self.significant_bits(), prec)`.
534 ///
535 /// # Panics
536 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
537 /// representable with `prec` bits.
538 ///
539 /// # Examples
540 /// ```
541 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
542 /// use malachite_base::rounding_modes::RoundingMode::*;
543 /// use malachite_float::Float;
544 /// use std::cmp::Ordering::*;
545 ///
546 /// let x = Float::from(PI);
547 /// let y = Float::from(E);
548 /// let z = Float::from(SQRT_2);
549 /// let w = Float::from(LN_2);
550 ///
551 /// let (diff, o) =
552 /// x.clone()
553 /// .mul_sub_mul_prec_round_val_val_ref_ref(y.clone(), &z, &w, 5, Floor);
554 /// assert_eq!(diff.to_string(), "7.50");
555 /// assert_eq!(o, Less);
556 ///
557 /// let (diff, o) =
558 /// x.clone()
559 /// .mul_sub_mul_prec_round_val_val_ref_ref(y.clone(), &z, &w, 5, Ceiling);
560 /// assert_eq!(diff.to_string(), "7.75");
561 /// assert_eq!(o, Greater);
562 ///
563 /// let (diff, o) =
564 /// x.clone()
565 /// .mul_sub_mul_prec_round_val_val_ref_ref(y.clone(), &z, &w, 5, Nearest);
566 /// assert_eq!(diff.to_string(), "7.50");
567 /// assert_eq!(o, Less);
568 ///
569 /// let (diff, o) =
570 /// x.clone()
571 /// .mul_sub_mul_prec_round_val_val_ref_ref(y.clone(), &z, &w, 20, Floor);
572 /// assert_eq!(diff.to_string(), "7.5594711");
573 /// assert_eq!(o, Less);
574 ///
575 /// let (diff, o) =
576 /// x.clone()
577 /// .mul_sub_mul_prec_round_val_val_ref_ref(y.clone(), &z, &w, 20, Ceiling);
578 /// assert_eq!(diff.to_string(), "7.5594788");
579 /// assert_eq!(o, Greater);
580 ///
581 /// let (diff, o) =
582 /// x.clone()
583 /// .mul_sub_mul_prec_round_val_val_ref_ref(y.clone(), &z, &w, 20, Nearest);
584 /// assert_eq!(diff.to_string(), "7.5594788");
585 /// assert_eq!(o, Greater);
586 /// ```
587 #[allow(clippy::needless_pass_by_value)]
588 #[inline]
589 pub fn mul_sub_mul_prec_round_val_val_ref_ref(
590 self,
591 y: Self,
592 z: &Self,
593 w: &Self,
594 prec: u64,
595 rm: RoundingMode,
596 ) -> (Self, Ordering) {
597 mul_add_mul_helper(&self, &y, z, w, true, prec, rm)
598 }
599
600 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
601 /// the result to the specified precision and with the specified rounding mode; the products are
602 /// not rounded before the final subtraction, so there is a single rounding. The second
603 /// [`Float`] is taken by reference and the others by value. An [`Ordering`] is also returned,
604 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
605 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
606 /// it also returns `Equal`.
607 ///
608 /// See [`RoundingMode`] for a description of the possible rounding modes.
609 ///
610 /// $$
611 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
612 /// $$
613 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
614 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
615 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
616 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
617 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
618 ///
619 /// If the output has a precision, it is `prec`.
620 ///
621 /// Special cases:
622 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
623 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
624 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
625 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
626 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
627 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
628 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
629 /// - If exactly one product is infinite, the result is that product's infinity, the second
630 /// product's sign counting as flipped.
631 /// - If both products are infinite, the result is their common infinity if their signs differ,
632 /// and `NaN` otherwise.
633 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
634 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
635 /// `Floor`
636 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
637 ///
638 /// Overflow and underflow:
639 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
640 /// returned instead.
641 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
642 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
643 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
644 /// returned instead.
645 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
646 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
647 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
648 /// instead.
649 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
650 /// instead.
651 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
652 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
653 /// returned instead.
654 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
655 /// instead.
656 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
657 /// instead.
658 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
659 /// instead.
660 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
661 /// returned instead.
662 ///
663 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec`] instead.
664 /// If you know that your target precision is the maximum of the precisions of the inputs,
665 /// consider using [`Float::mul_sub_mul_round`] instead. If both of these things are true,
666 /// consider using
667 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
668 ///
669 /// # Worst-case complexity
670 /// $T(n, m) = O(n \log n \log\log n + m)$
671 ///
672 /// $M(n, m) = O(n \log n + m)$
673 ///
674 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
675 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
676 /// `max(self.significant_bits(), prec)`.
677 ///
678 /// # Panics
679 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
680 /// representable with `prec` bits.
681 ///
682 /// # Examples
683 /// ```
684 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
685 /// use malachite_base::rounding_modes::RoundingMode::*;
686 /// use malachite_float::Float;
687 /// use std::cmp::Ordering::*;
688 ///
689 /// let x = Float::from(PI);
690 /// let y = Float::from(E);
691 /// let z = Float::from(SQRT_2);
692 /// let w = Float::from(LN_2);
693 ///
694 /// let (diff, o) =
695 /// x.clone()
696 /// .mul_sub_mul_prec_round_val_ref_val_val(&y, z.clone(), w.clone(), 5, Floor);
697 /// assert_eq!(diff.to_string(), "7.50");
698 /// assert_eq!(o, Less);
699 ///
700 /// let (diff, o) =
701 /// x.clone()
702 /// .mul_sub_mul_prec_round_val_ref_val_val(&y, z.clone(), w.clone(), 5, Ceiling);
703 /// assert_eq!(diff.to_string(), "7.75");
704 /// assert_eq!(o, Greater);
705 ///
706 /// let (diff, o) =
707 /// x.clone()
708 /// .mul_sub_mul_prec_round_val_ref_val_val(&y, z.clone(), w.clone(), 5, Nearest);
709 /// assert_eq!(diff.to_string(), "7.50");
710 /// assert_eq!(o, Less);
711 ///
712 /// let (diff, o) =
713 /// x.clone()
714 /// .mul_sub_mul_prec_round_val_ref_val_val(&y, z.clone(), w.clone(), 20, Floor);
715 /// assert_eq!(diff.to_string(), "7.5594711");
716 /// assert_eq!(o, Less);
717 ///
718 /// let (diff, o) =
719 /// x.clone()
720 /// .mul_sub_mul_prec_round_val_ref_val_val(&y, z.clone(), w.clone(), 20, Ceiling);
721 /// assert_eq!(diff.to_string(), "7.5594788");
722 /// assert_eq!(o, Greater);
723 ///
724 /// let (diff, o) =
725 /// x.clone()
726 /// .mul_sub_mul_prec_round_val_ref_val_val(&y, z.clone(), w.clone(), 20, Nearest);
727 /// assert_eq!(diff.to_string(), "7.5594788");
728 /// assert_eq!(o, Greater);
729 /// ```
730 #[allow(clippy::needless_pass_by_value)]
731 #[inline]
732 pub fn mul_sub_mul_prec_round_val_ref_val_val(
733 self,
734 y: &Self,
735 z: Self,
736 w: Self,
737 prec: u64,
738 rm: RoundingMode,
739 ) -> (Self, Ordering) {
740 mul_add_mul_helper(&self, y, &z, &w, true, prec, rm)
741 }
742
743 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
744 /// the result to the specified precision and with the specified rounding mode; the products are
745 /// not rounded before the final subtraction, so there is a single rounding. The second and
746 /// fourth [`Float`]s are taken by reference and the others by value. An [`Ordering`] is also
747 /// returned, indicating whether the rounded diff is less than, equal to, or greater than the
748 /// exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
749 /// returns a `NaN` it also returns `Equal`.
750 ///
751 /// See [`RoundingMode`] for a description of the possible rounding modes.
752 ///
753 /// $$
754 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
755 /// $$
756 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
757 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
758 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
759 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
760 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
761 ///
762 /// If the output has a precision, it is `prec`.
763 ///
764 /// Special cases:
765 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
766 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
767 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
768 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
769 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
770 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
771 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
772 /// - If exactly one product is infinite, the result is that product's infinity, the second
773 /// product's sign counting as flipped.
774 /// - If both products are infinite, the result is their common infinity if their signs differ,
775 /// and `NaN` otherwise.
776 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
777 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
778 /// `Floor`
779 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
780 ///
781 /// Overflow and underflow:
782 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
783 /// returned instead.
784 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
785 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
786 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
787 /// returned instead.
788 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
789 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
790 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
791 /// instead.
792 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
793 /// instead.
794 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
795 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
796 /// returned instead.
797 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
798 /// instead.
799 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
800 /// instead.
801 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
802 /// instead.
803 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
804 /// returned instead.
805 ///
806 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec`] instead.
807 /// If you know that your target precision is the maximum of the precisions of the inputs,
808 /// consider using [`Float::mul_sub_mul_round`] instead. If both of these things are true,
809 /// consider using
810 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
811 ///
812 /// # Worst-case complexity
813 /// $T(n, m) = O(n \log n \log\log n + m)$
814 ///
815 /// $M(n, m) = O(n \log n + m)$
816 ///
817 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
818 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
819 /// `max(self.significant_bits(), prec)`.
820 ///
821 /// # Panics
822 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
823 /// representable with `prec` bits.
824 ///
825 /// # Examples
826 /// ```
827 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
828 /// use malachite_base::rounding_modes::RoundingMode::*;
829 /// use malachite_float::Float;
830 /// use std::cmp::Ordering::*;
831 ///
832 /// let x = Float::from(PI);
833 /// let y = Float::from(E);
834 /// let z = Float::from(SQRT_2);
835 /// let w = Float::from(LN_2);
836 ///
837 /// let (diff, o) =
838 /// x.clone()
839 /// .mul_sub_mul_prec_round_val_ref_val_ref(&y, z.clone(), &w, 5, Floor);
840 /// assert_eq!(diff.to_string(), "7.50");
841 /// assert_eq!(o, Less);
842 ///
843 /// let (diff, o) =
844 /// x.clone()
845 /// .mul_sub_mul_prec_round_val_ref_val_ref(&y, z.clone(), &w, 5, Ceiling);
846 /// assert_eq!(diff.to_string(), "7.75");
847 /// assert_eq!(o, Greater);
848 ///
849 /// let (diff, o) =
850 /// x.clone()
851 /// .mul_sub_mul_prec_round_val_ref_val_ref(&y, z.clone(), &w, 5, Nearest);
852 /// assert_eq!(diff.to_string(), "7.50");
853 /// assert_eq!(o, Less);
854 ///
855 /// let (diff, o) =
856 /// x.clone()
857 /// .mul_sub_mul_prec_round_val_ref_val_ref(&y, z.clone(), &w, 20, Floor);
858 /// assert_eq!(diff.to_string(), "7.5594711");
859 /// assert_eq!(o, Less);
860 ///
861 /// let (diff, o) =
862 /// x.clone()
863 /// .mul_sub_mul_prec_round_val_ref_val_ref(&y, z.clone(), &w, 20, Ceiling);
864 /// assert_eq!(diff.to_string(), "7.5594788");
865 /// assert_eq!(o, Greater);
866 ///
867 /// let (diff, o) =
868 /// x.clone()
869 /// .mul_sub_mul_prec_round_val_ref_val_ref(&y, z.clone(), &w, 20, Nearest);
870 /// assert_eq!(diff.to_string(), "7.5594788");
871 /// assert_eq!(o, Greater);
872 /// ```
873 #[allow(clippy::needless_pass_by_value)]
874 #[inline]
875 pub fn mul_sub_mul_prec_round_val_ref_val_ref(
876 self,
877 y: &Self,
878 z: Self,
879 w: &Self,
880 prec: u64,
881 rm: RoundingMode,
882 ) -> (Self, Ordering) {
883 mul_add_mul_helper(&self, y, &z, w, true, prec, rm)
884 }
885
886 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
887 /// the result to the specified precision and with the specified rounding mode; the products are
888 /// not rounded before the final subtraction, so there is a single rounding. The second and
889 /// third [`Float`]s are taken by reference and the others by value. An [`Ordering`] is also
890 /// returned, indicating whether the rounded diff is less than, equal to, or greater than the
891 /// exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
892 /// returns a `NaN` it also returns `Equal`.
893 ///
894 /// See [`RoundingMode`] for a description of the possible rounding modes.
895 ///
896 /// $$
897 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
898 /// $$
899 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
900 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
901 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
902 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
903 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
904 ///
905 /// If the output has a precision, it is `prec`.
906 ///
907 /// Special cases:
908 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
909 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
910 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
911 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
912 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
913 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
914 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
915 /// - If exactly one product is infinite, the result is that product's infinity, the second
916 /// product's sign counting as flipped.
917 /// - If both products are infinite, the result is their common infinity if their signs differ,
918 /// and `NaN` otherwise.
919 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
920 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
921 /// `Floor`
922 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
923 ///
924 /// Overflow and underflow:
925 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
926 /// returned instead.
927 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
928 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
929 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
930 /// returned instead.
931 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
932 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
933 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
934 /// instead.
935 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
936 /// instead.
937 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
938 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
939 /// returned instead.
940 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
941 /// instead.
942 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
943 /// instead.
944 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
945 /// instead.
946 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
947 /// returned instead.
948 ///
949 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec`] instead.
950 /// If you know that your target precision is the maximum of the precisions of the inputs,
951 /// consider using [`Float::mul_sub_mul_round`] instead. If both of these things are true,
952 /// consider using
953 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
954 ///
955 /// # Worst-case complexity
956 /// $T(n, m) = O(n \log n \log\log n + m)$
957 ///
958 /// $M(n, m) = O(n \log n + m)$
959 ///
960 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
961 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
962 /// `max(self.significant_bits(), prec)`.
963 ///
964 /// # Panics
965 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
966 /// representable with `prec` bits.
967 ///
968 /// # Examples
969 /// ```
970 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
971 /// use malachite_base::rounding_modes::RoundingMode::*;
972 /// use malachite_float::Float;
973 /// use std::cmp::Ordering::*;
974 ///
975 /// let x = Float::from(PI);
976 /// let y = Float::from(E);
977 /// let z = Float::from(SQRT_2);
978 /// let w = Float::from(LN_2);
979 ///
980 /// let (diff, o) =
981 /// x.clone()
982 /// .mul_sub_mul_prec_round_val_ref_ref_val(&y, &z, w.clone(), 5, Floor);
983 /// assert_eq!(diff.to_string(), "7.50");
984 /// assert_eq!(o, Less);
985 ///
986 /// let (diff, o) =
987 /// x.clone()
988 /// .mul_sub_mul_prec_round_val_ref_ref_val(&y, &z, w.clone(), 5, Ceiling);
989 /// assert_eq!(diff.to_string(), "7.75");
990 /// assert_eq!(o, Greater);
991 ///
992 /// let (diff, o) =
993 /// x.clone()
994 /// .mul_sub_mul_prec_round_val_ref_ref_val(&y, &z, w.clone(), 5, Nearest);
995 /// assert_eq!(diff.to_string(), "7.50");
996 /// assert_eq!(o, Less);
997 ///
998 /// let (diff, o) =
999 /// x.clone()
1000 /// .mul_sub_mul_prec_round_val_ref_ref_val(&y, &z, w.clone(), 20, Floor);
1001 /// assert_eq!(diff.to_string(), "7.5594711");
1002 /// assert_eq!(o, Less);
1003 ///
1004 /// let (diff, o) =
1005 /// x.clone()
1006 /// .mul_sub_mul_prec_round_val_ref_ref_val(&y, &z, w.clone(), 20, Ceiling);
1007 /// assert_eq!(diff.to_string(), "7.5594788");
1008 /// assert_eq!(o, Greater);
1009 ///
1010 /// let (diff, o) =
1011 /// x.clone()
1012 /// .mul_sub_mul_prec_round_val_ref_ref_val(&y, &z, w.clone(), 20, Nearest);
1013 /// assert_eq!(diff.to_string(), "7.5594788");
1014 /// assert_eq!(o, Greater);
1015 /// ```
1016 #[allow(clippy::needless_pass_by_value)]
1017 #[inline]
1018 pub fn mul_sub_mul_prec_round_val_ref_ref_val(
1019 self,
1020 y: &Self,
1021 z: &Self,
1022 w: Self,
1023 prec: u64,
1024 rm: RoundingMode,
1025 ) -> (Self, Ordering) {
1026 mul_add_mul_helper(&self, y, z, &w, true, prec, rm)
1027 }
1028
1029 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
1030 /// the result to the specified precision and with the specified rounding mode; the products are
1031 /// not rounded before the final subtraction, so there is a single rounding. The first [`Float`]
1032 /// is taken by value and the others by reference. An [`Ordering`] is also returned, indicating
1033 /// whether the rounded diff is less than, equal to, or greater than the exact diff. Although
1034 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
1035 /// returns `Equal`.
1036 ///
1037 /// See [`RoundingMode`] for a description of the possible rounding modes.
1038 ///
1039 /// $$
1040 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
1041 /// $$
1042 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1043 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1044 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
1045 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1046 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
1047 ///
1048 /// If the output has a precision, it is `prec`.
1049 ///
1050 /// Special cases:
1051 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1052 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1053 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1054 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1055 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1056 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1057 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
1058 /// - If exactly one product is infinite, the result is that product's infinity, the second
1059 /// product's sign counting as flipped.
1060 /// - If both products are infinite, the result is their common infinity if their signs differ,
1061 /// and `NaN` otherwise.
1062 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
1063 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
1064 /// `Floor`
1065 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
1066 ///
1067 /// Overflow and underflow:
1068 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1069 /// returned instead.
1070 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
1071 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1072 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1073 /// returned instead.
1074 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
1075 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1076 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
1077 /// instead.
1078 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1079 /// instead.
1080 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1081 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
1082 /// returned instead.
1083 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
1084 /// instead.
1085 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1086 /// instead.
1087 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
1088 /// instead.
1089 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1090 /// returned instead.
1091 ///
1092 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec`] instead.
1093 /// If you know that your target precision is the maximum of the precisions of the inputs,
1094 /// consider using [`Float::mul_sub_mul_round`] instead. If both of these things are true,
1095 /// consider using
1096 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
1097 ///
1098 /// # Worst-case complexity
1099 /// $T(n, m) = O(n \log n \log\log n + m)$
1100 ///
1101 /// $M(n, m) = O(n \log n + m)$
1102 ///
1103 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1104 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1105 /// `max(self.significant_bits(), prec)`.
1106 ///
1107 /// # Panics
1108 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1109 /// representable with `prec` bits.
1110 ///
1111 /// # Examples
1112 /// ```
1113 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1114 /// use malachite_base::rounding_modes::RoundingMode::*;
1115 /// use malachite_float::Float;
1116 /// use std::cmp::Ordering::*;
1117 ///
1118 /// let x = Float::from(PI);
1119 /// let y = Float::from(E);
1120 /// let z = Float::from(SQRT_2);
1121 /// let w = Float::from(LN_2);
1122 ///
1123 /// let (diff, o) = x
1124 /// .clone()
1125 /// .mul_sub_mul_prec_round_val_ref_ref_ref(&y, &z, &w, 5, Floor);
1126 /// assert_eq!(diff.to_string(), "7.50");
1127 /// assert_eq!(o, Less);
1128 ///
1129 /// let (diff, o) = x
1130 /// .clone()
1131 /// .mul_sub_mul_prec_round_val_ref_ref_ref(&y, &z, &w, 5, Ceiling);
1132 /// assert_eq!(diff.to_string(), "7.75");
1133 /// assert_eq!(o, Greater);
1134 ///
1135 /// let (diff, o) = x
1136 /// .clone()
1137 /// .mul_sub_mul_prec_round_val_ref_ref_ref(&y, &z, &w, 5, Nearest);
1138 /// assert_eq!(diff.to_string(), "7.50");
1139 /// assert_eq!(o, Less);
1140 ///
1141 /// let (diff, o) = x
1142 /// .clone()
1143 /// .mul_sub_mul_prec_round_val_ref_ref_ref(&y, &z, &w, 20, Floor);
1144 /// assert_eq!(diff.to_string(), "7.5594711");
1145 /// assert_eq!(o, Less);
1146 ///
1147 /// let (diff, o) = x
1148 /// .clone()
1149 /// .mul_sub_mul_prec_round_val_ref_ref_ref(&y, &z, &w, 20, Ceiling);
1150 /// assert_eq!(diff.to_string(), "7.5594788");
1151 /// assert_eq!(o, Greater);
1152 ///
1153 /// let (diff, o) = x
1154 /// .clone()
1155 /// .mul_sub_mul_prec_round_val_ref_ref_ref(&y, &z, &w, 20, Nearest);
1156 /// assert_eq!(diff.to_string(), "7.5594788");
1157 /// assert_eq!(o, Greater);
1158 /// ```
1159 #[allow(clippy::needless_pass_by_value)]
1160 #[inline]
1161 pub fn mul_sub_mul_prec_round_val_ref_ref_ref(
1162 self,
1163 y: &Self,
1164 z: &Self,
1165 w: &Self,
1166 prec: u64,
1167 rm: RoundingMode,
1168 ) -> (Self, Ordering) {
1169 mul_add_mul_helper(&self, y, z, w, true, prec, rm)
1170 }
1171
1172 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
1173 /// the result to the specified precision and with the specified rounding mode; the products are
1174 /// not rounded before the final subtraction, so there is a single rounding. All four [`Float`]s
1175 /// are taken by reference. An [`Ordering`] is also returned, indicating whether the rounded
1176 /// diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
1177 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1178 ///
1179 /// See [`RoundingMode`] for a description of the possible rounding modes.
1180 ///
1181 /// $$
1182 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
1183 /// $$
1184 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1185 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1186 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
1187 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1188 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
1189 ///
1190 /// If the output has a precision, it is `prec`.
1191 ///
1192 /// Special cases:
1193 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1194 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1195 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1196 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1197 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
1198 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
1199 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
1200 /// - If exactly one product is infinite, the result is that product's infinity, the second
1201 /// product's sign counting as flipped.
1202 /// - If both products are infinite, the result is their common infinity if their signs differ,
1203 /// and `NaN` otherwise.
1204 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
1205 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
1206 /// `Floor`
1207 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
1208 ///
1209 /// Overflow and underflow:
1210 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
1211 /// returned instead.
1212 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
1213 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1214 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
1215 /// returned instead.
1216 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
1217 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
1218 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
1219 /// instead.
1220 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
1221 /// instead.
1222 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
1223 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
1224 /// returned instead.
1225 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
1226 /// instead.
1227 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
1228 /// instead.
1229 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
1230 /// instead.
1231 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1232 /// returned instead.
1233 ///
1234 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec`] instead.
1235 /// If you know that your target precision is the maximum of the precisions of the inputs,
1236 /// consider using [`Float::mul_sub_mul_round`] instead. If both of these things are true,
1237 /// consider using
1238 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
1239 ///
1240 /// # Worst-case complexity
1241 /// $T(n, m) = O(n \log n \log\log n + m)$
1242 ///
1243 /// $M(n, m) = O(n \log n + m)$
1244 ///
1245 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1246 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1247 /// `max(self.significant_bits(), prec)`.
1248 ///
1249 /// # Panics
1250 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1251 /// representable with `prec` bits.
1252 ///
1253 /// # Examples
1254 /// ```
1255 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1256 /// use malachite_base::rounding_modes::RoundingMode::*;
1257 /// use malachite_float::Float;
1258 /// use std::cmp::Ordering::*;
1259 ///
1260 /// let x = Float::from(PI);
1261 /// let y = Float::from(E);
1262 /// let z = Float::from(SQRT_2);
1263 /// let w = Float::from(LN_2);
1264 ///
1265 /// let (diff, o) = x.mul_sub_mul_prec_round_ref_ref_ref_ref(&y, &z, &w, 5, Floor);
1266 /// assert_eq!(diff.to_string(), "7.50");
1267 /// assert_eq!(o, Less);
1268 ///
1269 /// let (diff, o) = x.mul_sub_mul_prec_round_ref_ref_ref_ref(&y, &z, &w, 5, Ceiling);
1270 /// assert_eq!(diff.to_string(), "7.75");
1271 /// assert_eq!(o, Greater);
1272 ///
1273 /// let (diff, o) = x.mul_sub_mul_prec_round_ref_ref_ref_ref(&y, &z, &w, 5, Nearest);
1274 /// assert_eq!(diff.to_string(), "7.50");
1275 /// assert_eq!(o, Less);
1276 ///
1277 /// let (diff, o) = x.mul_sub_mul_prec_round_ref_ref_ref_ref(&y, &z, &w, 20, Floor);
1278 /// assert_eq!(diff.to_string(), "7.5594711");
1279 /// assert_eq!(o, Less);
1280 ///
1281 /// let (diff, o) = x.mul_sub_mul_prec_round_ref_ref_ref_ref(&y, &z, &w, 20, Ceiling);
1282 /// assert_eq!(diff.to_string(), "7.5594788");
1283 /// assert_eq!(o, Greater);
1284 ///
1285 /// let (diff, o) = x.mul_sub_mul_prec_round_ref_ref_ref_ref(&y, &z, &w, 20, Nearest);
1286 /// assert_eq!(diff.to_string(), "7.5594788");
1287 /// assert_eq!(o, Greater);
1288 /// ```
1289 #[allow(clippy::needless_pass_by_value)]
1290 #[inline]
1291 pub fn mul_sub_mul_prec_round_ref_ref_ref_ref(
1292 &self,
1293 y: &Self,
1294 z: &Self,
1295 w: &Self,
1296 prec: u64,
1297 rm: RoundingMode,
1298 ) -> (Self, Ordering) {
1299 mul_add_mul_helper(self, y, z, w, true, prec, rm)
1300 }
1301
1302 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
1303 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
1304 /// the specified rounding mode. The [`Float`]s on the right-hand side are all taken by value.
1305 /// An [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
1306 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
1307 /// this function assigns a `NaN` it also returns `Equal`.
1308 ///
1309 /// See [`RoundingMode`] for a description of the possible rounding modes.
1310 ///
1311 /// $$
1312 /// x \gets xy-zw+\varepsilon.
1313 /// $$
1314 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1315 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1316 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
1317 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1318 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
1319 ///
1320 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
1321 /// overflow, and underflow.
1322 ///
1323 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec_assign`]
1324 /// instead. If you know that your target precision is the maximum of the precisions of the
1325 /// inputs, consider using [`Float::mul_sub_mul_round_assign`] instead. If both of these things
1326 /// are true, consider using
1327 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
1328 ///
1329 /// # Worst-case complexity
1330 /// $T(n, m) = O(n \log n \log\log n + m)$
1331 ///
1332 /// $M(n, m) = O(n \log n + m)$
1333 ///
1334 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1335 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1336 /// `max(self.significant_bits(), prec)`.
1337 ///
1338 /// # Panics
1339 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1340 /// representable with `prec` bits.
1341 ///
1342 /// # Examples
1343 /// ```
1344 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1345 /// use malachite_base::rounding_modes::RoundingMode::*;
1346 /// use malachite_float::Float;
1347 /// use std::cmp::Ordering::*;
1348 ///
1349 /// let y = Float::from(E);
1350 /// let z = Float::from(SQRT_2);
1351 /// let w = Float::from(LN_2);
1352 ///
1353 /// let mut x = Float::from(PI);
1354 /// assert_eq!(
1355 /// x.mul_sub_mul_prec_round_assign(y.clone(), z.clone(), w.clone(), 5, Floor),
1356 /// Less
1357 /// );
1358 /// assert_eq!(x.to_string(), "7.50");
1359 ///
1360 /// let mut x = Float::from(PI);
1361 /// assert_eq!(
1362 /// x.mul_sub_mul_prec_round_assign(y.clone(), z.clone(), w.clone(), 5, Ceiling),
1363 /// Greater
1364 /// );
1365 /// assert_eq!(x.to_string(), "7.75");
1366 ///
1367 /// let mut x = Float::from(PI);
1368 /// assert_eq!(
1369 /// x.mul_sub_mul_prec_round_assign(y.clone(), z.clone(), w.clone(), 5, Nearest),
1370 /// Less
1371 /// );
1372 /// assert_eq!(x.to_string(), "7.50");
1373 /// ```
1374 #[allow(clippy::needless_pass_by_value)]
1375 #[inline]
1376 pub fn mul_sub_mul_prec_round_assign(
1377 &mut self,
1378 y: Self,
1379 z: Self,
1380 w: Self,
1381 prec: u64,
1382 rm: RoundingMode,
1383 ) -> Ordering {
1384 let (s, o) = mul_add_mul_helper(self, &y, &z, &w, true, prec, rm);
1385 *self = s;
1386 o
1387 }
1388
1389 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
1390 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
1391 /// the specified rounding mode. The last [`Float`] on the right-hand side is taken by reference
1392 /// and the others by value. An [`Ordering`] is returned, indicating whether the rounded diff is
1393 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
1394 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1395 ///
1396 /// See [`RoundingMode`] for a description of the possible rounding modes.
1397 ///
1398 /// $$
1399 /// x \gets xy-zw+\varepsilon.
1400 /// $$
1401 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1402 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1403 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
1404 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1405 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
1406 ///
1407 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
1408 /// overflow, and underflow.
1409 ///
1410 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec_assign`]
1411 /// instead. If you know that your target precision is the maximum of the precisions of the
1412 /// inputs, consider using [`Float::mul_sub_mul_round_assign`] instead. If both of these things
1413 /// are true, consider using
1414 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
1415 ///
1416 /// # Worst-case complexity
1417 /// $T(n, m) = O(n \log n \log\log n + m)$
1418 ///
1419 /// $M(n, m) = O(n \log n + m)$
1420 ///
1421 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1422 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1423 /// `max(self.significant_bits(), prec)`.
1424 ///
1425 /// # Panics
1426 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1427 /// representable with `prec` bits.
1428 ///
1429 /// # Examples
1430 /// ```
1431 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1432 /// use malachite_base::rounding_modes::RoundingMode::*;
1433 /// use malachite_float::Float;
1434 /// use std::cmp::Ordering::*;
1435 ///
1436 /// let y = Float::from(E);
1437 /// let z = Float::from(SQRT_2);
1438 /// let w = Float::from(LN_2);
1439 ///
1440 /// let mut x = Float::from(PI);
1441 /// assert_eq!(
1442 /// x.mul_sub_mul_prec_round_assign_val_val_ref(y.clone(), z.clone(), &w, 5, Floor),
1443 /// Less
1444 /// );
1445 /// assert_eq!(x.to_string(), "7.50");
1446 ///
1447 /// let mut x = Float::from(PI);
1448 /// assert_eq!(
1449 /// x.mul_sub_mul_prec_round_assign_val_val_ref(y.clone(), z.clone(), &w, 5, Ceiling),
1450 /// Greater
1451 /// );
1452 /// assert_eq!(x.to_string(), "7.75");
1453 ///
1454 /// let mut x = Float::from(PI);
1455 /// assert_eq!(
1456 /// x.mul_sub_mul_prec_round_assign_val_val_ref(y.clone(), z.clone(), &w, 5, Nearest),
1457 /// Less
1458 /// );
1459 /// assert_eq!(x.to_string(), "7.50");
1460 /// ```
1461 #[allow(clippy::needless_pass_by_value)]
1462 #[inline]
1463 pub fn mul_sub_mul_prec_round_assign_val_val_ref(
1464 &mut self,
1465 y: Self,
1466 z: Self,
1467 w: &Self,
1468 prec: u64,
1469 rm: RoundingMode,
1470 ) -> Ordering {
1471 let (s, o) = mul_add_mul_helper(self, &y, &z, w, true, prec, rm);
1472 *self = s;
1473 o
1474 }
1475
1476 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
1477 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
1478 /// the specified rounding mode. The middle [`Float`] on the right-hand side is taken by
1479 /// reference and the others by value. An [`Ordering`] is returned, indicating whether the
1480 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
1481 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1482 ///
1483 /// See [`RoundingMode`] for a description of the possible rounding modes.
1484 ///
1485 /// $$
1486 /// x \gets xy-zw+\varepsilon.
1487 /// $$
1488 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1489 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1490 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
1491 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1492 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
1493 ///
1494 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
1495 /// overflow, and underflow.
1496 ///
1497 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec_assign`]
1498 /// instead. If you know that your target precision is the maximum of the precisions of the
1499 /// inputs, consider using [`Float::mul_sub_mul_round_assign`] instead. If both of these things
1500 /// are true, consider using
1501 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
1502 ///
1503 /// # Worst-case complexity
1504 /// $T(n, m) = O(n \log n \log\log n + m)$
1505 ///
1506 /// $M(n, m) = O(n \log n + m)$
1507 ///
1508 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1509 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1510 /// `max(self.significant_bits(), prec)`.
1511 ///
1512 /// # Panics
1513 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1514 /// representable with `prec` bits.
1515 ///
1516 /// # Examples
1517 /// ```
1518 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1519 /// use malachite_base::rounding_modes::RoundingMode::*;
1520 /// use malachite_float::Float;
1521 /// use std::cmp::Ordering::*;
1522 ///
1523 /// let y = Float::from(E);
1524 /// let z = Float::from(SQRT_2);
1525 /// let w = Float::from(LN_2);
1526 ///
1527 /// let mut x = Float::from(PI);
1528 /// assert_eq!(
1529 /// x.mul_sub_mul_prec_round_assign_val_ref_val(y.clone(), &z, w.clone(), 5, Floor),
1530 /// Less
1531 /// );
1532 /// assert_eq!(x.to_string(), "7.50");
1533 ///
1534 /// let mut x = Float::from(PI);
1535 /// assert_eq!(
1536 /// x.mul_sub_mul_prec_round_assign_val_ref_val(y.clone(), &z, w.clone(), 5, Ceiling),
1537 /// Greater
1538 /// );
1539 /// assert_eq!(x.to_string(), "7.75");
1540 ///
1541 /// let mut x = Float::from(PI);
1542 /// assert_eq!(
1543 /// x.mul_sub_mul_prec_round_assign_val_ref_val(y.clone(), &z, w.clone(), 5, Nearest),
1544 /// Less
1545 /// );
1546 /// assert_eq!(x.to_string(), "7.50");
1547 /// ```
1548 #[allow(clippy::needless_pass_by_value)]
1549 #[inline]
1550 pub fn mul_sub_mul_prec_round_assign_val_ref_val(
1551 &mut self,
1552 y: Self,
1553 z: &Self,
1554 w: Self,
1555 prec: u64,
1556 rm: RoundingMode,
1557 ) -> Ordering {
1558 let (s, o) = mul_add_mul_helper(self, &y, z, &w, true, prec, rm);
1559 *self = s;
1560 o
1561 }
1562
1563 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
1564 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
1565 /// the specified rounding mode. The first [`Float`] on the right-hand side is taken by value
1566 /// and the others by reference. An [`Ordering`] is returned, indicating whether the rounded
1567 /// diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
1568 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1569 ///
1570 /// See [`RoundingMode`] for a description of the possible rounding modes.
1571 ///
1572 /// $$
1573 /// x \gets xy-zw+\varepsilon.
1574 /// $$
1575 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1576 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1577 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
1578 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1579 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
1580 ///
1581 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
1582 /// overflow, and underflow.
1583 ///
1584 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec_assign`]
1585 /// instead. If you know that your target precision is the maximum of the precisions of the
1586 /// inputs, consider using [`Float::mul_sub_mul_round_assign`] instead. If both of these things
1587 /// are true, consider using
1588 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
1589 ///
1590 /// # Worst-case complexity
1591 /// $T(n, m) = O(n \log n \log\log n + m)$
1592 ///
1593 /// $M(n, m) = O(n \log n + m)$
1594 ///
1595 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1596 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1597 /// `max(self.significant_bits(), prec)`.
1598 ///
1599 /// # Panics
1600 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1601 /// representable with `prec` bits.
1602 ///
1603 /// # Examples
1604 /// ```
1605 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1606 /// use malachite_base::rounding_modes::RoundingMode::*;
1607 /// use malachite_float::Float;
1608 /// use std::cmp::Ordering::*;
1609 ///
1610 /// let y = Float::from(E);
1611 /// let z = Float::from(SQRT_2);
1612 /// let w = Float::from(LN_2);
1613 ///
1614 /// let mut x = Float::from(PI);
1615 /// assert_eq!(
1616 /// x.mul_sub_mul_prec_round_assign_val_ref_ref(y.clone(), &z, &w, 5, Floor),
1617 /// Less
1618 /// );
1619 /// assert_eq!(x.to_string(), "7.50");
1620 ///
1621 /// let mut x = Float::from(PI);
1622 /// assert_eq!(
1623 /// x.mul_sub_mul_prec_round_assign_val_ref_ref(y.clone(), &z, &w, 5, Ceiling),
1624 /// Greater
1625 /// );
1626 /// assert_eq!(x.to_string(), "7.75");
1627 ///
1628 /// let mut x = Float::from(PI);
1629 /// assert_eq!(
1630 /// x.mul_sub_mul_prec_round_assign_val_ref_ref(y.clone(), &z, &w, 5, Nearest),
1631 /// Less
1632 /// );
1633 /// assert_eq!(x.to_string(), "7.50");
1634 /// ```
1635 #[allow(clippy::needless_pass_by_value)]
1636 #[inline]
1637 pub fn mul_sub_mul_prec_round_assign_val_ref_ref(
1638 &mut self,
1639 y: Self,
1640 z: &Self,
1641 w: &Self,
1642 prec: u64,
1643 rm: RoundingMode,
1644 ) -> Ordering {
1645 let (s, o) = mul_add_mul_helper(self, &y, z, w, true, prec, rm);
1646 *self = s;
1647 o
1648 }
1649
1650 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
1651 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
1652 /// the specified rounding mode. The first [`Float`] on the right-hand side is taken by
1653 /// reference and the others by value. An [`Ordering`] is returned, indicating whether the
1654 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
1655 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1656 ///
1657 /// See [`RoundingMode`] for a description of the possible rounding modes.
1658 ///
1659 /// $$
1660 /// x \gets xy-zw+\varepsilon.
1661 /// $$
1662 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1663 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1664 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
1665 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1666 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
1667 ///
1668 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
1669 /// overflow, and underflow.
1670 ///
1671 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec_assign`]
1672 /// instead. If you know that your target precision is the maximum of the precisions of the
1673 /// inputs, consider using [`Float::mul_sub_mul_round_assign`] instead. If both of these things
1674 /// are true, consider using
1675 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
1676 ///
1677 /// # Worst-case complexity
1678 /// $T(n, m) = O(n \log n \log\log n + m)$
1679 ///
1680 /// $M(n, m) = O(n \log n + m)$
1681 ///
1682 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1683 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1684 /// `max(self.significant_bits(), prec)`.
1685 ///
1686 /// # Panics
1687 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1688 /// representable with `prec` bits.
1689 ///
1690 /// # Examples
1691 /// ```
1692 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1693 /// use malachite_base::rounding_modes::RoundingMode::*;
1694 /// use malachite_float::Float;
1695 /// use std::cmp::Ordering::*;
1696 ///
1697 /// let y = Float::from(E);
1698 /// let z = Float::from(SQRT_2);
1699 /// let w = Float::from(LN_2);
1700 ///
1701 /// let mut x = Float::from(PI);
1702 /// assert_eq!(
1703 /// x.mul_sub_mul_prec_round_assign_ref_val_val(&y, z.clone(), w.clone(), 5, Floor),
1704 /// Less
1705 /// );
1706 /// assert_eq!(x.to_string(), "7.50");
1707 ///
1708 /// let mut x = Float::from(PI);
1709 /// assert_eq!(
1710 /// x.mul_sub_mul_prec_round_assign_ref_val_val(&y, z.clone(), w.clone(), 5, Ceiling),
1711 /// Greater
1712 /// );
1713 /// assert_eq!(x.to_string(), "7.75");
1714 ///
1715 /// let mut x = Float::from(PI);
1716 /// assert_eq!(
1717 /// x.mul_sub_mul_prec_round_assign_ref_val_val(&y, z.clone(), w.clone(), 5, Nearest),
1718 /// Less
1719 /// );
1720 /// assert_eq!(x.to_string(), "7.50");
1721 /// ```
1722 #[allow(clippy::needless_pass_by_value)]
1723 #[inline]
1724 pub fn mul_sub_mul_prec_round_assign_ref_val_val(
1725 &mut self,
1726 y: &Self,
1727 z: Self,
1728 w: Self,
1729 prec: u64,
1730 rm: RoundingMode,
1731 ) -> Ordering {
1732 let (s, o) = mul_add_mul_helper(self, y, &z, &w, true, prec, rm);
1733 *self = s;
1734 o
1735 }
1736
1737 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
1738 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
1739 /// the specified rounding mode. The middle [`Float`] on the right-hand side is taken by value
1740 /// and the others by reference. An [`Ordering`] is returned, indicating whether the rounded
1741 /// diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
1742 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1743 ///
1744 /// See [`RoundingMode`] for a description of the possible rounding modes.
1745 ///
1746 /// $$
1747 /// x \gets xy-zw+\varepsilon.
1748 /// $$
1749 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1750 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1751 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
1752 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1753 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
1754 ///
1755 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
1756 /// overflow, and underflow.
1757 ///
1758 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec_assign`]
1759 /// instead. If you know that your target precision is the maximum of the precisions of the
1760 /// inputs, consider using [`Float::mul_sub_mul_round_assign`] instead. If both of these things
1761 /// are true, consider using
1762 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
1763 ///
1764 /// # Worst-case complexity
1765 /// $T(n, m) = O(n \log n \log\log n + m)$
1766 ///
1767 /// $M(n, m) = O(n \log n + m)$
1768 ///
1769 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1770 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1771 /// `max(self.significant_bits(), prec)`.
1772 ///
1773 /// # Panics
1774 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1775 /// representable with `prec` bits.
1776 ///
1777 /// # Examples
1778 /// ```
1779 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1780 /// use malachite_base::rounding_modes::RoundingMode::*;
1781 /// use malachite_float::Float;
1782 /// use std::cmp::Ordering::*;
1783 ///
1784 /// let y = Float::from(E);
1785 /// let z = Float::from(SQRT_2);
1786 /// let w = Float::from(LN_2);
1787 ///
1788 /// let mut x = Float::from(PI);
1789 /// assert_eq!(
1790 /// x.mul_sub_mul_prec_round_assign_ref_val_ref(&y, z.clone(), &w, 5, Floor),
1791 /// Less
1792 /// );
1793 /// assert_eq!(x.to_string(), "7.50");
1794 ///
1795 /// let mut x = Float::from(PI);
1796 /// assert_eq!(
1797 /// x.mul_sub_mul_prec_round_assign_ref_val_ref(&y, z.clone(), &w, 5, Ceiling),
1798 /// Greater
1799 /// );
1800 /// assert_eq!(x.to_string(), "7.75");
1801 ///
1802 /// let mut x = Float::from(PI);
1803 /// assert_eq!(
1804 /// x.mul_sub_mul_prec_round_assign_ref_val_ref(&y, z.clone(), &w, 5, Nearest),
1805 /// Less
1806 /// );
1807 /// assert_eq!(x.to_string(), "7.50");
1808 /// ```
1809 #[allow(clippy::needless_pass_by_value)]
1810 #[inline]
1811 pub fn mul_sub_mul_prec_round_assign_ref_val_ref(
1812 &mut self,
1813 y: &Self,
1814 z: Self,
1815 w: &Self,
1816 prec: u64,
1817 rm: RoundingMode,
1818 ) -> Ordering {
1819 let (s, o) = mul_add_mul_helper(self, y, &z, w, true, prec, rm);
1820 *self = s;
1821 o
1822 }
1823
1824 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
1825 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
1826 /// the specified rounding mode. The last [`Float`] on the right-hand side is taken by value and
1827 /// the others by reference. An [`Ordering`] is returned, indicating whether the rounded diff is
1828 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
1829 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1830 ///
1831 /// See [`RoundingMode`] for a description of the possible rounding modes.
1832 ///
1833 /// $$
1834 /// x \gets xy-zw+\varepsilon.
1835 /// $$
1836 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1837 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1838 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
1839 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1840 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
1841 ///
1842 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
1843 /// overflow, and underflow.
1844 ///
1845 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec_assign`]
1846 /// instead. If you know that your target precision is the maximum of the precisions of the
1847 /// inputs, consider using [`Float::mul_sub_mul_round_assign`] instead. If both of these things
1848 /// are true, consider using
1849 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
1850 ///
1851 /// # Worst-case complexity
1852 /// $T(n, m) = O(n \log n \log\log n + m)$
1853 ///
1854 /// $M(n, m) = O(n \log n + m)$
1855 ///
1856 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1857 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1858 /// `max(self.significant_bits(), prec)`.
1859 ///
1860 /// # Panics
1861 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1862 /// representable with `prec` bits.
1863 ///
1864 /// # Examples
1865 /// ```
1866 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1867 /// use malachite_base::rounding_modes::RoundingMode::*;
1868 /// use malachite_float::Float;
1869 /// use std::cmp::Ordering::*;
1870 ///
1871 /// let y = Float::from(E);
1872 /// let z = Float::from(SQRT_2);
1873 /// let w = Float::from(LN_2);
1874 ///
1875 /// let mut x = Float::from(PI);
1876 /// assert_eq!(
1877 /// x.mul_sub_mul_prec_round_assign_ref_ref_val(&y, &z, w.clone(), 5, Floor),
1878 /// Less
1879 /// );
1880 /// assert_eq!(x.to_string(), "7.50");
1881 ///
1882 /// let mut x = Float::from(PI);
1883 /// assert_eq!(
1884 /// x.mul_sub_mul_prec_round_assign_ref_ref_val(&y, &z, w.clone(), 5, Ceiling),
1885 /// Greater
1886 /// );
1887 /// assert_eq!(x.to_string(), "7.75");
1888 ///
1889 /// let mut x = Float::from(PI);
1890 /// assert_eq!(
1891 /// x.mul_sub_mul_prec_round_assign_ref_ref_val(&y, &z, w.clone(), 5, Nearest),
1892 /// Less
1893 /// );
1894 /// assert_eq!(x.to_string(), "7.50");
1895 /// ```
1896 #[allow(clippy::needless_pass_by_value)]
1897 #[inline]
1898 pub fn mul_sub_mul_prec_round_assign_ref_ref_val(
1899 &mut self,
1900 y: &Self,
1901 z: &Self,
1902 w: Self,
1903 prec: u64,
1904 rm: RoundingMode,
1905 ) -> Ordering {
1906 let (s, o) = mul_add_mul_helper(self, y, z, &w, true, prec, rm);
1907 *self = s;
1908 o
1909 }
1910
1911 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
1912 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
1913 /// the specified rounding mode. The [`Float`]s on the right-hand side are all taken by
1914 /// reference. An [`Ordering`] is returned, indicating whether the rounded diff is less than,
1915 /// equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
1916 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1917 ///
1918 /// See [`RoundingMode`] for a description of the possible rounding modes.
1919 ///
1920 /// $$
1921 /// x \gets xy-zw+\varepsilon.
1922 /// $$
1923 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1924 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1925 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
1926 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1927 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
1928 ///
1929 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
1930 /// overflow, and underflow.
1931 ///
1932 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_prec_assign`]
1933 /// instead. If you know that your target precision is the maximum of the precisions of the
1934 /// inputs, consider using [`Float::mul_sub_mul_round_assign`] instead. If both of these things
1935 /// are true, consider using
1936 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
1937 ///
1938 /// # Worst-case complexity
1939 /// $T(n, m) = O(n \log n \log\log n + m)$
1940 ///
1941 /// $M(n, m) = O(n \log n + m)$
1942 ///
1943 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
1944 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
1945 /// `max(self.significant_bits(), prec)`.
1946 ///
1947 /// # Panics
1948 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
1949 /// representable with `prec` bits.
1950 ///
1951 /// # Examples
1952 /// ```
1953 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
1954 /// use malachite_base::rounding_modes::RoundingMode::*;
1955 /// use malachite_float::Float;
1956 /// use std::cmp::Ordering::*;
1957 ///
1958 /// let y = Float::from(E);
1959 /// let z = Float::from(SQRT_2);
1960 /// let w = Float::from(LN_2);
1961 ///
1962 /// let mut x = Float::from(PI);
1963 /// assert_eq!(
1964 /// x.mul_sub_mul_prec_round_assign_ref_ref_ref(&y, &z, &w, 5, Floor),
1965 /// Less
1966 /// );
1967 /// assert_eq!(x.to_string(), "7.50");
1968 ///
1969 /// let mut x = Float::from(PI);
1970 /// assert_eq!(
1971 /// x.mul_sub_mul_prec_round_assign_ref_ref_ref(&y, &z, &w, 5, Ceiling),
1972 /// Greater
1973 /// );
1974 /// assert_eq!(x.to_string(), "7.75");
1975 ///
1976 /// let mut x = Float::from(PI);
1977 /// assert_eq!(
1978 /// x.mul_sub_mul_prec_round_assign_ref_ref_ref(&y, &z, &w, 5, Nearest),
1979 /// Less
1980 /// );
1981 /// assert_eq!(x.to_string(), "7.50");
1982 /// ```
1983 #[allow(clippy::needless_pass_by_value)]
1984 #[inline]
1985 pub fn mul_sub_mul_prec_round_assign_ref_ref_ref(
1986 &mut self,
1987 y: &Self,
1988 z: &Self,
1989 w: &Self,
1990 prec: u64,
1991 rm: RoundingMode,
1992 ) -> Ordering {
1993 let (s, o) = mul_add_mul_helper(self, y, z, w, true, prec, rm);
1994 *self = s;
1995 o
1996 }
1997
1998 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
1999 /// the result to the nearest value of the specified precision; the products are not rounded
2000 /// before the final subtraction, so there is a single rounding. All four [`Float`]s are taken
2001 /// by value. An [`Ordering`] is also returned, indicating whether the rounded diff is less
2002 /// than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
2003 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2004 ///
2005 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2006 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2007 /// the `Nearest` rounding mode.
2008 ///
2009 /// $$
2010 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
2011 /// $$
2012 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2013 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2014 /// |xy-zw|\rfloor-p}$.
2015 ///
2016 /// If the output has a precision, it is `prec`.
2017 ///
2018 /// Special cases:
2019 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2020 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2021 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2022 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2023 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2024 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2025 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2026 /// - If exactly one product is infinite, the result is that product's infinity, the second
2027 /// product's sign counting as flipped.
2028 /// - If both products are infinite, the result is their common infinity if their signs differ,
2029 /// and `NaN` otherwise.
2030 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
2031 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
2032 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
2033 ///
2034 /// Overflow and underflow:
2035 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2036 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2037 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2038 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2039 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2040 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2041 ///
2042 /// If you want to use a rounding mode other than `Nearest`, consider using
2043 /// [`Float::mul_sub_mul_prec_round`] instead. If you know that your target precision is the
2044 /// maximum of the precisions of the inputs, consider using
2045 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
2046 ///
2047 /// # Worst-case complexity
2048 /// $T(n, m) = O(n \log n \log\log n + m)$
2049 ///
2050 /// $M(n, m) = O(n \log n + m)$
2051 ///
2052 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2053 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2054 /// `max(self.significant_bits(), prec)`.
2055 ///
2056 /// # Panics
2057 /// Panics if `prec` is zero.
2058 ///
2059 /// # Examples
2060 /// ```
2061 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2062 /// use malachite_float::Float;
2063 /// use std::cmp::Ordering::*;
2064 ///
2065 /// let x = Float::from(PI);
2066 /// let y = Float::from(E);
2067 /// let z = Float::from(SQRT_2);
2068 /// let w = Float::from(LN_2);
2069 ///
2070 /// let (diff, o) = x
2071 /// .clone()
2072 /// .mul_sub_mul_prec(y.clone(), z.clone(), w.clone(), 5);
2073 /// assert_eq!(diff.to_string(), "7.50");
2074 /// assert_eq!(o, Less);
2075 ///
2076 /// let (diff, o) = x
2077 /// .clone()
2078 /// .mul_sub_mul_prec(y.clone(), z.clone(), w.clone(), 20);
2079 /// assert_eq!(diff.to_string(), "7.5594788");
2080 /// assert_eq!(o, Greater);
2081 /// ```
2082 #[allow(clippy::needless_pass_by_value)]
2083 #[inline]
2084 pub fn mul_sub_mul_prec(self, y: Self, z: Self, w: Self, prec: u64) -> (Self, Ordering) {
2085 self.mul_sub_mul_prec_round(y, z, w, prec, Nearest)
2086 }
2087
2088 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
2089 /// the result to the nearest value of the specified precision; the products are not rounded
2090 /// before the final subtraction, so there is a single rounding. The first three [`Float`]s are
2091 /// taken by value and the fourth by reference. An [`Ordering`] is also returned, indicating
2092 /// whether the rounded diff is less than, equal to, or greater than the exact diff. Although
2093 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
2094 /// returns `Equal`.
2095 ///
2096 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2097 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2098 /// the `Nearest` rounding mode.
2099 ///
2100 /// $$
2101 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
2102 /// $$
2103 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2104 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2105 /// |xy-zw|\rfloor-p}$.
2106 ///
2107 /// If the output has a precision, it is `prec`.
2108 ///
2109 /// Special cases:
2110 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2111 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2112 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2113 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2114 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2115 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2116 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2117 /// - If exactly one product is infinite, the result is that product's infinity, the second
2118 /// product's sign counting as flipped.
2119 /// - If both products are infinite, the result is their common infinity if their signs differ,
2120 /// and `NaN` otherwise.
2121 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
2122 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
2123 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
2124 ///
2125 /// Overflow and underflow:
2126 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2127 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2128 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2129 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2130 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2131 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2132 ///
2133 /// If you want to use a rounding mode other than `Nearest`, consider using
2134 /// [`Float::mul_sub_mul_prec_round`] instead. If you know that your target precision is the
2135 /// maximum of the precisions of the inputs, consider using
2136 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
2137 ///
2138 /// # Worst-case complexity
2139 /// $T(n, m) = O(n \log n \log\log n + m)$
2140 ///
2141 /// $M(n, m) = O(n \log n + m)$
2142 ///
2143 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2144 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2145 /// `max(self.significant_bits(), prec)`.
2146 ///
2147 /// # Panics
2148 /// Panics if `prec` is zero.
2149 ///
2150 /// # Examples
2151 /// ```
2152 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2153 /// use malachite_float::Float;
2154 /// use std::cmp::Ordering::*;
2155 ///
2156 /// let x = Float::from(PI);
2157 /// let y = Float::from(E);
2158 /// let z = Float::from(SQRT_2);
2159 /// let w = Float::from(LN_2);
2160 ///
2161 /// let (diff, o) = x
2162 /// .clone()
2163 /// .mul_sub_mul_prec_val_val_val_ref(y.clone(), z.clone(), &w, 5);
2164 /// assert_eq!(diff.to_string(), "7.50");
2165 /// assert_eq!(o, Less);
2166 ///
2167 /// let (diff, o) = x
2168 /// .clone()
2169 /// .mul_sub_mul_prec_val_val_val_ref(y.clone(), z.clone(), &w, 20);
2170 /// assert_eq!(diff.to_string(), "7.5594788");
2171 /// assert_eq!(o, Greater);
2172 /// ```
2173 #[allow(clippy::needless_pass_by_value)]
2174 #[inline]
2175 pub fn mul_sub_mul_prec_val_val_val_ref(
2176 self,
2177 y: Self,
2178 z: Self,
2179 w: &Self,
2180 prec: u64,
2181 ) -> (Self, Ordering) {
2182 self.mul_sub_mul_prec_round_val_val_val_ref(y, z, w, prec, Nearest)
2183 }
2184
2185 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
2186 /// the result to the nearest value of the specified precision; the products are not rounded
2187 /// before the final subtraction, so there is a single rounding. The third [`Float`] is taken by
2188 /// reference and the others by value. An [`Ordering`] is also returned, indicating whether the
2189 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
2190 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2191 ///
2192 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2193 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2194 /// the `Nearest` rounding mode.
2195 ///
2196 /// $$
2197 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
2198 /// $$
2199 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2200 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2201 /// |xy-zw|\rfloor-p}$.
2202 ///
2203 /// If the output has a precision, it is `prec`.
2204 ///
2205 /// Special cases:
2206 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2207 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2208 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2209 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2210 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2211 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2212 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2213 /// - If exactly one product is infinite, the result is that product's infinity, the second
2214 /// product's sign counting as flipped.
2215 /// - If both products are infinite, the result is their common infinity if their signs differ,
2216 /// and `NaN` otherwise.
2217 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
2218 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
2219 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
2220 ///
2221 /// Overflow and underflow:
2222 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2223 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2224 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2225 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2226 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2227 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2228 ///
2229 /// If you want to use a rounding mode other than `Nearest`, consider using
2230 /// [`Float::mul_sub_mul_prec_round`] instead. If you know that your target precision is the
2231 /// maximum of the precisions of the inputs, consider using
2232 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
2233 ///
2234 /// # Worst-case complexity
2235 /// $T(n, m) = O(n \log n \log\log n + m)$
2236 ///
2237 /// $M(n, m) = O(n \log n + m)$
2238 ///
2239 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2240 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2241 /// `max(self.significant_bits(), prec)`.
2242 ///
2243 /// # Panics
2244 /// Panics if `prec` is zero.
2245 ///
2246 /// # Examples
2247 /// ```
2248 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2249 /// use malachite_float::Float;
2250 /// use std::cmp::Ordering::*;
2251 ///
2252 /// let x = Float::from(PI);
2253 /// let y = Float::from(E);
2254 /// let z = Float::from(SQRT_2);
2255 /// let w = Float::from(LN_2);
2256 ///
2257 /// let (diff, o) = x
2258 /// .clone()
2259 /// .mul_sub_mul_prec_val_val_ref_val(y.clone(), &z, w.clone(), 5);
2260 /// assert_eq!(diff.to_string(), "7.50");
2261 /// assert_eq!(o, Less);
2262 ///
2263 /// let (diff, o) = x
2264 /// .clone()
2265 /// .mul_sub_mul_prec_val_val_ref_val(y.clone(), &z, w.clone(), 20);
2266 /// assert_eq!(diff.to_string(), "7.5594788");
2267 /// assert_eq!(o, Greater);
2268 /// ```
2269 #[allow(clippy::needless_pass_by_value)]
2270 #[inline]
2271 pub fn mul_sub_mul_prec_val_val_ref_val(
2272 self,
2273 y: Self,
2274 z: &Self,
2275 w: Self,
2276 prec: u64,
2277 ) -> (Self, Ordering) {
2278 self.mul_sub_mul_prec_round_val_val_ref_val(y, z, w, prec, Nearest)
2279 }
2280
2281 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
2282 /// the result to the nearest value of the specified precision; the products are not rounded
2283 /// before the final subtraction, so there is a single rounding. The first two [`Float`]s are
2284 /// taken by value and the last two by reference. An [`Ordering`] is also returned, indicating
2285 /// whether the rounded diff is less than, equal to, or greater than the exact diff. Although
2286 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
2287 /// returns `Equal`.
2288 ///
2289 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2290 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2291 /// the `Nearest` rounding mode.
2292 ///
2293 /// $$
2294 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
2295 /// $$
2296 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2297 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2298 /// |xy-zw|\rfloor-p}$.
2299 ///
2300 /// If the output has a precision, it is `prec`.
2301 ///
2302 /// Special cases:
2303 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2304 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2305 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2306 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2307 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2308 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2309 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2310 /// - If exactly one product is infinite, the result is that product's infinity, the second
2311 /// product's sign counting as flipped.
2312 /// - If both products are infinite, the result is their common infinity if their signs differ,
2313 /// and `NaN` otherwise.
2314 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
2315 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
2316 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
2317 ///
2318 /// Overflow and underflow:
2319 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2320 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2321 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2322 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2323 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2324 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2325 ///
2326 /// If you want to use a rounding mode other than `Nearest`, consider using
2327 /// [`Float::mul_sub_mul_prec_round`] instead. If you know that your target precision is the
2328 /// maximum of the precisions of the inputs, consider using
2329 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
2330 ///
2331 /// # Worst-case complexity
2332 /// $T(n, m) = O(n \log n \log\log n + m)$
2333 ///
2334 /// $M(n, m) = O(n \log n + m)$
2335 ///
2336 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2337 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2338 /// `max(self.significant_bits(), prec)`.
2339 ///
2340 /// # Panics
2341 /// Panics if `prec` is zero.
2342 ///
2343 /// # Examples
2344 /// ```
2345 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2346 /// use malachite_float::Float;
2347 /// use std::cmp::Ordering::*;
2348 ///
2349 /// let x = Float::from(PI);
2350 /// let y = Float::from(E);
2351 /// let z = Float::from(SQRT_2);
2352 /// let w = Float::from(LN_2);
2353 ///
2354 /// let (diff, o) = x
2355 /// .clone()
2356 /// .mul_sub_mul_prec_val_val_ref_ref(y.clone(), &z, &w, 5);
2357 /// assert_eq!(diff.to_string(), "7.50");
2358 /// assert_eq!(o, Less);
2359 ///
2360 /// let (diff, o) = x
2361 /// .clone()
2362 /// .mul_sub_mul_prec_val_val_ref_ref(y.clone(), &z, &w, 20);
2363 /// assert_eq!(diff.to_string(), "7.5594788");
2364 /// assert_eq!(o, Greater);
2365 /// ```
2366 #[allow(clippy::needless_pass_by_value)]
2367 #[inline]
2368 pub fn mul_sub_mul_prec_val_val_ref_ref(
2369 self,
2370 y: Self,
2371 z: &Self,
2372 w: &Self,
2373 prec: u64,
2374 ) -> (Self, Ordering) {
2375 self.mul_sub_mul_prec_round_val_val_ref_ref(y, z, w, prec, Nearest)
2376 }
2377
2378 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
2379 /// the result to the nearest value of the specified precision; the products are not rounded
2380 /// before the final subtraction, so there is a single rounding. The second [`Float`] is taken
2381 /// by reference and the others by value. An [`Ordering`] is also returned, indicating whether
2382 /// the rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are
2383 /// not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
2384 /// `Equal`.
2385 ///
2386 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2387 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2388 /// the `Nearest` rounding mode.
2389 ///
2390 /// $$
2391 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
2392 /// $$
2393 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2394 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2395 /// |xy-zw|\rfloor-p}$.
2396 ///
2397 /// If the output has a precision, it is `prec`.
2398 ///
2399 /// Special cases:
2400 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2401 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2402 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2403 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2404 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2405 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2406 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2407 /// - If exactly one product is infinite, the result is that product's infinity, the second
2408 /// product's sign counting as flipped.
2409 /// - If both products are infinite, the result is their common infinity if their signs differ,
2410 /// and `NaN` otherwise.
2411 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
2412 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
2413 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
2414 ///
2415 /// Overflow and underflow:
2416 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2417 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2418 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2419 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2420 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2421 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2422 ///
2423 /// If you want to use a rounding mode other than `Nearest`, consider using
2424 /// [`Float::mul_sub_mul_prec_round`] instead. If you know that your target precision is the
2425 /// maximum of the precisions of the inputs, consider using
2426 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
2427 ///
2428 /// # Worst-case complexity
2429 /// $T(n, m) = O(n \log n \log\log n + m)$
2430 ///
2431 /// $M(n, m) = O(n \log n + m)$
2432 ///
2433 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2434 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2435 /// `max(self.significant_bits(), prec)`.
2436 ///
2437 /// # Panics
2438 /// Panics if `prec` is zero.
2439 ///
2440 /// # Examples
2441 /// ```
2442 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2443 /// use malachite_float::Float;
2444 /// use std::cmp::Ordering::*;
2445 ///
2446 /// let x = Float::from(PI);
2447 /// let y = Float::from(E);
2448 /// let z = Float::from(SQRT_2);
2449 /// let w = Float::from(LN_2);
2450 ///
2451 /// let (diff, o) = x
2452 /// .clone()
2453 /// .mul_sub_mul_prec_val_ref_val_val(&y, z.clone(), w.clone(), 5);
2454 /// assert_eq!(diff.to_string(), "7.50");
2455 /// assert_eq!(o, Less);
2456 ///
2457 /// let (diff, o) = x
2458 /// .clone()
2459 /// .mul_sub_mul_prec_val_ref_val_val(&y, z.clone(), w.clone(), 20);
2460 /// assert_eq!(diff.to_string(), "7.5594788");
2461 /// assert_eq!(o, Greater);
2462 /// ```
2463 #[allow(clippy::needless_pass_by_value)]
2464 #[inline]
2465 pub fn mul_sub_mul_prec_val_ref_val_val(
2466 self,
2467 y: &Self,
2468 z: Self,
2469 w: Self,
2470 prec: u64,
2471 ) -> (Self, Ordering) {
2472 self.mul_sub_mul_prec_round_val_ref_val_val(y, z, w, prec, Nearest)
2473 }
2474
2475 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
2476 /// the result to the nearest value of the specified precision; the products are not rounded
2477 /// before the final subtraction, so there is a single rounding. The second and fourth
2478 /// [`Float`]s are taken by reference and the others by value. An [`Ordering`] is also returned,
2479 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
2480 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
2481 /// it also returns `Equal`.
2482 ///
2483 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2484 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2485 /// the `Nearest` rounding mode.
2486 ///
2487 /// $$
2488 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
2489 /// $$
2490 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2491 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2492 /// |xy-zw|\rfloor-p}$.
2493 ///
2494 /// If the output has a precision, it is `prec`.
2495 ///
2496 /// Special cases:
2497 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2498 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2499 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2500 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2501 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2502 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2503 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2504 /// - If exactly one product is infinite, the result is that product's infinity, the second
2505 /// product's sign counting as flipped.
2506 /// - If both products are infinite, the result is their common infinity if their signs differ,
2507 /// and `NaN` otherwise.
2508 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
2509 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
2510 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
2511 ///
2512 /// Overflow and underflow:
2513 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2514 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2515 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2516 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2517 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2518 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2519 ///
2520 /// If you want to use a rounding mode other than `Nearest`, consider using
2521 /// [`Float::mul_sub_mul_prec_round`] instead. If you know that your target precision is the
2522 /// maximum of the precisions of the inputs, consider using
2523 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
2524 ///
2525 /// # Worst-case complexity
2526 /// $T(n, m) = O(n \log n \log\log n + m)$
2527 ///
2528 /// $M(n, m) = O(n \log n + m)$
2529 ///
2530 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2531 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2532 /// `max(self.significant_bits(), prec)`.
2533 ///
2534 /// # Panics
2535 /// Panics if `prec` is zero.
2536 ///
2537 /// # Examples
2538 /// ```
2539 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2540 /// use malachite_float::Float;
2541 /// use std::cmp::Ordering::*;
2542 ///
2543 /// let x = Float::from(PI);
2544 /// let y = Float::from(E);
2545 /// let z = Float::from(SQRT_2);
2546 /// let w = Float::from(LN_2);
2547 ///
2548 /// let (diff, o) = x
2549 /// .clone()
2550 /// .mul_sub_mul_prec_val_ref_val_ref(&y, z.clone(), &w, 5);
2551 /// assert_eq!(diff.to_string(), "7.50");
2552 /// assert_eq!(o, Less);
2553 ///
2554 /// let (diff, o) = x
2555 /// .clone()
2556 /// .mul_sub_mul_prec_val_ref_val_ref(&y, z.clone(), &w, 20);
2557 /// assert_eq!(diff.to_string(), "7.5594788");
2558 /// assert_eq!(o, Greater);
2559 /// ```
2560 #[allow(clippy::needless_pass_by_value)]
2561 #[inline]
2562 pub fn mul_sub_mul_prec_val_ref_val_ref(
2563 self,
2564 y: &Self,
2565 z: Self,
2566 w: &Self,
2567 prec: u64,
2568 ) -> (Self, Ordering) {
2569 self.mul_sub_mul_prec_round_val_ref_val_ref(y, z, w, prec, Nearest)
2570 }
2571
2572 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
2573 /// the result to the nearest value of the specified precision; the products are not rounded
2574 /// before the final subtraction, so there is a single rounding. The second and third [`Float`]s
2575 /// are taken by reference and the others by value. An [`Ordering`] is also returned, indicating
2576 /// whether the rounded diff is less than, equal to, or greater than the exact diff. Although
2577 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
2578 /// returns `Equal`.
2579 ///
2580 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2581 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2582 /// the `Nearest` rounding mode.
2583 ///
2584 /// $$
2585 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
2586 /// $$
2587 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2588 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2589 /// |xy-zw|\rfloor-p}$.
2590 ///
2591 /// If the output has a precision, it is `prec`.
2592 ///
2593 /// Special cases:
2594 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2595 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2596 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2597 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2598 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2599 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2600 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2601 /// - If exactly one product is infinite, the result is that product's infinity, the second
2602 /// product's sign counting as flipped.
2603 /// - If both products are infinite, the result is their common infinity if their signs differ,
2604 /// and `NaN` otherwise.
2605 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
2606 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
2607 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
2608 ///
2609 /// Overflow and underflow:
2610 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2611 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2612 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2613 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2614 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2615 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2616 ///
2617 /// If you want to use a rounding mode other than `Nearest`, consider using
2618 /// [`Float::mul_sub_mul_prec_round`] instead. If you know that your target precision is the
2619 /// maximum of the precisions of the inputs, consider using
2620 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
2621 ///
2622 /// # Worst-case complexity
2623 /// $T(n, m) = O(n \log n \log\log n + m)$
2624 ///
2625 /// $M(n, m) = O(n \log n + m)$
2626 ///
2627 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2628 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2629 /// `max(self.significant_bits(), prec)`.
2630 ///
2631 /// # Panics
2632 /// Panics if `prec` is zero.
2633 ///
2634 /// # Examples
2635 /// ```
2636 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2637 /// use malachite_float::Float;
2638 /// use std::cmp::Ordering::*;
2639 ///
2640 /// let x = Float::from(PI);
2641 /// let y = Float::from(E);
2642 /// let z = Float::from(SQRT_2);
2643 /// let w = Float::from(LN_2);
2644 ///
2645 /// let (diff, o) = x
2646 /// .clone()
2647 /// .mul_sub_mul_prec_val_ref_ref_val(&y, &z, w.clone(), 5);
2648 /// assert_eq!(diff.to_string(), "7.50");
2649 /// assert_eq!(o, Less);
2650 ///
2651 /// let (diff, o) = x
2652 /// .clone()
2653 /// .mul_sub_mul_prec_val_ref_ref_val(&y, &z, w.clone(), 20);
2654 /// assert_eq!(diff.to_string(), "7.5594788");
2655 /// assert_eq!(o, Greater);
2656 /// ```
2657 #[allow(clippy::needless_pass_by_value)]
2658 #[inline]
2659 pub fn mul_sub_mul_prec_val_ref_ref_val(
2660 self,
2661 y: &Self,
2662 z: &Self,
2663 w: Self,
2664 prec: u64,
2665 ) -> (Self, Ordering) {
2666 self.mul_sub_mul_prec_round_val_ref_ref_val(y, z, w, prec, Nearest)
2667 }
2668
2669 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
2670 /// the result to the nearest value of the specified precision; the products are not rounded
2671 /// before the final subtraction, so there is a single rounding. The first [`Float`] is taken by
2672 /// value and the others by reference. An [`Ordering`] is also returned, indicating whether the
2673 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
2674 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2675 ///
2676 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2677 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2678 /// the `Nearest` rounding mode.
2679 ///
2680 /// $$
2681 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
2682 /// $$
2683 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2684 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2685 /// |xy-zw|\rfloor-p}$.
2686 ///
2687 /// If the output has a precision, it is `prec`.
2688 ///
2689 /// Special cases:
2690 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2691 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2692 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2693 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2694 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2695 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2696 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2697 /// - If exactly one product is infinite, the result is that product's infinity, the second
2698 /// product's sign counting as flipped.
2699 /// - If both products are infinite, the result is their common infinity if their signs differ,
2700 /// and `NaN` otherwise.
2701 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
2702 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
2703 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
2704 ///
2705 /// Overflow and underflow:
2706 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2707 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2708 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2709 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2710 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2711 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2712 ///
2713 /// If you want to use a rounding mode other than `Nearest`, consider using
2714 /// [`Float::mul_sub_mul_prec_round`] instead. If you know that your target precision is the
2715 /// maximum of the precisions of the inputs, consider using
2716 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
2717 ///
2718 /// # Worst-case complexity
2719 /// $T(n, m) = O(n \log n \log\log n + m)$
2720 ///
2721 /// $M(n, m) = O(n \log n + m)$
2722 ///
2723 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2724 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2725 /// `max(self.significant_bits(), prec)`.
2726 ///
2727 /// # Panics
2728 /// Panics if `prec` is zero.
2729 ///
2730 /// # Examples
2731 /// ```
2732 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2733 /// use malachite_float::Float;
2734 /// use std::cmp::Ordering::*;
2735 ///
2736 /// let x = Float::from(PI);
2737 /// let y = Float::from(E);
2738 /// let z = Float::from(SQRT_2);
2739 /// let w = Float::from(LN_2);
2740 ///
2741 /// let (diff, o) = x.clone().mul_sub_mul_prec_val_ref_ref_ref(&y, &z, &w, 5);
2742 /// assert_eq!(diff.to_string(), "7.50");
2743 /// assert_eq!(o, Less);
2744 ///
2745 /// let (diff, o) = x.clone().mul_sub_mul_prec_val_ref_ref_ref(&y, &z, &w, 20);
2746 /// assert_eq!(diff.to_string(), "7.5594788");
2747 /// assert_eq!(o, Greater);
2748 /// ```
2749 #[allow(clippy::needless_pass_by_value)]
2750 #[inline]
2751 pub fn mul_sub_mul_prec_val_ref_ref_ref(
2752 self,
2753 y: &Self,
2754 z: &Self,
2755 w: &Self,
2756 prec: u64,
2757 ) -> (Self, Ordering) {
2758 self.mul_sub_mul_prec_round_val_ref_ref_ref(y, z, w, prec, Nearest)
2759 }
2760
2761 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
2762 /// the result to the nearest value of the specified precision; the products are not rounded
2763 /// before the final subtraction, so there is a single rounding. All four [`Float`]s are taken
2764 /// by reference. An [`Ordering`] is also returned, indicating whether the rounded diff is less
2765 /// than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
2766 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2767 ///
2768 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2769 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2770 /// the `Nearest` rounding mode.
2771 ///
2772 /// $$
2773 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
2774 /// $$
2775 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2776 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2777 /// |xy-zw|\rfloor-p}$.
2778 ///
2779 /// If the output has a precision, it is `prec`.
2780 ///
2781 /// Special cases:
2782 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2783 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2784 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2785 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2786 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
2787 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
2788 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
2789 /// - If exactly one product is infinite, the result is that product's infinity, the second
2790 /// product's sign counting as flipped.
2791 /// - If both products are infinite, the result is their common infinity if their signs differ,
2792 /// and `NaN` otherwise.
2793 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
2794 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
2795 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
2796 ///
2797 /// Overflow and underflow:
2798 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
2799 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
2800 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
2801 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
2802 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
2803 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2804 ///
2805 /// If you want to use a rounding mode other than `Nearest`, consider using
2806 /// [`Float::mul_sub_mul_prec_round`] instead. If you know that your target precision is the
2807 /// maximum of the precisions of the inputs, consider using
2808 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
2809 ///
2810 /// # Worst-case complexity
2811 /// $T(n, m) = O(n \log n \log\log n + m)$
2812 ///
2813 /// $M(n, m) = O(n \log n + m)$
2814 ///
2815 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2816 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2817 /// `max(self.significant_bits(), prec)`.
2818 ///
2819 /// # Panics
2820 /// Panics if `prec` is zero.
2821 ///
2822 /// # Examples
2823 /// ```
2824 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2825 /// use malachite_float::Float;
2826 /// use std::cmp::Ordering::*;
2827 ///
2828 /// let x = Float::from(PI);
2829 /// let y = Float::from(E);
2830 /// let z = Float::from(SQRT_2);
2831 /// let w = Float::from(LN_2);
2832 ///
2833 /// let (diff, o) = x.mul_sub_mul_prec_ref_ref_ref_ref(&y, &z, &w, 5);
2834 /// assert_eq!(diff.to_string(), "7.50");
2835 /// assert_eq!(o, Less);
2836 ///
2837 /// let (diff, o) = x.mul_sub_mul_prec_ref_ref_ref_ref(&y, &z, &w, 20);
2838 /// assert_eq!(diff.to_string(), "7.5594788");
2839 /// assert_eq!(o, Greater);
2840 /// ```
2841 #[allow(clippy::needless_pass_by_value)]
2842 #[inline]
2843 pub fn mul_sub_mul_prec_ref_ref_ref_ref(
2844 &self,
2845 y: &Self,
2846 z: &Self,
2847 w: &Self,
2848 prec: u64,
2849 ) -> (Self, Ordering) {
2850 self.mul_sub_mul_prec_round_ref_ref_ref_ref(y, z, w, prec, Nearest)
2851 }
2852
2853 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
2854 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
2855 /// specified precision. The [`Float`]s on the right-hand side are all taken by value. An
2856 /// [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
2857 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
2858 /// this function assigns a `NaN` it also returns `Equal`.
2859 ///
2860 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2861 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2862 /// the `Nearest` rounding mode.
2863 ///
2864 /// $$
2865 /// x \gets xy-zw+\varepsilon.
2866 /// $$
2867 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2868 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2869 /// |xy-zw|\rfloor-p}$.
2870 ///
2871 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
2872 /// overflow, and underflow.
2873 ///
2874 /// If you want to use a rounding mode other than `Nearest`, consider using
2875 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know that your target precision is
2876 /// the maximum of the precisions of the inputs, consider using
2877 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
2878 ///
2879 /// # Worst-case complexity
2880 /// $T(n, m) = O(n \log n \log\log n + m)$
2881 ///
2882 /// $M(n, m) = O(n \log n + m)$
2883 ///
2884 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2885 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2886 /// `max(self.significant_bits(), prec)`.
2887 ///
2888 /// # Panics
2889 /// Panics if `prec` is zero.
2890 ///
2891 /// # Examples
2892 /// ```
2893 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2894 /// use malachite_float::Float;
2895 /// use std::cmp::Ordering::*;
2896 ///
2897 /// let y = Float::from(E);
2898 /// let z = Float::from(SQRT_2);
2899 /// let w = Float::from(LN_2);
2900 ///
2901 /// let mut x = Float::from(PI);
2902 /// assert_eq!(
2903 /// x.mul_sub_mul_prec_assign(y.clone(), z.clone(), w.clone(), 5),
2904 /// Less
2905 /// );
2906 /// assert_eq!(x.to_string(), "7.50");
2907 ///
2908 /// let mut x = Float::from(PI);
2909 /// assert_eq!(
2910 /// x.mul_sub_mul_prec_assign(y.clone(), z.clone(), w.clone(), 20),
2911 /// Greater
2912 /// );
2913 /// assert_eq!(x.to_string(), "7.5594788");
2914 /// ```
2915 #[allow(clippy::needless_pass_by_value)]
2916 #[inline]
2917 pub fn mul_sub_mul_prec_assign(&mut self, y: Self, z: Self, w: Self, prec: u64) -> Ordering {
2918 self.mul_sub_mul_prec_round_assign(y, z, w, prec, Nearest)
2919 }
2920
2921 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
2922 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
2923 /// specified precision. The last [`Float`] on the right-hand side is taken by reference and the
2924 /// others by value. An [`Ordering`] is returned, indicating whether the rounded diff is less
2925 /// than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
2926 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
2927 ///
2928 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2929 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2930 /// the `Nearest` rounding mode.
2931 ///
2932 /// $$
2933 /// x \gets xy-zw+\varepsilon.
2934 /// $$
2935 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2936 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2937 /// |xy-zw|\rfloor-p}$.
2938 ///
2939 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
2940 /// overflow, and underflow.
2941 ///
2942 /// If you want to use a rounding mode other than `Nearest`, consider using
2943 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know that your target precision is
2944 /// the maximum of the precisions of the inputs, consider using
2945 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
2946 ///
2947 /// # Worst-case complexity
2948 /// $T(n, m) = O(n \log n \log\log n + m)$
2949 ///
2950 /// $M(n, m) = O(n \log n + m)$
2951 ///
2952 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
2953 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
2954 /// `max(self.significant_bits(), prec)`.
2955 ///
2956 /// # Panics
2957 /// Panics if `prec` is zero.
2958 ///
2959 /// # Examples
2960 /// ```
2961 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
2962 /// use malachite_float::Float;
2963 /// use std::cmp::Ordering::*;
2964 ///
2965 /// let y = Float::from(E);
2966 /// let z = Float::from(SQRT_2);
2967 /// let w = Float::from(LN_2);
2968 ///
2969 /// let mut x = Float::from(PI);
2970 /// assert_eq!(
2971 /// x.mul_sub_mul_prec_assign_val_val_ref(y.clone(), z.clone(), &w, 5),
2972 /// Less
2973 /// );
2974 /// assert_eq!(x.to_string(), "7.50");
2975 ///
2976 /// let mut x = Float::from(PI);
2977 /// assert_eq!(
2978 /// x.mul_sub_mul_prec_assign_val_val_ref(y.clone(), z.clone(), &w, 20),
2979 /// Greater
2980 /// );
2981 /// assert_eq!(x.to_string(), "7.5594788");
2982 /// ```
2983 #[allow(clippy::needless_pass_by_value)]
2984 #[inline]
2985 pub fn mul_sub_mul_prec_assign_val_val_ref(
2986 &mut self,
2987 y: Self,
2988 z: Self,
2989 w: &Self,
2990 prec: u64,
2991 ) -> Ordering {
2992 self.mul_sub_mul_prec_round_assign_val_val_ref(y, z, w, prec, Nearest)
2993 }
2994
2995 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
2996 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
2997 /// specified precision. The middle [`Float`] on the right-hand side is taken by reference and
2998 /// the others by value. An [`Ordering`] is returned, indicating whether the rounded diff is
2999 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
3000 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
3001 ///
3002 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3003 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3004 /// the `Nearest` rounding mode.
3005 ///
3006 /// $$
3007 /// x \gets xy-zw+\varepsilon.
3008 /// $$
3009 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3010 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3011 /// |xy-zw|\rfloor-p}$.
3012 ///
3013 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
3014 /// overflow, and underflow.
3015 ///
3016 /// If you want to use a rounding mode other than `Nearest`, consider using
3017 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know that your target precision is
3018 /// the maximum of the precisions of the inputs, consider using
3019 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
3020 ///
3021 /// # Worst-case complexity
3022 /// $T(n, m) = O(n \log n \log\log n + m)$
3023 ///
3024 /// $M(n, m) = O(n \log n + m)$
3025 ///
3026 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3027 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3028 /// `max(self.significant_bits(), prec)`.
3029 ///
3030 /// # Panics
3031 /// Panics if `prec` is zero.
3032 ///
3033 /// # Examples
3034 /// ```
3035 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3036 /// use malachite_float::Float;
3037 /// use std::cmp::Ordering::*;
3038 ///
3039 /// let y = Float::from(E);
3040 /// let z = Float::from(SQRT_2);
3041 /// let w = Float::from(LN_2);
3042 ///
3043 /// let mut x = Float::from(PI);
3044 /// assert_eq!(
3045 /// x.mul_sub_mul_prec_assign_val_ref_val(y.clone(), &z, w.clone(), 5),
3046 /// Less
3047 /// );
3048 /// assert_eq!(x.to_string(), "7.50");
3049 ///
3050 /// let mut x = Float::from(PI);
3051 /// assert_eq!(
3052 /// x.mul_sub_mul_prec_assign_val_ref_val(y.clone(), &z, w.clone(), 20),
3053 /// Greater
3054 /// );
3055 /// assert_eq!(x.to_string(), "7.5594788");
3056 /// ```
3057 #[allow(clippy::needless_pass_by_value)]
3058 #[inline]
3059 pub fn mul_sub_mul_prec_assign_val_ref_val(
3060 &mut self,
3061 y: Self,
3062 z: &Self,
3063 w: Self,
3064 prec: u64,
3065 ) -> Ordering {
3066 self.mul_sub_mul_prec_round_assign_val_ref_val(y, z, w, prec, Nearest)
3067 }
3068
3069 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
3070 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
3071 /// specified precision. The first [`Float`] on the right-hand side is taken by value and the
3072 /// others by reference. An [`Ordering`] is returned, indicating whether the rounded diff is
3073 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
3074 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
3075 ///
3076 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3077 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3078 /// the `Nearest` rounding mode.
3079 ///
3080 /// $$
3081 /// x \gets xy-zw+\varepsilon.
3082 /// $$
3083 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3084 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3085 /// |xy-zw|\rfloor-p}$.
3086 ///
3087 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
3088 /// overflow, and underflow.
3089 ///
3090 /// If you want to use a rounding mode other than `Nearest`, consider using
3091 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know that your target precision is
3092 /// the maximum of the precisions of the inputs, consider using
3093 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
3094 ///
3095 /// # Worst-case complexity
3096 /// $T(n, m) = O(n \log n \log\log n + m)$
3097 ///
3098 /// $M(n, m) = O(n \log n + m)$
3099 ///
3100 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3101 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3102 /// `max(self.significant_bits(), prec)`.
3103 ///
3104 /// # Panics
3105 /// Panics if `prec` is zero.
3106 ///
3107 /// # Examples
3108 /// ```
3109 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3110 /// use malachite_float::Float;
3111 /// use std::cmp::Ordering::*;
3112 ///
3113 /// let y = Float::from(E);
3114 /// let z = Float::from(SQRT_2);
3115 /// let w = Float::from(LN_2);
3116 ///
3117 /// let mut x = Float::from(PI);
3118 /// assert_eq!(
3119 /// x.mul_sub_mul_prec_assign_val_ref_ref(y.clone(), &z, &w, 5),
3120 /// Less
3121 /// );
3122 /// assert_eq!(x.to_string(), "7.50");
3123 ///
3124 /// let mut x = Float::from(PI);
3125 /// assert_eq!(
3126 /// x.mul_sub_mul_prec_assign_val_ref_ref(y.clone(), &z, &w, 20),
3127 /// Greater
3128 /// );
3129 /// assert_eq!(x.to_string(), "7.5594788");
3130 /// ```
3131 #[allow(clippy::needless_pass_by_value)]
3132 #[inline]
3133 pub fn mul_sub_mul_prec_assign_val_ref_ref(
3134 &mut self,
3135 y: Self,
3136 z: &Self,
3137 w: &Self,
3138 prec: u64,
3139 ) -> Ordering {
3140 self.mul_sub_mul_prec_round_assign_val_ref_ref(y, z, w, prec, Nearest)
3141 }
3142
3143 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
3144 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
3145 /// specified precision. The first [`Float`] on the right-hand side is taken by reference and
3146 /// the others by value. An [`Ordering`] is returned, indicating whether the rounded diff is
3147 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
3148 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
3149 ///
3150 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3151 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3152 /// the `Nearest` rounding mode.
3153 ///
3154 /// $$
3155 /// x \gets xy-zw+\varepsilon.
3156 /// $$
3157 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3158 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3159 /// |xy-zw|\rfloor-p}$.
3160 ///
3161 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
3162 /// overflow, and underflow.
3163 ///
3164 /// If you want to use a rounding mode other than `Nearest`, consider using
3165 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know that your target precision is
3166 /// the maximum of the precisions of the inputs, consider using
3167 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
3168 ///
3169 /// # Worst-case complexity
3170 /// $T(n, m) = O(n \log n \log\log n + m)$
3171 ///
3172 /// $M(n, m) = O(n \log n + m)$
3173 ///
3174 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3175 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3176 /// `max(self.significant_bits(), prec)`.
3177 ///
3178 /// # Panics
3179 /// Panics if `prec` is zero.
3180 ///
3181 /// # Examples
3182 /// ```
3183 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3184 /// use malachite_float::Float;
3185 /// use std::cmp::Ordering::*;
3186 ///
3187 /// let y = Float::from(E);
3188 /// let z = Float::from(SQRT_2);
3189 /// let w = Float::from(LN_2);
3190 ///
3191 /// let mut x = Float::from(PI);
3192 /// assert_eq!(
3193 /// x.mul_sub_mul_prec_assign_ref_val_val(&y, z.clone(), w.clone(), 5),
3194 /// Less
3195 /// );
3196 /// assert_eq!(x.to_string(), "7.50");
3197 ///
3198 /// let mut x = Float::from(PI);
3199 /// assert_eq!(
3200 /// x.mul_sub_mul_prec_assign_ref_val_val(&y, z.clone(), w.clone(), 20),
3201 /// Greater
3202 /// );
3203 /// assert_eq!(x.to_string(), "7.5594788");
3204 /// ```
3205 #[allow(clippy::needless_pass_by_value)]
3206 #[inline]
3207 pub fn mul_sub_mul_prec_assign_ref_val_val(
3208 &mut self,
3209 y: &Self,
3210 z: Self,
3211 w: Self,
3212 prec: u64,
3213 ) -> Ordering {
3214 self.mul_sub_mul_prec_round_assign_ref_val_val(y, z, w, prec, Nearest)
3215 }
3216
3217 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
3218 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
3219 /// specified precision. The middle [`Float`] on the right-hand side is taken by value and the
3220 /// others by reference. An [`Ordering`] is returned, indicating whether the rounded diff is
3221 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
3222 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
3223 ///
3224 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3225 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3226 /// the `Nearest` rounding mode.
3227 ///
3228 /// $$
3229 /// x \gets xy-zw+\varepsilon.
3230 /// $$
3231 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3232 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3233 /// |xy-zw|\rfloor-p}$.
3234 ///
3235 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
3236 /// overflow, and underflow.
3237 ///
3238 /// If you want to use a rounding mode other than `Nearest`, consider using
3239 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know that your target precision is
3240 /// the maximum of the precisions of the inputs, consider using
3241 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
3242 ///
3243 /// # Worst-case complexity
3244 /// $T(n, m) = O(n \log n \log\log n + m)$
3245 ///
3246 /// $M(n, m) = O(n \log n + m)$
3247 ///
3248 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3249 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3250 /// `max(self.significant_bits(), prec)`.
3251 ///
3252 /// # Panics
3253 /// Panics if `prec` is zero.
3254 ///
3255 /// # Examples
3256 /// ```
3257 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3258 /// use malachite_float::Float;
3259 /// use std::cmp::Ordering::*;
3260 ///
3261 /// let y = Float::from(E);
3262 /// let z = Float::from(SQRT_2);
3263 /// let w = Float::from(LN_2);
3264 ///
3265 /// let mut x = Float::from(PI);
3266 /// assert_eq!(
3267 /// x.mul_sub_mul_prec_assign_ref_val_ref(&y, z.clone(), &w, 5),
3268 /// Less
3269 /// );
3270 /// assert_eq!(x.to_string(), "7.50");
3271 ///
3272 /// let mut x = Float::from(PI);
3273 /// assert_eq!(
3274 /// x.mul_sub_mul_prec_assign_ref_val_ref(&y, z.clone(), &w, 20),
3275 /// Greater
3276 /// );
3277 /// assert_eq!(x.to_string(), "7.5594788");
3278 /// ```
3279 #[allow(clippy::needless_pass_by_value)]
3280 #[inline]
3281 pub fn mul_sub_mul_prec_assign_ref_val_ref(
3282 &mut self,
3283 y: &Self,
3284 z: Self,
3285 w: &Self,
3286 prec: u64,
3287 ) -> Ordering {
3288 self.mul_sub_mul_prec_round_assign_ref_val_ref(y, z, w, prec, Nearest)
3289 }
3290
3291 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
3292 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
3293 /// specified precision. The last [`Float`] on the right-hand side is taken by value and the
3294 /// others by reference. An [`Ordering`] is returned, indicating whether the rounded diff is
3295 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
3296 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
3297 ///
3298 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3299 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3300 /// the `Nearest` rounding mode.
3301 ///
3302 /// $$
3303 /// x \gets xy-zw+\varepsilon.
3304 /// $$
3305 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3306 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3307 /// |xy-zw|\rfloor-p}$.
3308 ///
3309 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
3310 /// overflow, and underflow.
3311 ///
3312 /// If you want to use a rounding mode other than `Nearest`, consider using
3313 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know that your target precision is
3314 /// the maximum of the precisions of the inputs, consider using
3315 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
3316 ///
3317 /// # Worst-case complexity
3318 /// $T(n, m) = O(n \log n \log\log n + m)$
3319 ///
3320 /// $M(n, m) = O(n \log n + m)$
3321 ///
3322 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3323 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3324 /// `max(self.significant_bits(), prec)`.
3325 ///
3326 /// # Panics
3327 /// Panics if `prec` is zero.
3328 ///
3329 /// # Examples
3330 /// ```
3331 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3332 /// use malachite_float::Float;
3333 /// use std::cmp::Ordering::*;
3334 ///
3335 /// let y = Float::from(E);
3336 /// let z = Float::from(SQRT_2);
3337 /// let w = Float::from(LN_2);
3338 ///
3339 /// let mut x = Float::from(PI);
3340 /// assert_eq!(
3341 /// x.mul_sub_mul_prec_assign_ref_ref_val(&y, &z, w.clone(), 5),
3342 /// Less
3343 /// );
3344 /// assert_eq!(x.to_string(), "7.50");
3345 ///
3346 /// let mut x = Float::from(PI);
3347 /// assert_eq!(
3348 /// x.mul_sub_mul_prec_assign_ref_ref_val(&y, &z, w.clone(), 20),
3349 /// Greater
3350 /// );
3351 /// assert_eq!(x.to_string(), "7.5594788");
3352 /// ```
3353 #[allow(clippy::needless_pass_by_value)]
3354 #[inline]
3355 pub fn mul_sub_mul_prec_assign_ref_ref_val(
3356 &mut self,
3357 y: &Self,
3358 z: &Self,
3359 w: Self,
3360 prec: u64,
3361 ) -> Ordering {
3362 self.mul_sub_mul_prec_round_assign_ref_ref_val(y, z, w, prec, Nearest)
3363 }
3364
3365 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
3366 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
3367 /// specified precision. The [`Float`]s on the right-hand side are all taken by reference. An
3368 /// [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
3369 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
3370 /// this function assigns a `NaN` it also returns `Equal`.
3371 ///
3372 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
3373 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
3374 /// the `Nearest` rounding mode.
3375 ///
3376 /// $$
3377 /// x \gets xy-zw+\varepsilon.
3378 /// $$
3379 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3380 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3381 /// |xy-zw|\rfloor-p}$.
3382 ///
3383 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
3384 /// overflow, and underflow.
3385 ///
3386 /// If you want to use a rounding mode other than `Nearest`, consider using
3387 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know that your target precision is
3388 /// the maximum of the precisions of the inputs, consider using
3389 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
3390 ///
3391 /// # Worst-case complexity
3392 /// $T(n, m) = O(n \log n \log\log n + m)$
3393 ///
3394 /// $M(n, m) = O(n \log n + m)$
3395 ///
3396 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3397 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3398 /// `max(self.significant_bits(), prec)`.
3399 ///
3400 /// # Panics
3401 /// Panics if `prec` is zero.
3402 ///
3403 /// # Examples
3404 /// ```
3405 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3406 /// use malachite_float::Float;
3407 /// use std::cmp::Ordering::*;
3408 ///
3409 /// let y = Float::from(E);
3410 /// let z = Float::from(SQRT_2);
3411 /// let w = Float::from(LN_2);
3412 ///
3413 /// let mut x = Float::from(PI);
3414 /// assert_eq!(x.mul_sub_mul_prec_assign_ref_ref_ref(&y, &z, &w, 5), Less);
3415 /// assert_eq!(x.to_string(), "7.50");
3416 ///
3417 /// let mut x = Float::from(PI);
3418 /// assert_eq!(
3419 /// x.mul_sub_mul_prec_assign_ref_ref_ref(&y, &z, &w, 20),
3420 /// Greater
3421 /// );
3422 /// assert_eq!(x.to_string(), "7.5594788");
3423 /// ```
3424 #[allow(clippy::needless_pass_by_value)]
3425 #[inline]
3426 pub fn mul_sub_mul_prec_assign_ref_ref_ref(
3427 &mut self,
3428 y: &Self,
3429 z: &Self,
3430 w: &Self,
3431 prec: u64,
3432 ) -> Ordering {
3433 self.mul_sub_mul_prec_round_assign_ref_ref_ref(y, z, w, prec, Nearest)
3434 }
3435
3436 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
3437 /// the result with the specified rounding mode; the products are not rounded before the final
3438 /// subtraction, so there is a single rounding. All four [`Float`]s are taken by value. An
3439 /// [`Ordering`] is also returned, indicating whether the rounded diff is less than, equal to,
3440 /// or greater than the exact diff. Although `NaN`s are not comparable to any [`Float`],
3441 /// whenever this function returns a `NaN` it also returns `Equal`.
3442 ///
3443 /// The precision of the output is the maximum of the precisions of the inputs. See
3444 /// [`RoundingMode`] for a description of the possible rounding modes.
3445 ///
3446 /// $$
3447 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
3448 /// $$
3449 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3450 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3451 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3452 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3453 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3454 ///
3455 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3456 ///
3457 /// Special cases:
3458 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3459 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3460 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3461 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3462 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3463 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3464 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
3465 /// - If exactly one product is infinite, the result is that product's infinity, the second
3466 /// product's sign counting as flipped.
3467 /// - If both products are infinite, the result is their common infinity if their signs differ,
3468 /// and `NaN` otherwise.
3469 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
3470 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
3471 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
3472 ///
3473 /// Overflow and underflow:
3474 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3475 /// returned instead.
3476 /// - 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}$
3477 /// is returned instead, where `p` is the precision of the output.
3478 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3479 /// returned instead.
3480 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3481 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3482 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3483 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3484 /// instead.
3485 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3486 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
3487 /// returned instead.
3488 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3489 /// instead.
3490 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3491 /// instead.
3492 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3493 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3494 /// returned instead.
3495 ///
3496 /// If you want to specify an output precision, consider using [`Float::mul_sub_mul_prec_round`]
3497 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3498 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
3499 ///
3500 /// # Worst-case complexity
3501 /// $T(n, m) = O(n \log n \log\log n + m)$
3502 ///
3503 /// $M(n, m) = O(n \log n + m)$
3504 ///
3505 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3506 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3507 /// `self.significant_bits()`.
3508 ///
3509 /// # Panics
3510 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3511 /// represent the output.
3512 ///
3513 /// # Examples
3514 /// ```
3515 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3516 /// use malachite_base::rounding_modes::RoundingMode::*;
3517 /// use malachite_float::Float;
3518 /// use std::cmp::Ordering::*;
3519 ///
3520 /// let x = Float::from(PI);
3521 /// let y = Float::from(E);
3522 /// let z = Float::from(SQRT_2);
3523 /// let w = Float::from(LN_2);
3524 ///
3525 /// let (diff, o) = x
3526 /// .clone()
3527 /// .mul_sub_mul_round(y.clone(), z.clone(), w.clone(), Floor);
3528 /// assert_eq!(diff.to_string(), "7.5594760792050186");
3529 /// assert_eq!(o, Less);
3530 ///
3531 /// let (diff, o) = x
3532 /// .clone()
3533 /// .mul_sub_mul_round(y.clone(), z.clone(), w.clone(), Ceiling);
3534 /// assert_eq!(diff.to_string(), "7.5594760792050195");
3535 /// assert_eq!(o, Greater);
3536 ///
3537 /// let (diff, o) = x
3538 /// .clone()
3539 /// .mul_sub_mul_round(y.clone(), z.clone(), w.clone(), Nearest);
3540 /// assert_eq!(diff.to_string(), "7.5594760792050186");
3541 /// assert_eq!(o, Less);
3542 /// ```
3543 #[allow(clippy::needless_pass_by_value)]
3544 #[inline]
3545 pub fn mul_sub_mul_round(
3546 self,
3547 y: Self,
3548 z: Self,
3549 w: Self,
3550 rm: RoundingMode,
3551 ) -> (Self, Ordering) {
3552 let prec = max!(
3553 self.significant_bits(),
3554 y.significant_bits(),
3555 z.significant_bits(),
3556 w.significant_bits()
3557 );
3558 self.mul_sub_mul_prec_round(y, z, w, prec, rm)
3559 }
3560
3561 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
3562 /// the result with the specified rounding mode; the products are not rounded before the final
3563 /// subtraction, so there is a single rounding. The first three [`Float`]s are taken by value
3564 /// and the fourth by reference. An [`Ordering`] is also returned, indicating whether the
3565 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
3566 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3567 ///
3568 /// The precision of the output is the maximum of the precisions of the inputs. See
3569 /// [`RoundingMode`] for a description of the possible rounding modes.
3570 ///
3571 /// $$
3572 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
3573 /// $$
3574 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3575 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3576 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3577 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3578 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3579 ///
3580 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3581 ///
3582 /// Special cases:
3583 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3584 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3585 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3586 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3587 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3588 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3589 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
3590 /// - If exactly one product is infinite, the result is that product's infinity, the second
3591 /// product's sign counting as flipped.
3592 /// - If both products are infinite, the result is their common infinity if their signs differ,
3593 /// and `NaN` otherwise.
3594 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
3595 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
3596 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
3597 ///
3598 /// Overflow and underflow:
3599 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3600 /// returned instead.
3601 /// - 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}$
3602 /// is returned instead, where `p` is the precision of the output.
3603 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3604 /// returned instead.
3605 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3606 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3607 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3608 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3609 /// instead.
3610 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3611 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
3612 /// returned instead.
3613 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3614 /// instead.
3615 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3616 /// instead.
3617 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3618 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3619 /// returned instead.
3620 ///
3621 /// If you want to specify an output precision, consider using [`Float::mul_sub_mul_prec_round`]
3622 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3623 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
3624 ///
3625 /// # Worst-case complexity
3626 /// $T(n, m) = O(n \log n \log\log n + m)$
3627 ///
3628 /// $M(n, m) = O(n \log n + m)$
3629 ///
3630 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3631 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3632 /// `self.significant_bits()`.
3633 ///
3634 /// # Panics
3635 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3636 /// represent the output.
3637 ///
3638 /// # Examples
3639 /// ```
3640 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3641 /// use malachite_base::rounding_modes::RoundingMode::*;
3642 /// use malachite_float::Float;
3643 /// use std::cmp::Ordering::*;
3644 ///
3645 /// let x = Float::from(PI);
3646 /// let y = Float::from(E);
3647 /// let z = Float::from(SQRT_2);
3648 /// let w = Float::from(LN_2);
3649 ///
3650 /// let (diff, o) =
3651 /// x.clone()
3652 /// .mul_sub_mul_round_val_val_val_ref(y.clone(), z.clone(), &w, Floor);
3653 /// assert_eq!(diff.to_string(), "7.5594760792050186");
3654 /// assert_eq!(o, Less);
3655 ///
3656 /// let (diff, o) =
3657 /// x.clone()
3658 /// .mul_sub_mul_round_val_val_val_ref(y.clone(), z.clone(), &w, Ceiling);
3659 /// assert_eq!(diff.to_string(), "7.5594760792050195");
3660 /// assert_eq!(o, Greater);
3661 ///
3662 /// let (diff, o) =
3663 /// x.clone()
3664 /// .mul_sub_mul_round_val_val_val_ref(y.clone(), z.clone(), &w, Nearest);
3665 /// assert_eq!(diff.to_string(), "7.5594760792050186");
3666 /// assert_eq!(o, Less);
3667 /// ```
3668 #[allow(clippy::needless_pass_by_value)]
3669 #[inline]
3670 pub fn mul_sub_mul_round_val_val_val_ref(
3671 self,
3672 y: Self,
3673 z: Self,
3674 w: &Self,
3675 rm: RoundingMode,
3676 ) -> (Self, Ordering) {
3677 let prec = max!(
3678 self.significant_bits(),
3679 y.significant_bits(),
3680 z.significant_bits(),
3681 w.significant_bits()
3682 );
3683 self.mul_sub_mul_prec_round_val_val_val_ref(y, z, w, prec, rm)
3684 }
3685
3686 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
3687 /// the result with the specified rounding mode; the products are not rounded before the final
3688 /// subtraction, so there is a single rounding. The third [`Float`] is taken by reference and
3689 /// the others by value. An [`Ordering`] is also returned, indicating whether the rounded diff
3690 /// is less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable
3691 /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3692 ///
3693 /// The precision of the output is the maximum of the precisions of the inputs. See
3694 /// [`RoundingMode`] for a description of the possible rounding modes.
3695 ///
3696 /// $$
3697 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
3698 /// $$
3699 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3700 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3701 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3702 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3703 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3704 ///
3705 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3706 ///
3707 /// Special cases:
3708 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3709 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3710 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3711 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3712 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3713 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3714 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
3715 /// - If exactly one product is infinite, the result is that product's infinity, the second
3716 /// product's sign counting as flipped.
3717 /// - If both products are infinite, the result is their common infinity if their signs differ,
3718 /// and `NaN` otherwise.
3719 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
3720 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
3721 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
3722 ///
3723 /// Overflow and underflow:
3724 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3725 /// returned instead.
3726 /// - 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}$
3727 /// is returned instead, where `p` is the precision of the output.
3728 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3729 /// returned instead.
3730 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3731 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3732 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3733 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3734 /// instead.
3735 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3736 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
3737 /// returned instead.
3738 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3739 /// instead.
3740 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3741 /// instead.
3742 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3743 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3744 /// returned instead.
3745 ///
3746 /// If you want to specify an output precision, consider using [`Float::mul_sub_mul_prec_round`]
3747 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3748 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
3749 ///
3750 /// # Worst-case complexity
3751 /// $T(n, m) = O(n \log n \log\log n + m)$
3752 ///
3753 /// $M(n, m) = O(n \log n + m)$
3754 ///
3755 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3756 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3757 /// `self.significant_bits()`.
3758 ///
3759 /// # Panics
3760 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3761 /// represent the output.
3762 ///
3763 /// # Examples
3764 /// ```
3765 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3766 /// use malachite_base::rounding_modes::RoundingMode::*;
3767 /// use malachite_float::Float;
3768 /// use std::cmp::Ordering::*;
3769 ///
3770 /// let x = Float::from(PI);
3771 /// let y = Float::from(E);
3772 /// let z = Float::from(SQRT_2);
3773 /// let w = Float::from(LN_2);
3774 ///
3775 /// let (diff, o) =
3776 /// x.clone()
3777 /// .mul_sub_mul_round_val_val_ref_val(y.clone(), &z, w.clone(), Floor);
3778 /// assert_eq!(diff.to_string(), "7.5594760792050186");
3779 /// assert_eq!(o, Less);
3780 ///
3781 /// let (diff, o) =
3782 /// x.clone()
3783 /// .mul_sub_mul_round_val_val_ref_val(y.clone(), &z, w.clone(), Ceiling);
3784 /// assert_eq!(diff.to_string(), "7.5594760792050195");
3785 /// assert_eq!(o, Greater);
3786 ///
3787 /// let (diff, o) =
3788 /// x.clone()
3789 /// .mul_sub_mul_round_val_val_ref_val(y.clone(), &z, w.clone(), Nearest);
3790 /// assert_eq!(diff.to_string(), "7.5594760792050186");
3791 /// assert_eq!(o, Less);
3792 /// ```
3793 #[allow(clippy::needless_pass_by_value)]
3794 #[inline]
3795 pub fn mul_sub_mul_round_val_val_ref_val(
3796 self,
3797 y: Self,
3798 z: &Self,
3799 w: Self,
3800 rm: RoundingMode,
3801 ) -> (Self, Ordering) {
3802 let prec = max!(
3803 self.significant_bits(),
3804 y.significant_bits(),
3805 z.significant_bits(),
3806 w.significant_bits()
3807 );
3808 self.mul_sub_mul_prec_round_val_val_ref_val(y, z, w, prec, rm)
3809 }
3810
3811 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
3812 /// the result with the specified rounding mode; the products are not rounded before the final
3813 /// subtraction, so there is a single rounding. The first two [`Float`]s are taken by value and
3814 /// the last two by reference. An [`Ordering`] is also returned, indicating whether the rounded
3815 /// diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
3816 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3817 ///
3818 /// The precision of the output is the maximum of the precisions of the inputs. See
3819 /// [`RoundingMode`] for a description of the possible rounding modes.
3820 ///
3821 /// $$
3822 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
3823 /// $$
3824 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3825 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3826 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3827 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3828 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3829 ///
3830 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3831 ///
3832 /// Special cases:
3833 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3834 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3835 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3836 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3837 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3838 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3839 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
3840 /// - If exactly one product is infinite, the result is that product's infinity, the second
3841 /// product's sign counting as flipped.
3842 /// - If both products are infinite, the result is their common infinity if their signs differ,
3843 /// and `NaN` otherwise.
3844 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
3845 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
3846 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
3847 ///
3848 /// Overflow and underflow:
3849 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3850 /// returned instead.
3851 /// - 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}$
3852 /// is returned instead, where `p` is the precision of the output.
3853 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3854 /// returned instead.
3855 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3856 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3857 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3858 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3859 /// instead.
3860 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3861 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
3862 /// returned instead.
3863 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3864 /// instead.
3865 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3866 /// instead.
3867 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3868 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3869 /// returned instead.
3870 ///
3871 /// If you want to specify an output precision, consider using [`Float::mul_sub_mul_prec_round`]
3872 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3873 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
3874 ///
3875 /// # Worst-case complexity
3876 /// $T(n, m) = O(n \log n \log\log n + m)$
3877 ///
3878 /// $M(n, m) = O(n \log n + m)$
3879 ///
3880 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
3881 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
3882 /// `self.significant_bits()`.
3883 ///
3884 /// # Panics
3885 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3886 /// represent the output.
3887 ///
3888 /// # Examples
3889 /// ```
3890 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
3891 /// use malachite_base::rounding_modes::RoundingMode::*;
3892 /// use malachite_float::Float;
3893 /// use std::cmp::Ordering::*;
3894 ///
3895 /// let x = Float::from(PI);
3896 /// let y = Float::from(E);
3897 /// let z = Float::from(SQRT_2);
3898 /// let w = Float::from(LN_2);
3899 ///
3900 /// let (diff, o) = x
3901 /// .clone()
3902 /// .mul_sub_mul_round_val_val_ref_ref(y.clone(), &z, &w, Floor);
3903 /// assert_eq!(diff.to_string(), "7.5594760792050186");
3904 /// assert_eq!(o, Less);
3905 ///
3906 /// let (diff, o) = x
3907 /// .clone()
3908 /// .mul_sub_mul_round_val_val_ref_ref(y.clone(), &z, &w, Ceiling);
3909 /// assert_eq!(diff.to_string(), "7.5594760792050195");
3910 /// assert_eq!(o, Greater);
3911 ///
3912 /// let (diff, o) = x
3913 /// .clone()
3914 /// .mul_sub_mul_round_val_val_ref_ref(y.clone(), &z, &w, Nearest);
3915 /// assert_eq!(diff.to_string(), "7.5594760792050186");
3916 /// assert_eq!(o, Less);
3917 /// ```
3918 #[allow(clippy::needless_pass_by_value)]
3919 #[inline]
3920 pub fn mul_sub_mul_round_val_val_ref_ref(
3921 self,
3922 y: Self,
3923 z: &Self,
3924 w: &Self,
3925 rm: RoundingMode,
3926 ) -> (Self, Ordering) {
3927 let prec = max!(
3928 self.significant_bits(),
3929 y.significant_bits(),
3930 z.significant_bits(),
3931 w.significant_bits()
3932 );
3933 self.mul_sub_mul_prec_round_val_val_ref_ref(y, z, w, prec, rm)
3934 }
3935
3936 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
3937 /// the result with the specified rounding mode; the products are not rounded before the final
3938 /// subtraction, so there is a single rounding. The second [`Float`] is taken by reference and
3939 /// the others by value. An [`Ordering`] is also returned, indicating whether the rounded diff
3940 /// is less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable
3941 /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3942 ///
3943 /// The precision of the output is the maximum of the precisions of the inputs. See
3944 /// [`RoundingMode`] for a description of the possible rounding modes.
3945 ///
3946 /// $$
3947 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
3948 /// $$
3949 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3950 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3951 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3952 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3953 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3954 ///
3955 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3956 ///
3957 /// Special cases:
3958 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3959 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3960 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3961 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3962 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
3963 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
3964 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
3965 /// - If exactly one product is infinite, the result is that product's infinity, the second
3966 /// product's sign counting as flipped.
3967 /// - If both products are infinite, the result is their common infinity if their signs differ,
3968 /// and `NaN` otherwise.
3969 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
3970 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
3971 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
3972 ///
3973 /// Overflow and underflow:
3974 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3975 /// returned instead.
3976 /// - 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}$
3977 /// is returned instead, where `p` is the precision of the output.
3978 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3979 /// returned instead.
3980 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3981 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3982 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3983 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3984 /// instead.
3985 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3986 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
3987 /// returned instead.
3988 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3989 /// instead.
3990 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3991 /// instead.
3992 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3993 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3994 /// returned instead.
3995 ///
3996 /// If you want to specify an output precision, consider using [`Float::mul_sub_mul_prec_round`]
3997 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3998 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
3999 ///
4000 /// # Worst-case complexity
4001 /// $T(n, m) = O(n \log n \log\log n + m)$
4002 ///
4003 /// $M(n, m) = O(n \log n + m)$
4004 ///
4005 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4006 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4007 /// `self.significant_bits()`.
4008 ///
4009 /// # Panics
4010 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4011 /// represent the output.
4012 ///
4013 /// # Examples
4014 /// ```
4015 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4016 /// use malachite_base::rounding_modes::RoundingMode::*;
4017 /// use malachite_float::Float;
4018 /// use std::cmp::Ordering::*;
4019 ///
4020 /// let x = Float::from(PI);
4021 /// let y = Float::from(E);
4022 /// let z = Float::from(SQRT_2);
4023 /// let w = Float::from(LN_2);
4024 ///
4025 /// let (diff, o) =
4026 /// x.clone()
4027 /// .mul_sub_mul_round_val_ref_val_val(&y, z.clone(), w.clone(), Floor);
4028 /// assert_eq!(diff.to_string(), "7.5594760792050186");
4029 /// assert_eq!(o, Less);
4030 ///
4031 /// let (diff, o) =
4032 /// x.clone()
4033 /// .mul_sub_mul_round_val_ref_val_val(&y, z.clone(), w.clone(), Ceiling);
4034 /// assert_eq!(diff.to_string(), "7.5594760792050195");
4035 /// assert_eq!(o, Greater);
4036 ///
4037 /// let (diff, o) =
4038 /// x.clone()
4039 /// .mul_sub_mul_round_val_ref_val_val(&y, z.clone(), w.clone(), Nearest);
4040 /// assert_eq!(diff.to_string(), "7.5594760792050186");
4041 /// assert_eq!(o, Less);
4042 /// ```
4043 #[allow(clippy::needless_pass_by_value)]
4044 #[inline]
4045 pub fn mul_sub_mul_round_val_ref_val_val(
4046 self,
4047 y: &Self,
4048 z: Self,
4049 w: Self,
4050 rm: RoundingMode,
4051 ) -> (Self, Ordering) {
4052 let prec = max!(
4053 self.significant_bits(),
4054 y.significant_bits(),
4055 z.significant_bits(),
4056 w.significant_bits()
4057 );
4058 self.mul_sub_mul_prec_round_val_ref_val_val(y, z, w, prec, rm)
4059 }
4060
4061 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
4062 /// the result with the specified rounding mode; the products are not rounded before the final
4063 /// subtraction, so there is a single rounding. The second and fourth [`Float`]s are taken by
4064 /// reference and the others by value. An [`Ordering`] is also returned, indicating whether the
4065 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
4066 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
4067 ///
4068 /// The precision of the output is the maximum of the precisions of the inputs. See
4069 /// [`RoundingMode`] for a description of the possible rounding modes.
4070 ///
4071 /// $$
4072 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
4073 /// $$
4074 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4075 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4076 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4077 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4078 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4079 ///
4080 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4081 ///
4082 /// Special cases:
4083 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4084 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4085 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4086 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4087 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4088 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4089 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
4090 /// - If exactly one product is infinite, the result is that product's infinity, the second
4091 /// product's sign counting as flipped.
4092 /// - If both products are infinite, the result is their common infinity if their signs differ,
4093 /// and `NaN` otherwise.
4094 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
4095 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
4096 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
4097 ///
4098 /// Overflow and underflow:
4099 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4100 /// returned instead.
4101 /// - 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}$
4102 /// is returned instead, where `p` is the precision of the output.
4103 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4104 /// returned instead.
4105 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4106 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4107 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4108 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4109 /// instead.
4110 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4111 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4112 /// returned instead.
4113 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4114 /// instead.
4115 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4116 /// instead.
4117 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4118 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4119 /// returned instead.
4120 ///
4121 /// If you want to specify an output precision, consider using [`Float::mul_sub_mul_prec_round`]
4122 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
4123 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
4124 ///
4125 /// # Worst-case complexity
4126 /// $T(n, m) = O(n \log n \log\log n + m)$
4127 ///
4128 /// $M(n, m) = O(n \log n + m)$
4129 ///
4130 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4131 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4132 /// `self.significant_bits()`.
4133 ///
4134 /// # Panics
4135 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4136 /// represent the output.
4137 ///
4138 /// # Examples
4139 /// ```
4140 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4141 /// use malachite_base::rounding_modes::RoundingMode::*;
4142 /// use malachite_float::Float;
4143 /// use std::cmp::Ordering::*;
4144 ///
4145 /// let x = Float::from(PI);
4146 /// let y = Float::from(E);
4147 /// let z = Float::from(SQRT_2);
4148 /// let w = Float::from(LN_2);
4149 ///
4150 /// let (diff, o) = x
4151 /// .clone()
4152 /// .mul_sub_mul_round_val_ref_val_ref(&y, z.clone(), &w, Floor);
4153 /// assert_eq!(diff.to_string(), "7.5594760792050186");
4154 /// assert_eq!(o, Less);
4155 ///
4156 /// let (diff, o) = x
4157 /// .clone()
4158 /// .mul_sub_mul_round_val_ref_val_ref(&y, z.clone(), &w, Ceiling);
4159 /// assert_eq!(diff.to_string(), "7.5594760792050195");
4160 /// assert_eq!(o, Greater);
4161 ///
4162 /// let (diff, o) = x
4163 /// .clone()
4164 /// .mul_sub_mul_round_val_ref_val_ref(&y, z.clone(), &w, Nearest);
4165 /// assert_eq!(diff.to_string(), "7.5594760792050186");
4166 /// assert_eq!(o, Less);
4167 /// ```
4168 #[allow(clippy::needless_pass_by_value)]
4169 #[inline]
4170 pub fn mul_sub_mul_round_val_ref_val_ref(
4171 self,
4172 y: &Self,
4173 z: Self,
4174 w: &Self,
4175 rm: RoundingMode,
4176 ) -> (Self, Ordering) {
4177 let prec = max!(
4178 self.significant_bits(),
4179 y.significant_bits(),
4180 z.significant_bits(),
4181 w.significant_bits()
4182 );
4183 self.mul_sub_mul_prec_round_val_ref_val_ref(y, z, w, prec, rm)
4184 }
4185
4186 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
4187 /// the result with the specified rounding mode; the products are not rounded before the final
4188 /// subtraction, so there is a single rounding. The second and third [`Float`]s are taken by
4189 /// reference and the others by value. An [`Ordering`] is also returned, indicating whether the
4190 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
4191 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
4192 ///
4193 /// The precision of the output is the maximum of the precisions of the inputs. See
4194 /// [`RoundingMode`] for a description of the possible rounding modes.
4195 ///
4196 /// $$
4197 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
4198 /// $$
4199 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4200 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4201 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4202 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4203 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4204 ///
4205 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4206 ///
4207 /// Special cases:
4208 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4209 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4210 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4211 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4212 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4213 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4214 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
4215 /// - If exactly one product is infinite, the result is that product's infinity, the second
4216 /// product's sign counting as flipped.
4217 /// - If both products are infinite, the result is their common infinity if their signs differ,
4218 /// and `NaN` otherwise.
4219 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
4220 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
4221 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
4222 ///
4223 /// Overflow and underflow:
4224 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4225 /// returned instead.
4226 /// - 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}$
4227 /// is returned instead, where `p` is the precision of the output.
4228 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4229 /// returned instead.
4230 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4231 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4232 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4233 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4234 /// instead.
4235 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4236 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4237 /// returned instead.
4238 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4239 /// instead.
4240 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4241 /// instead.
4242 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4243 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4244 /// returned instead.
4245 ///
4246 /// If you want to specify an output precision, consider using [`Float::mul_sub_mul_prec_round`]
4247 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
4248 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
4249 ///
4250 /// # Worst-case complexity
4251 /// $T(n, m) = O(n \log n \log\log n + m)$
4252 ///
4253 /// $M(n, m) = O(n \log n + m)$
4254 ///
4255 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4256 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4257 /// `self.significant_bits()`.
4258 ///
4259 /// # Panics
4260 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4261 /// represent the output.
4262 ///
4263 /// # Examples
4264 /// ```
4265 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4266 /// use malachite_base::rounding_modes::RoundingMode::*;
4267 /// use malachite_float::Float;
4268 /// use std::cmp::Ordering::*;
4269 ///
4270 /// let x = Float::from(PI);
4271 /// let y = Float::from(E);
4272 /// let z = Float::from(SQRT_2);
4273 /// let w = Float::from(LN_2);
4274 ///
4275 /// let (diff, o) = x
4276 /// .clone()
4277 /// .mul_sub_mul_round_val_ref_ref_val(&y, &z, w.clone(), Floor);
4278 /// assert_eq!(diff.to_string(), "7.5594760792050186");
4279 /// assert_eq!(o, Less);
4280 ///
4281 /// let (diff, o) = x
4282 /// .clone()
4283 /// .mul_sub_mul_round_val_ref_ref_val(&y, &z, w.clone(), Ceiling);
4284 /// assert_eq!(diff.to_string(), "7.5594760792050195");
4285 /// assert_eq!(o, Greater);
4286 ///
4287 /// let (diff, o) = x
4288 /// .clone()
4289 /// .mul_sub_mul_round_val_ref_ref_val(&y, &z, w.clone(), Nearest);
4290 /// assert_eq!(diff.to_string(), "7.5594760792050186");
4291 /// assert_eq!(o, Less);
4292 /// ```
4293 #[allow(clippy::needless_pass_by_value)]
4294 #[inline]
4295 pub fn mul_sub_mul_round_val_ref_ref_val(
4296 self,
4297 y: &Self,
4298 z: &Self,
4299 w: Self,
4300 rm: RoundingMode,
4301 ) -> (Self, Ordering) {
4302 let prec = max!(
4303 self.significant_bits(),
4304 y.significant_bits(),
4305 z.significant_bits(),
4306 w.significant_bits()
4307 );
4308 self.mul_sub_mul_prec_round_val_ref_ref_val(y, z, w, prec, rm)
4309 }
4310
4311 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
4312 /// the result with the specified rounding mode; the products are not rounded before the final
4313 /// subtraction, so there is a single rounding. The first [`Float`] is taken by value and the
4314 /// others by reference. An [`Ordering`] is also returned, indicating whether the rounded diff
4315 /// is less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable
4316 /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
4317 ///
4318 /// The precision of the output is the maximum of the precisions of the inputs. See
4319 /// [`RoundingMode`] for a description of the possible rounding modes.
4320 ///
4321 /// $$
4322 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
4323 /// $$
4324 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4325 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4326 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4327 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4328 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4329 ///
4330 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4331 ///
4332 /// Special cases:
4333 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4334 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4335 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4336 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4337 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4338 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4339 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
4340 /// - If exactly one product is infinite, the result is that product's infinity, the second
4341 /// product's sign counting as flipped.
4342 /// - If both products are infinite, the result is their common infinity if their signs differ,
4343 /// and `NaN` otherwise.
4344 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
4345 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
4346 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
4347 ///
4348 /// Overflow and underflow:
4349 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4350 /// returned instead.
4351 /// - 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}$
4352 /// is returned instead, where `p` is the precision of the output.
4353 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4354 /// returned instead.
4355 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4356 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4357 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4358 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4359 /// instead.
4360 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4361 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4362 /// returned instead.
4363 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4364 /// instead.
4365 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4366 /// instead.
4367 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4368 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4369 /// returned instead.
4370 ///
4371 /// If you want to specify an output precision, consider using [`Float::mul_sub_mul_prec_round`]
4372 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
4373 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
4374 ///
4375 /// # Worst-case complexity
4376 /// $T(n, m) = O(n \log n \log\log n + m)$
4377 ///
4378 /// $M(n, m) = O(n \log n + m)$
4379 ///
4380 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4381 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4382 /// `self.significant_bits()`.
4383 ///
4384 /// # Panics
4385 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4386 /// represent the output.
4387 ///
4388 /// # Examples
4389 /// ```
4390 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4391 /// use malachite_base::rounding_modes::RoundingMode::*;
4392 /// use malachite_float::Float;
4393 /// use std::cmp::Ordering::*;
4394 ///
4395 /// let x = Float::from(PI);
4396 /// let y = Float::from(E);
4397 /// let z = Float::from(SQRT_2);
4398 /// let w = Float::from(LN_2);
4399 ///
4400 /// let (diff, o) = x
4401 /// .clone()
4402 /// .mul_sub_mul_round_val_ref_ref_ref(&y, &z, &w, Floor);
4403 /// assert_eq!(diff.to_string(), "7.5594760792050186");
4404 /// assert_eq!(o, Less);
4405 ///
4406 /// let (diff, o) = x
4407 /// .clone()
4408 /// .mul_sub_mul_round_val_ref_ref_ref(&y, &z, &w, Ceiling);
4409 /// assert_eq!(diff.to_string(), "7.5594760792050195");
4410 /// assert_eq!(o, Greater);
4411 ///
4412 /// let (diff, o) = x
4413 /// .clone()
4414 /// .mul_sub_mul_round_val_ref_ref_ref(&y, &z, &w, Nearest);
4415 /// assert_eq!(diff.to_string(), "7.5594760792050186");
4416 /// assert_eq!(o, Less);
4417 /// ```
4418 #[allow(clippy::needless_pass_by_value)]
4419 #[inline]
4420 pub fn mul_sub_mul_round_val_ref_ref_ref(
4421 self,
4422 y: &Self,
4423 z: &Self,
4424 w: &Self,
4425 rm: RoundingMode,
4426 ) -> (Self, Ordering) {
4427 let prec = max!(
4428 self.significant_bits(),
4429 y.significant_bits(),
4430 z.significant_bits(),
4431 w.significant_bits()
4432 );
4433 self.mul_sub_mul_prec_round_val_ref_ref_ref(y, z, w, prec, rm)
4434 }
4435
4436 /// Subtracts the product of one pair of [`Float`]s from the product of another pair, rounding
4437 /// the result with the specified rounding mode; the products are not rounded before the final
4438 /// subtraction, so there is a single rounding. All four [`Float`]s are taken by reference. An
4439 /// [`Ordering`] is also returned, indicating whether the rounded diff is less than, equal to,
4440 /// or greater than the exact diff. Although `NaN`s are not comparable to any [`Float`],
4441 /// whenever this function returns a `NaN` it also returns `Equal`.
4442 ///
4443 /// The precision of the output is the maximum of the precisions of the inputs. See
4444 /// [`RoundingMode`] for a description of the possible rounding modes.
4445 ///
4446 /// $$
4447 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
4448 /// $$
4449 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4450 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4451 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4452 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4453 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4454 ///
4455 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4456 ///
4457 /// Special cases:
4458 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4459 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4460 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4461 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4462 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
4463 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
4464 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
4465 /// - If exactly one product is infinite, the result is that product's infinity, the second
4466 /// product's sign counting as flipped.
4467 /// - If both products are infinite, the result is their common infinity if their signs differ,
4468 /// and `NaN` otherwise.
4469 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
4470 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
4471 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
4472 ///
4473 /// Overflow and underflow:
4474 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4475 /// returned instead.
4476 /// - 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}$
4477 /// is returned instead, where `p` is the precision of the output.
4478 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4479 /// returned instead.
4480 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4481 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4482 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4483 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4484 /// instead.
4485 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4486 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4487 /// returned instead.
4488 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4489 /// instead.
4490 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4491 /// instead.
4492 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4493 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4494 /// returned instead.
4495 ///
4496 /// If you want to specify an output precision, consider using [`Float::mul_sub_mul_prec_round`]
4497 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
4498 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
4499 ///
4500 /// # Worst-case complexity
4501 /// $T(n, m) = O(n \log n \log\log n + m)$
4502 ///
4503 /// $M(n, m) = O(n \log n + m)$
4504 ///
4505 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4506 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4507 /// `self.significant_bits()`.
4508 ///
4509 /// # Panics
4510 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4511 /// represent the output.
4512 ///
4513 /// # Examples
4514 /// ```
4515 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4516 /// use malachite_base::rounding_modes::RoundingMode::*;
4517 /// use malachite_float::Float;
4518 /// use std::cmp::Ordering::*;
4519 ///
4520 /// let x = Float::from(PI);
4521 /// let y = Float::from(E);
4522 /// let z = Float::from(SQRT_2);
4523 /// let w = Float::from(LN_2);
4524 ///
4525 /// let (diff, o) = x.mul_sub_mul_round_ref_ref_ref_ref(&y, &z, &w, Floor);
4526 /// assert_eq!(diff.to_string(), "7.5594760792050186");
4527 /// assert_eq!(o, Less);
4528 ///
4529 /// let (diff, o) = x.mul_sub_mul_round_ref_ref_ref_ref(&y, &z, &w, Ceiling);
4530 /// assert_eq!(diff.to_string(), "7.5594760792050195");
4531 /// assert_eq!(o, Greater);
4532 ///
4533 /// let (diff, o) = x.mul_sub_mul_round_ref_ref_ref_ref(&y, &z, &w, Nearest);
4534 /// assert_eq!(diff.to_string(), "7.5594760792050186");
4535 /// assert_eq!(o, Less);
4536 /// ```
4537 #[allow(clippy::needless_pass_by_value)]
4538 #[inline]
4539 pub fn mul_sub_mul_round_ref_ref_ref_ref(
4540 &self,
4541 y: &Self,
4542 z: &Self,
4543 w: &Self,
4544 rm: RoundingMode,
4545 ) -> (Self, Ordering) {
4546 let prec = max!(
4547 self.significant_bits(),
4548 y.significant_bits(),
4549 z.significant_bits(),
4550 w.significant_bits()
4551 );
4552 self.mul_sub_mul_prec_round_ref_ref_ref_ref(y, z, w, prec, rm)
4553 }
4554
4555 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
4556 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
4557 /// The [`Float`]s on the right-hand side are all taken by value. An [`Ordering`] is returned,
4558 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
4559 /// Although `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN`
4560 /// it also returns `Equal`.
4561 ///
4562 /// The precision of the output is the maximum of the precisions of the inputs. See
4563 /// [`RoundingMode`] for a description of the possible rounding modes.
4564 ///
4565 /// $$
4566 /// x \gets xy-zw+\varepsilon.
4567 /// $$
4568 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4569 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4570 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4571 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4572 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4573 ///
4574 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
4575 /// overflow, and underflow.
4576 ///
4577 /// If you want to specify an output precision, consider using
4578 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
4579 /// rounding mode, consider using
4580 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
4581 ///
4582 /// # Worst-case complexity
4583 /// $T(n, m) = O(n \log n \log\log n + m)$
4584 ///
4585 /// $M(n, m) = O(n \log n + m)$
4586 ///
4587 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4588 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4589 /// `self.significant_bits()`.
4590 ///
4591 /// # Panics
4592 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4593 /// represent the output.
4594 ///
4595 /// # Examples
4596 /// ```
4597 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4598 /// use malachite_base::rounding_modes::RoundingMode::*;
4599 /// use malachite_float::Float;
4600 /// use std::cmp::Ordering::*;
4601 ///
4602 /// let y = Float::from(E);
4603 /// let z = Float::from(SQRT_2);
4604 /// let w = Float::from(LN_2);
4605 ///
4606 /// let mut x = Float::from(PI);
4607 /// assert_eq!(
4608 /// x.mul_sub_mul_round_assign(y.clone(), z.clone(), w.clone(), Floor),
4609 /// Less
4610 /// );
4611 /// assert_eq!(x.to_string(), "7.5594760792050186");
4612 ///
4613 /// let mut x = Float::from(PI);
4614 /// assert_eq!(
4615 /// x.mul_sub_mul_round_assign(y.clone(), z.clone(), w.clone(), Ceiling),
4616 /// Greater
4617 /// );
4618 /// assert_eq!(x.to_string(), "7.5594760792050195");
4619 ///
4620 /// let mut x = Float::from(PI);
4621 /// assert_eq!(
4622 /// x.mul_sub_mul_round_assign(y.clone(), z.clone(), w.clone(), Nearest),
4623 /// Less
4624 /// );
4625 /// assert_eq!(x.to_string(), "7.5594760792050186");
4626 /// ```
4627 #[allow(clippy::needless_pass_by_value)]
4628 #[inline]
4629 pub fn mul_sub_mul_round_assign(
4630 &mut self,
4631 y: Self,
4632 z: Self,
4633 w: Self,
4634 rm: RoundingMode,
4635 ) -> Ordering {
4636 let prec = max!(
4637 self.significant_bits(),
4638 y.significant_bits(),
4639 z.significant_bits(),
4640 w.significant_bits()
4641 );
4642 self.mul_sub_mul_prec_round_assign(y, z, w, prec, rm)
4643 }
4644
4645 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
4646 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
4647 /// The last [`Float`] on the right-hand side is taken by reference and the others by value. An
4648 /// [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
4649 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
4650 /// this function assigns a `NaN` it also returns `Equal`.
4651 ///
4652 /// The precision of the output is the maximum of the precisions of the inputs. See
4653 /// [`RoundingMode`] for a description of the possible rounding modes.
4654 ///
4655 /// $$
4656 /// x \gets xy-zw+\varepsilon.
4657 /// $$
4658 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4659 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4660 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4661 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4662 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4663 ///
4664 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
4665 /// overflow, and underflow.
4666 ///
4667 /// If you want to specify an output precision, consider using
4668 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
4669 /// rounding mode, consider using
4670 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
4671 ///
4672 /// # Worst-case complexity
4673 /// $T(n, m) = O(n \log n \log\log n + m)$
4674 ///
4675 /// $M(n, m) = O(n \log n + m)$
4676 ///
4677 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4678 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4679 /// `self.significant_bits()`.
4680 ///
4681 /// # Panics
4682 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4683 /// represent the output.
4684 ///
4685 /// # Examples
4686 /// ```
4687 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4688 /// use malachite_base::rounding_modes::RoundingMode::*;
4689 /// use malachite_float::Float;
4690 /// use std::cmp::Ordering::*;
4691 ///
4692 /// let y = Float::from(E);
4693 /// let z = Float::from(SQRT_2);
4694 /// let w = Float::from(LN_2);
4695 ///
4696 /// let mut x = Float::from(PI);
4697 /// assert_eq!(
4698 /// x.mul_sub_mul_round_assign_val_val_ref(y.clone(), z.clone(), &w, Floor),
4699 /// Less
4700 /// );
4701 /// assert_eq!(x.to_string(), "7.5594760792050186");
4702 ///
4703 /// let mut x = Float::from(PI);
4704 /// assert_eq!(
4705 /// x.mul_sub_mul_round_assign_val_val_ref(y.clone(), z.clone(), &w, Ceiling),
4706 /// Greater
4707 /// );
4708 /// assert_eq!(x.to_string(), "7.5594760792050195");
4709 ///
4710 /// let mut x = Float::from(PI);
4711 /// assert_eq!(
4712 /// x.mul_sub_mul_round_assign_val_val_ref(y.clone(), z.clone(), &w, Nearest),
4713 /// Less
4714 /// );
4715 /// assert_eq!(x.to_string(), "7.5594760792050186");
4716 /// ```
4717 #[allow(clippy::needless_pass_by_value)]
4718 #[inline]
4719 pub fn mul_sub_mul_round_assign_val_val_ref(
4720 &mut self,
4721 y: Self,
4722 z: Self,
4723 w: &Self,
4724 rm: RoundingMode,
4725 ) -> Ordering {
4726 let prec = max!(
4727 self.significant_bits(),
4728 y.significant_bits(),
4729 z.significant_bits(),
4730 w.significant_bits()
4731 );
4732 self.mul_sub_mul_prec_round_assign_val_val_ref(y, z, w, prec, rm)
4733 }
4734
4735 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
4736 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
4737 /// The middle [`Float`] on the right-hand side is taken by reference and the others by value.
4738 /// An [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
4739 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
4740 /// this function assigns a `NaN` it also returns `Equal`.
4741 ///
4742 /// The precision of the output is the maximum of the precisions of the inputs. See
4743 /// [`RoundingMode`] for a description of the possible rounding modes.
4744 ///
4745 /// $$
4746 /// x \gets xy-zw+\varepsilon.
4747 /// $$
4748 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4749 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4750 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4751 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4752 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4753 ///
4754 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
4755 /// overflow, and underflow.
4756 ///
4757 /// If you want to specify an output precision, consider using
4758 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
4759 /// rounding mode, consider using
4760 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
4761 ///
4762 /// # Worst-case complexity
4763 /// $T(n, m) = O(n \log n \log\log n + m)$
4764 ///
4765 /// $M(n, m) = O(n \log n + m)$
4766 ///
4767 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4768 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4769 /// `self.significant_bits()`.
4770 ///
4771 /// # Panics
4772 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4773 /// represent the output.
4774 ///
4775 /// # Examples
4776 /// ```
4777 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4778 /// use malachite_base::rounding_modes::RoundingMode::*;
4779 /// use malachite_float::Float;
4780 /// use std::cmp::Ordering::*;
4781 ///
4782 /// let y = Float::from(E);
4783 /// let z = Float::from(SQRT_2);
4784 /// let w = Float::from(LN_2);
4785 ///
4786 /// let mut x = Float::from(PI);
4787 /// assert_eq!(
4788 /// x.mul_sub_mul_round_assign_val_ref_val(y.clone(), &z, w.clone(), Floor),
4789 /// Less
4790 /// );
4791 /// assert_eq!(x.to_string(), "7.5594760792050186");
4792 ///
4793 /// let mut x = Float::from(PI);
4794 /// assert_eq!(
4795 /// x.mul_sub_mul_round_assign_val_ref_val(y.clone(), &z, w.clone(), Ceiling),
4796 /// Greater
4797 /// );
4798 /// assert_eq!(x.to_string(), "7.5594760792050195");
4799 ///
4800 /// let mut x = Float::from(PI);
4801 /// assert_eq!(
4802 /// x.mul_sub_mul_round_assign_val_ref_val(y.clone(), &z, w.clone(), Nearest),
4803 /// Less
4804 /// );
4805 /// assert_eq!(x.to_string(), "7.5594760792050186");
4806 /// ```
4807 #[allow(clippy::needless_pass_by_value)]
4808 #[inline]
4809 pub fn mul_sub_mul_round_assign_val_ref_val(
4810 &mut self,
4811 y: Self,
4812 z: &Self,
4813 w: Self,
4814 rm: RoundingMode,
4815 ) -> Ordering {
4816 let prec = max!(
4817 self.significant_bits(),
4818 y.significant_bits(),
4819 z.significant_bits(),
4820 w.significant_bits()
4821 );
4822 self.mul_sub_mul_prec_round_assign_val_ref_val(y, z, w, prec, rm)
4823 }
4824
4825 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
4826 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
4827 /// The first [`Float`] on the right-hand side is taken by value and the others by reference. An
4828 /// [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
4829 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
4830 /// this function assigns a `NaN` it also returns `Equal`.
4831 ///
4832 /// The precision of the output is the maximum of the precisions of the inputs. See
4833 /// [`RoundingMode`] for a description of the possible rounding modes.
4834 ///
4835 /// $$
4836 /// x \gets xy-zw+\varepsilon.
4837 /// $$
4838 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4839 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4840 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4841 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4842 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4843 ///
4844 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
4845 /// overflow, and underflow.
4846 ///
4847 /// If you want to specify an output precision, consider using
4848 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
4849 /// rounding mode, consider using
4850 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
4851 ///
4852 /// # Worst-case complexity
4853 /// $T(n, m) = O(n \log n \log\log n + m)$
4854 ///
4855 /// $M(n, m) = O(n \log n + m)$
4856 ///
4857 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4858 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4859 /// `self.significant_bits()`.
4860 ///
4861 /// # Panics
4862 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4863 /// represent the output.
4864 ///
4865 /// # Examples
4866 /// ```
4867 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4868 /// use malachite_base::rounding_modes::RoundingMode::*;
4869 /// use malachite_float::Float;
4870 /// use std::cmp::Ordering::*;
4871 ///
4872 /// let y = Float::from(E);
4873 /// let z = Float::from(SQRT_2);
4874 /// let w = Float::from(LN_2);
4875 ///
4876 /// let mut x = Float::from(PI);
4877 /// assert_eq!(
4878 /// x.mul_sub_mul_round_assign_val_ref_ref(y.clone(), &z, &w, Floor),
4879 /// Less
4880 /// );
4881 /// assert_eq!(x.to_string(), "7.5594760792050186");
4882 ///
4883 /// let mut x = Float::from(PI);
4884 /// assert_eq!(
4885 /// x.mul_sub_mul_round_assign_val_ref_ref(y.clone(), &z, &w, Ceiling),
4886 /// Greater
4887 /// );
4888 /// assert_eq!(x.to_string(), "7.5594760792050195");
4889 ///
4890 /// let mut x = Float::from(PI);
4891 /// assert_eq!(
4892 /// x.mul_sub_mul_round_assign_val_ref_ref(y.clone(), &z, &w, Nearest),
4893 /// Less
4894 /// );
4895 /// assert_eq!(x.to_string(), "7.5594760792050186");
4896 /// ```
4897 #[allow(clippy::needless_pass_by_value)]
4898 #[inline]
4899 pub fn mul_sub_mul_round_assign_val_ref_ref(
4900 &mut self,
4901 y: Self,
4902 z: &Self,
4903 w: &Self,
4904 rm: RoundingMode,
4905 ) -> Ordering {
4906 let prec = max!(
4907 self.significant_bits(),
4908 y.significant_bits(),
4909 z.significant_bits(),
4910 w.significant_bits()
4911 );
4912 self.mul_sub_mul_prec_round_assign_val_ref_ref(y, z, w, prec, rm)
4913 }
4914
4915 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
4916 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
4917 /// The first [`Float`] on the right-hand side is taken by reference and the others by value. An
4918 /// [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
4919 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
4920 /// this function assigns a `NaN` it also returns `Equal`.
4921 ///
4922 /// The precision of the output is the maximum of the precisions of the inputs. See
4923 /// [`RoundingMode`] for a description of the possible rounding modes.
4924 ///
4925 /// $$
4926 /// x \gets xy-zw+\varepsilon.
4927 /// $$
4928 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4929 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4930 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
4931 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4932 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4933 ///
4934 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
4935 /// overflow, and underflow.
4936 ///
4937 /// If you want to specify an output precision, consider using
4938 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
4939 /// rounding mode, consider using
4940 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
4941 ///
4942 /// # Worst-case complexity
4943 /// $T(n, m) = O(n \log n \log\log n + m)$
4944 ///
4945 /// $M(n, m) = O(n \log n + m)$
4946 ///
4947 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4948 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
4949 /// `self.significant_bits()`.
4950 ///
4951 /// # Panics
4952 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
4953 /// represent the output.
4954 ///
4955 /// # Examples
4956 /// ```
4957 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
4958 /// use malachite_base::rounding_modes::RoundingMode::*;
4959 /// use malachite_float::Float;
4960 /// use std::cmp::Ordering::*;
4961 ///
4962 /// let y = Float::from(E);
4963 /// let z = Float::from(SQRT_2);
4964 /// let w = Float::from(LN_2);
4965 ///
4966 /// let mut x = Float::from(PI);
4967 /// assert_eq!(
4968 /// x.mul_sub_mul_round_assign_ref_val_val(&y, z.clone(), w.clone(), Floor),
4969 /// Less
4970 /// );
4971 /// assert_eq!(x.to_string(), "7.5594760792050186");
4972 ///
4973 /// let mut x = Float::from(PI);
4974 /// assert_eq!(
4975 /// x.mul_sub_mul_round_assign_ref_val_val(&y, z.clone(), w.clone(), Ceiling),
4976 /// Greater
4977 /// );
4978 /// assert_eq!(x.to_string(), "7.5594760792050195");
4979 ///
4980 /// let mut x = Float::from(PI);
4981 /// assert_eq!(
4982 /// x.mul_sub_mul_round_assign_ref_val_val(&y, z.clone(), w.clone(), Nearest),
4983 /// Less
4984 /// );
4985 /// assert_eq!(x.to_string(), "7.5594760792050186");
4986 /// ```
4987 #[allow(clippy::needless_pass_by_value)]
4988 #[inline]
4989 pub fn mul_sub_mul_round_assign_ref_val_val(
4990 &mut self,
4991 y: &Self,
4992 z: Self,
4993 w: Self,
4994 rm: RoundingMode,
4995 ) -> Ordering {
4996 let prec = max!(
4997 self.significant_bits(),
4998 y.significant_bits(),
4999 z.significant_bits(),
5000 w.significant_bits()
5001 );
5002 self.mul_sub_mul_prec_round_assign_ref_val_val(y, z, w, prec, rm)
5003 }
5004
5005 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
5006 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
5007 /// The middle [`Float`] on the right-hand side is taken by value and the others by reference.
5008 /// An [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
5009 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
5010 /// this function assigns a `NaN` it also returns `Equal`.
5011 ///
5012 /// The precision of the output is the maximum of the precisions of the inputs. See
5013 /// [`RoundingMode`] for a description of the possible rounding modes.
5014 ///
5015 /// $$
5016 /// x \gets xy-zw+\varepsilon.
5017 /// $$
5018 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5019 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5020 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
5021 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5022 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
5023 ///
5024 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
5025 /// overflow, and underflow.
5026 ///
5027 /// If you want to specify an output precision, consider using
5028 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
5029 /// rounding mode, consider using
5030 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
5031 ///
5032 /// # Worst-case complexity
5033 /// $T(n, m) = O(n \log n \log\log n + m)$
5034 ///
5035 /// $M(n, m) = O(n \log n + m)$
5036 ///
5037 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5038 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5039 /// `self.significant_bits()`.
5040 ///
5041 /// # Panics
5042 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
5043 /// represent the output.
5044 ///
5045 /// # Examples
5046 /// ```
5047 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
5048 /// use malachite_base::rounding_modes::RoundingMode::*;
5049 /// use malachite_float::Float;
5050 /// use std::cmp::Ordering::*;
5051 ///
5052 /// let y = Float::from(E);
5053 /// let z = Float::from(SQRT_2);
5054 /// let w = Float::from(LN_2);
5055 ///
5056 /// let mut x = Float::from(PI);
5057 /// assert_eq!(
5058 /// x.mul_sub_mul_round_assign_ref_val_ref(&y, z.clone(), &w, Floor),
5059 /// Less
5060 /// );
5061 /// assert_eq!(x.to_string(), "7.5594760792050186");
5062 ///
5063 /// let mut x = Float::from(PI);
5064 /// assert_eq!(
5065 /// x.mul_sub_mul_round_assign_ref_val_ref(&y, z.clone(), &w, Ceiling),
5066 /// Greater
5067 /// );
5068 /// assert_eq!(x.to_string(), "7.5594760792050195");
5069 ///
5070 /// let mut x = Float::from(PI);
5071 /// assert_eq!(
5072 /// x.mul_sub_mul_round_assign_ref_val_ref(&y, z.clone(), &w, Nearest),
5073 /// Less
5074 /// );
5075 /// assert_eq!(x.to_string(), "7.5594760792050186");
5076 /// ```
5077 #[allow(clippy::needless_pass_by_value)]
5078 #[inline]
5079 pub fn mul_sub_mul_round_assign_ref_val_ref(
5080 &mut self,
5081 y: &Self,
5082 z: Self,
5083 w: &Self,
5084 rm: RoundingMode,
5085 ) -> Ordering {
5086 let prec = max!(
5087 self.significant_bits(),
5088 y.significant_bits(),
5089 z.significant_bits(),
5090 w.significant_bits()
5091 );
5092 self.mul_sub_mul_prec_round_assign_ref_val_ref(y, z, w, prec, rm)
5093 }
5094
5095 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
5096 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
5097 /// The last [`Float`] on the right-hand side is taken by value and the others by reference. An
5098 /// [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
5099 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
5100 /// this function assigns a `NaN` it also returns `Equal`.
5101 ///
5102 /// The precision of the output is the maximum of the precisions of the inputs. See
5103 /// [`RoundingMode`] for a description of the possible rounding modes.
5104 ///
5105 /// $$
5106 /// x \gets xy-zw+\varepsilon.
5107 /// $$
5108 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5109 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5110 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
5111 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5112 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
5113 ///
5114 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
5115 /// overflow, and underflow.
5116 ///
5117 /// If you want to specify an output precision, consider using
5118 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
5119 /// rounding mode, consider using
5120 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
5121 ///
5122 /// # Worst-case complexity
5123 /// $T(n, m) = O(n \log n \log\log n + m)$
5124 ///
5125 /// $M(n, m) = O(n \log n + m)$
5126 ///
5127 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5128 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5129 /// `self.significant_bits()`.
5130 ///
5131 /// # Panics
5132 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
5133 /// represent the output.
5134 ///
5135 /// # Examples
5136 /// ```
5137 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
5138 /// use malachite_base::rounding_modes::RoundingMode::*;
5139 /// use malachite_float::Float;
5140 /// use std::cmp::Ordering::*;
5141 ///
5142 /// let y = Float::from(E);
5143 /// let z = Float::from(SQRT_2);
5144 /// let w = Float::from(LN_2);
5145 ///
5146 /// let mut x = Float::from(PI);
5147 /// assert_eq!(
5148 /// x.mul_sub_mul_round_assign_ref_ref_val(&y, &z, w.clone(), Floor),
5149 /// Less
5150 /// );
5151 /// assert_eq!(x.to_string(), "7.5594760792050186");
5152 ///
5153 /// let mut x = Float::from(PI);
5154 /// assert_eq!(
5155 /// x.mul_sub_mul_round_assign_ref_ref_val(&y, &z, w.clone(), Ceiling),
5156 /// Greater
5157 /// );
5158 /// assert_eq!(x.to_string(), "7.5594760792050195");
5159 ///
5160 /// let mut x = Float::from(PI);
5161 /// assert_eq!(
5162 /// x.mul_sub_mul_round_assign_ref_ref_val(&y, &z, w.clone(), Nearest),
5163 /// Less
5164 /// );
5165 /// assert_eq!(x.to_string(), "7.5594760792050186");
5166 /// ```
5167 #[allow(clippy::needless_pass_by_value)]
5168 #[inline]
5169 pub fn mul_sub_mul_round_assign_ref_ref_val(
5170 &mut self,
5171 y: &Self,
5172 z: &Self,
5173 w: Self,
5174 rm: RoundingMode,
5175 ) -> Ordering {
5176 let prec = max!(
5177 self.significant_bits(),
5178 y.significant_bits(),
5179 z.significant_bits(),
5180 w.significant_bits()
5181 );
5182 self.mul_sub_mul_prec_round_assign_ref_ref_val(y, z, w, prec, rm)
5183 }
5184
5185 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
5186 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
5187 /// The [`Float`]s on the right-hand side are all taken by reference. An [`Ordering`] is
5188 /// returned, indicating whether the rounded diff is less than, equal to, or greater than the
5189 /// exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
5190 /// assigns a `NaN` it also returns `Equal`.
5191 ///
5192 /// The precision of the output is the maximum of the precisions of the inputs. See
5193 /// [`RoundingMode`] for a description of the possible rounding modes.
5194 ///
5195 /// $$
5196 /// x \gets xy-zw+\varepsilon.
5197 /// $$
5198 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5199 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5200 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
5201 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5202 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
5203 ///
5204 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
5205 /// overflow, and underflow.
5206 ///
5207 /// If you want to specify an output precision, consider using
5208 /// [`Float::mul_sub_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
5209 /// rounding mode, consider using
5210 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
5211 ///
5212 /// # Worst-case complexity
5213 /// $T(n, m) = O(n \log n \log\log n + m)$
5214 ///
5215 /// $M(n, m) = O(n \log n + m)$
5216 ///
5217 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5218 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5219 /// `self.significant_bits()`.
5220 ///
5221 /// # Panics
5222 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
5223 /// represent the output.
5224 ///
5225 /// # Examples
5226 /// ```
5227 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
5228 /// use malachite_base::rounding_modes::RoundingMode::*;
5229 /// use malachite_float::Float;
5230 /// use std::cmp::Ordering::*;
5231 ///
5232 /// let y = Float::from(E);
5233 /// let z = Float::from(SQRT_2);
5234 /// let w = Float::from(LN_2);
5235 ///
5236 /// let mut x = Float::from(PI);
5237 /// assert_eq!(
5238 /// x.mul_sub_mul_round_assign_ref_ref_ref(&y, &z, &w, Floor),
5239 /// Less
5240 /// );
5241 /// assert_eq!(x.to_string(), "7.5594760792050186");
5242 ///
5243 /// let mut x = Float::from(PI);
5244 /// assert_eq!(
5245 /// x.mul_sub_mul_round_assign_ref_ref_ref(&y, &z, &w, Ceiling),
5246 /// Greater
5247 /// );
5248 /// assert_eq!(x.to_string(), "7.5594760792050195");
5249 ///
5250 /// let mut x = Float::from(PI);
5251 /// assert_eq!(
5252 /// x.mul_sub_mul_round_assign_ref_ref_ref(&y, &z, &w, Nearest),
5253 /// Less
5254 /// );
5255 /// assert_eq!(x.to_string(), "7.5594760792050186");
5256 /// ```
5257 #[allow(clippy::needless_pass_by_value)]
5258 #[inline]
5259 pub fn mul_sub_mul_round_assign_ref_ref_ref(
5260 &mut self,
5261 y: &Self,
5262 z: &Self,
5263 w: &Self,
5264 rm: RoundingMode,
5265 ) -> Ordering {
5266 let prec = max!(
5267 self.significant_bits(),
5268 y.significant_bits(),
5269 z.significant_bits(),
5270 w.significant_bits()
5271 );
5272 self.mul_sub_mul_prec_round_assign_ref_ref_ref(y, z, w, prec, rm)
5273 }
5274}
5275
5276impl Float {
5277 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
5278 /// rounding the result to the specified precision and with the specified rounding mode; the
5279 /// [`Rational`] enters its product exactly and the products are not rounded before the final
5280 /// subtraction, so there is a single rounding. The [`Float`]s and the [`Rational`] are all
5281 /// taken by value. An [`Ordering`] is also returned, indicating whether the rounded diff is
5282 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
5283 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
5284 ///
5285 /// See [`RoundingMode`] for a description of the possible rounding modes.
5286 ///
5287 /// $$
5288 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
5289 /// $$
5290 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5291 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5292 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
5293 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5294 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
5295 ///
5296 /// If the output has a precision, it is `prec`.
5297 ///
5298 /// Special cases:
5299 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5300 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5301 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5302 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5303 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
5304 /// [`Rational`] counts as an unsigned zero and a positive sign.
5305 /// - If exactly one product is infinite, the result is that product's infinity, the second
5306 /// product's sign counting as flipped.
5307 /// - If both products are infinite, the result is their common infinity if their signs differ,
5308 /// and `NaN` otherwise.
5309 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
5310 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
5311 /// `Floor`
5312 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
5313 ///
5314 /// Overflow and underflow:
5315 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5316 /// returned instead.
5317 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
5318 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5319 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5320 /// returned instead.
5321 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5322 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5323 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
5324 /// instead.
5325 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5326 /// instead.
5327 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5328 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5329 /// returned instead.
5330 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5331 /// instead.
5332 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5333 /// instead.
5334 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
5335 /// instead.
5336 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5337 /// returned instead.
5338 ///
5339 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_rational_prec`]
5340 /// instead. If you know that your target precision is the maximum of the precisions of the
5341 /// inputs, consider using [`Float::mul_sub_mul_rational_round`] instead. If both of these
5342 /// things are true, consider using
5343 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
5344 ///
5345 /// # Worst-case complexity
5346 /// $T(n, m) = O(n \log n \log\log n + m)$
5347 ///
5348 /// $M(n, m) = O(n \log n + m)$
5349 ///
5350 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5351 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5352 /// `max(self.significant_bits(), prec)`.
5353 ///
5354 /// # Panics
5355 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
5356 /// representable with `prec` bits.
5357 ///
5358 /// # Examples
5359 /// ```
5360 /// use core::f64::consts::{E, PI, SQRT_2};
5361 /// use malachite_base::rounding_modes::RoundingMode::*;
5362 /// use malachite_float::Float;
5363 /// use malachite_q::Rational;
5364 /// use std::cmp::Ordering::*;
5365 ///
5366 /// let x = Float::from(PI);
5367 /// let y = Float::from(E);
5368 /// let z = Float::from(SQRT_2);
5369 /// let w = Rational::from_signeds(22, 7);
5370 ///
5371 /// let (diff, o) =
5372 /// x.clone()
5373 /// .mul_sub_mul_rational_prec_round(y.clone(), z.clone(), w.clone(), 5, Floor);
5374 /// assert_eq!(diff.to_string(), "4.00");
5375 /// assert_eq!(o, Less);
5376 ///
5377 /// let (diff, o) =
5378 /// x.clone()
5379 /// .mul_sub_mul_rational_prec_round(y.clone(), z.clone(), w.clone(), 5, Ceiling);
5380 /// assert_eq!(diff.to_string(), "4.25");
5381 /// assert_eq!(o, Greater);
5382 ///
5383 /// let (diff, o) =
5384 /// x.clone()
5385 /// .mul_sub_mul_rational_prec_round(y.clone(), z.clone(), w.clone(), 5, Nearest);
5386 /// assert_eq!(diff.to_string(), "4.00");
5387 /// assert_eq!(o, Less);
5388 ///
5389 /// let (diff, o) =
5390 /// x.clone()
5391 /// .mul_sub_mul_rational_prec_round(y.clone(), z.clone(), w.clone(), 20, Floor);
5392 /// assert_eq!(diff.to_string(), "4.0950623");
5393 /// assert_eq!(o, Less);
5394 ///
5395 /// let (diff, o) =
5396 /// x.clone()
5397 /// .mul_sub_mul_rational_prec_round(y.clone(), z.clone(), w.clone(), 20, Ceiling);
5398 /// assert_eq!(diff.to_string(), "4.0950699");
5399 /// assert_eq!(o, Greater);
5400 ///
5401 /// let (diff, o) =
5402 /// x.clone()
5403 /// .mul_sub_mul_rational_prec_round(y.clone(), z.clone(), w.clone(), 20, Nearest);
5404 /// assert_eq!(diff.to_string(), "4.0950623");
5405 /// assert_eq!(o, Less);
5406 /// ```
5407 #[allow(clippy::needless_pass_by_value)]
5408 #[inline]
5409 pub fn mul_sub_mul_rational_prec_round(
5410 self,
5411 y: Self,
5412 z: Self,
5413 w: Rational,
5414 prec: u64,
5415 rm: RoundingMode,
5416 ) -> (Self, Ordering) {
5417 mul_add_mul_rational_helper(&self, &y, &z, &w, true, prec, rm)
5418 }
5419
5420 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
5421 /// rounding the result to the specified precision and with the specified rounding mode; the
5422 /// [`Rational`] enters its product exactly and the products are not rounded before the final
5423 /// subtraction, so there is a single rounding. The [`Float`]s are taken by value and the
5424 /// [`Rational`] by reference. An [`Ordering`] is also returned, indicating whether the rounded
5425 /// diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
5426 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
5427 ///
5428 /// See [`RoundingMode`] for a description of the possible rounding modes.
5429 ///
5430 /// $$
5431 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
5432 /// $$
5433 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5434 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5435 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
5436 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5437 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
5438 ///
5439 /// If the output has a precision, it is `prec`.
5440 ///
5441 /// Special cases:
5442 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5443 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5444 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5445 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5446 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
5447 /// [`Rational`] counts as an unsigned zero and a positive sign.
5448 /// - If exactly one product is infinite, the result is that product's infinity, the second
5449 /// product's sign counting as flipped.
5450 /// - If both products are infinite, the result is their common infinity if their signs differ,
5451 /// and `NaN` otherwise.
5452 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
5453 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
5454 /// `Floor`
5455 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
5456 ///
5457 /// Overflow and underflow:
5458 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5459 /// returned instead.
5460 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
5461 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5462 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5463 /// returned instead.
5464 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5465 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5466 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
5467 /// instead.
5468 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5469 /// instead.
5470 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5471 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5472 /// returned instead.
5473 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5474 /// instead.
5475 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5476 /// instead.
5477 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
5478 /// instead.
5479 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5480 /// returned instead.
5481 ///
5482 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_rational_prec`]
5483 /// instead. If you know that your target precision is the maximum of the precisions of the
5484 /// inputs, consider using [`Float::mul_sub_mul_rational_round`] instead. If both of these
5485 /// things are true, consider using
5486 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
5487 ///
5488 /// # Worst-case complexity
5489 /// $T(n, m) = O(n \log n \log\log n + m)$
5490 ///
5491 /// $M(n, m) = O(n \log n + m)$
5492 ///
5493 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5494 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5495 /// `max(self.significant_bits(), prec)`.
5496 ///
5497 /// # Panics
5498 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
5499 /// representable with `prec` bits.
5500 ///
5501 /// # Examples
5502 /// ```
5503 /// use core::f64::consts::{E, PI, SQRT_2};
5504 /// use malachite_base::rounding_modes::RoundingMode::*;
5505 /// use malachite_float::Float;
5506 /// use malachite_q::Rational;
5507 /// use std::cmp::Ordering::*;
5508 ///
5509 /// let x = Float::from(PI);
5510 /// let y = Float::from(E);
5511 /// let z = Float::from(SQRT_2);
5512 /// let w = Rational::from_signeds(22, 7);
5513 ///
5514 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_val_ref(
5515 /// y.clone(),
5516 /// z.clone(),
5517 /// &w,
5518 /// 5,
5519 /// Floor,
5520 /// );
5521 /// assert_eq!(diff.to_string(), "4.00");
5522 /// assert_eq!(o, Less);
5523 ///
5524 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_val_ref(
5525 /// y.clone(),
5526 /// z.clone(),
5527 /// &w,
5528 /// 5,
5529 /// Ceiling,
5530 /// );
5531 /// assert_eq!(diff.to_string(), "4.25");
5532 /// assert_eq!(o, Greater);
5533 ///
5534 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_val_ref(
5535 /// y.clone(),
5536 /// z.clone(),
5537 /// &w,
5538 /// 5,
5539 /// Nearest,
5540 /// );
5541 /// assert_eq!(diff.to_string(), "4.00");
5542 /// assert_eq!(o, Less);
5543 ///
5544 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_val_ref(
5545 /// y.clone(),
5546 /// z.clone(),
5547 /// &w,
5548 /// 20,
5549 /// Floor,
5550 /// );
5551 /// assert_eq!(diff.to_string(), "4.0950623");
5552 /// assert_eq!(o, Less);
5553 ///
5554 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_val_ref(
5555 /// y.clone(),
5556 /// z.clone(),
5557 /// &w,
5558 /// 20,
5559 /// Ceiling,
5560 /// );
5561 /// assert_eq!(diff.to_string(), "4.0950699");
5562 /// assert_eq!(o, Greater);
5563 ///
5564 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_val_ref(
5565 /// y.clone(),
5566 /// z.clone(),
5567 /// &w,
5568 /// 20,
5569 /// Nearest,
5570 /// );
5571 /// assert_eq!(diff.to_string(), "4.0950623");
5572 /// assert_eq!(o, Less);
5573 /// ```
5574 #[allow(clippy::needless_pass_by_value)]
5575 #[inline]
5576 pub fn mul_sub_mul_rational_prec_round_val_val_val_ref(
5577 self,
5578 y: Self,
5579 z: Self,
5580 w: &Rational,
5581 prec: u64,
5582 rm: RoundingMode,
5583 ) -> (Self, Ordering) {
5584 mul_add_mul_rational_helper(&self, &y, &z, w, true, prec, rm)
5585 }
5586
5587 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
5588 /// rounding the result to the specified precision and with the specified rounding mode; the
5589 /// [`Rational`] enters its product exactly and the products are not rounded before the final
5590 /// subtraction, so there is a single rounding. The third [`Float`] is taken by reference and
5591 /// the other operands by value. An [`Ordering`] is also returned, indicating whether the
5592 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
5593 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
5594 ///
5595 /// See [`RoundingMode`] for a description of the possible rounding modes.
5596 ///
5597 /// $$
5598 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
5599 /// $$
5600 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5601 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5602 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
5603 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5604 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
5605 ///
5606 /// If the output has a precision, it is `prec`.
5607 ///
5608 /// Special cases:
5609 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5610 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5611 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5612 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5613 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
5614 /// [`Rational`] counts as an unsigned zero and a positive sign.
5615 /// - If exactly one product is infinite, the result is that product's infinity, the second
5616 /// product's sign counting as flipped.
5617 /// - If both products are infinite, the result is their common infinity if their signs differ,
5618 /// and `NaN` otherwise.
5619 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
5620 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
5621 /// `Floor`
5622 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
5623 ///
5624 /// Overflow and underflow:
5625 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5626 /// returned instead.
5627 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
5628 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5629 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5630 /// returned instead.
5631 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5632 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5633 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
5634 /// instead.
5635 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5636 /// instead.
5637 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5638 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5639 /// returned instead.
5640 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5641 /// instead.
5642 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5643 /// instead.
5644 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
5645 /// instead.
5646 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5647 /// returned instead.
5648 ///
5649 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_rational_prec`]
5650 /// instead. If you know that your target precision is the maximum of the precisions of the
5651 /// inputs, consider using [`Float::mul_sub_mul_rational_round`] instead. If both of these
5652 /// things are true, consider using
5653 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
5654 ///
5655 /// # Worst-case complexity
5656 /// $T(n, m) = O(n \log n \log\log n + m)$
5657 ///
5658 /// $M(n, m) = O(n \log n + m)$
5659 ///
5660 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5661 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5662 /// `max(self.significant_bits(), prec)`.
5663 ///
5664 /// # Panics
5665 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
5666 /// representable with `prec` bits.
5667 ///
5668 /// # Examples
5669 /// ```
5670 /// use core::f64::consts::{E, PI, SQRT_2};
5671 /// use malachite_base::rounding_modes::RoundingMode::*;
5672 /// use malachite_float::Float;
5673 /// use malachite_q::Rational;
5674 /// use std::cmp::Ordering::*;
5675 ///
5676 /// let x = Float::from(PI);
5677 /// let y = Float::from(E);
5678 /// let z = Float::from(SQRT_2);
5679 /// let w = Rational::from_signeds(22, 7);
5680 ///
5681 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_ref_val(
5682 /// y.clone(),
5683 /// &z,
5684 /// w.clone(),
5685 /// 5,
5686 /// Floor,
5687 /// );
5688 /// assert_eq!(diff.to_string(), "4.00");
5689 /// assert_eq!(o, Less);
5690 ///
5691 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_ref_val(
5692 /// y.clone(),
5693 /// &z,
5694 /// w.clone(),
5695 /// 5,
5696 /// Ceiling,
5697 /// );
5698 /// assert_eq!(diff.to_string(), "4.25");
5699 /// assert_eq!(o, Greater);
5700 ///
5701 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_ref_val(
5702 /// y.clone(),
5703 /// &z,
5704 /// w.clone(),
5705 /// 5,
5706 /// Nearest,
5707 /// );
5708 /// assert_eq!(diff.to_string(), "4.00");
5709 /// assert_eq!(o, Less);
5710 ///
5711 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_ref_val(
5712 /// y.clone(),
5713 /// &z,
5714 /// w.clone(),
5715 /// 20,
5716 /// Floor,
5717 /// );
5718 /// assert_eq!(diff.to_string(), "4.0950623");
5719 /// assert_eq!(o, Less);
5720 ///
5721 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_ref_val(
5722 /// y.clone(),
5723 /// &z,
5724 /// w.clone(),
5725 /// 20,
5726 /// Ceiling,
5727 /// );
5728 /// assert_eq!(diff.to_string(), "4.0950699");
5729 /// assert_eq!(o, Greater);
5730 ///
5731 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_ref_val(
5732 /// y.clone(),
5733 /// &z,
5734 /// w.clone(),
5735 /// 20,
5736 /// Nearest,
5737 /// );
5738 /// assert_eq!(diff.to_string(), "4.0950623");
5739 /// assert_eq!(o, Less);
5740 /// ```
5741 #[allow(clippy::needless_pass_by_value)]
5742 #[inline]
5743 pub fn mul_sub_mul_rational_prec_round_val_val_ref_val(
5744 self,
5745 y: Self,
5746 z: &Self,
5747 w: Rational,
5748 prec: u64,
5749 rm: RoundingMode,
5750 ) -> (Self, Ordering) {
5751 mul_add_mul_rational_helper(&self, &y, z, &w, true, prec, rm)
5752 }
5753
5754 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
5755 /// rounding the result to the specified precision and with the specified rounding mode; the
5756 /// [`Rational`] enters its product exactly and the products are not rounded before the final
5757 /// subtraction, so there is a single rounding. The first two [`Float`]s are taken by value and
5758 /// the third [`Float`] and the [`Rational`] by reference. An [`Ordering`] is also returned,
5759 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
5760 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
5761 /// it also returns `Equal`.
5762 ///
5763 /// See [`RoundingMode`] for a description of the possible rounding modes.
5764 ///
5765 /// $$
5766 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
5767 /// $$
5768 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5769 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5770 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
5771 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5772 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
5773 ///
5774 /// If the output has a precision, it is `prec`.
5775 ///
5776 /// Special cases:
5777 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5778 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5779 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5780 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5781 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
5782 /// [`Rational`] counts as an unsigned zero and a positive sign.
5783 /// - If exactly one product is infinite, the result is that product's infinity, the second
5784 /// product's sign counting as flipped.
5785 /// - If both products are infinite, the result is their common infinity if their signs differ,
5786 /// and `NaN` otherwise.
5787 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
5788 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
5789 /// `Floor`
5790 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
5791 ///
5792 /// Overflow and underflow:
5793 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5794 /// returned instead.
5795 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
5796 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5797 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5798 /// returned instead.
5799 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5800 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5801 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
5802 /// instead.
5803 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5804 /// instead.
5805 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5806 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5807 /// returned instead.
5808 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5809 /// instead.
5810 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5811 /// instead.
5812 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
5813 /// instead.
5814 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5815 /// returned instead.
5816 ///
5817 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_rational_prec`]
5818 /// instead. If you know that your target precision is the maximum of the precisions of the
5819 /// inputs, consider using [`Float::mul_sub_mul_rational_round`] instead. If both of these
5820 /// things are true, consider using
5821 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
5822 ///
5823 /// # Worst-case complexity
5824 /// $T(n, m) = O(n \log n \log\log n + m)$
5825 ///
5826 /// $M(n, m) = O(n \log n + m)$
5827 ///
5828 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5829 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5830 /// `max(self.significant_bits(), prec)`.
5831 ///
5832 /// # Panics
5833 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
5834 /// representable with `prec` bits.
5835 ///
5836 /// # Examples
5837 /// ```
5838 /// use core::f64::consts::{E, PI, SQRT_2};
5839 /// use malachite_base::rounding_modes::RoundingMode::*;
5840 /// use malachite_float::Float;
5841 /// use malachite_q::Rational;
5842 /// use std::cmp::Ordering::*;
5843 ///
5844 /// let x = Float::from(PI);
5845 /// let y = Float::from(E);
5846 /// let z = Float::from(SQRT_2);
5847 /// let w = Rational::from_signeds(22, 7);
5848 ///
5849 /// let (diff, o) =
5850 /// x.clone()
5851 /// .mul_sub_mul_rational_prec_round_val_val_ref_ref(y.clone(), &z, &w, 5, Floor);
5852 /// assert_eq!(diff.to_string(), "4.00");
5853 /// assert_eq!(o, Less);
5854 ///
5855 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_ref_ref(
5856 /// y.clone(),
5857 /// &z,
5858 /// &w,
5859 /// 5,
5860 /// Ceiling,
5861 /// );
5862 /// assert_eq!(diff.to_string(), "4.25");
5863 /// assert_eq!(o, Greater);
5864 ///
5865 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_ref_ref(
5866 /// y.clone(),
5867 /// &z,
5868 /// &w,
5869 /// 5,
5870 /// Nearest,
5871 /// );
5872 /// assert_eq!(diff.to_string(), "4.00");
5873 /// assert_eq!(o, Less);
5874 ///
5875 /// let (diff, o) =
5876 /// x.clone()
5877 /// .mul_sub_mul_rational_prec_round_val_val_ref_ref(y.clone(), &z, &w, 20, Floor);
5878 /// assert_eq!(diff.to_string(), "4.0950623");
5879 /// assert_eq!(o, Less);
5880 ///
5881 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_ref_ref(
5882 /// y.clone(),
5883 /// &z,
5884 /// &w,
5885 /// 20,
5886 /// Ceiling,
5887 /// );
5888 /// assert_eq!(diff.to_string(), "4.0950699");
5889 /// assert_eq!(o, Greater);
5890 ///
5891 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_val_ref_ref(
5892 /// y.clone(),
5893 /// &z,
5894 /// &w,
5895 /// 20,
5896 /// Nearest,
5897 /// );
5898 /// assert_eq!(diff.to_string(), "4.0950623");
5899 /// assert_eq!(o, Less);
5900 /// ```
5901 #[allow(clippy::needless_pass_by_value)]
5902 #[inline]
5903 pub fn mul_sub_mul_rational_prec_round_val_val_ref_ref(
5904 self,
5905 y: Self,
5906 z: &Self,
5907 w: &Rational,
5908 prec: u64,
5909 rm: RoundingMode,
5910 ) -> (Self, Ordering) {
5911 mul_add_mul_rational_helper(&self, &y, z, w, true, prec, rm)
5912 }
5913
5914 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
5915 /// rounding the result to the specified precision and with the specified rounding mode; the
5916 /// [`Rational`] enters its product exactly and the products are not rounded before the final
5917 /// subtraction, so there is a single rounding. The second [`Float`] is taken by reference and
5918 /// the other operands by value. An [`Ordering`] is also returned, indicating whether the
5919 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
5920 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
5921 ///
5922 /// See [`RoundingMode`] for a description of the possible rounding modes.
5923 ///
5924 /// $$
5925 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
5926 /// $$
5927 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5928 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5929 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
5930 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5931 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
5932 ///
5933 /// If the output has a precision, it is `prec`.
5934 ///
5935 /// Special cases:
5936 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5937 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5938 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
5939 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
5940 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
5941 /// [`Rational`] counts as an unsigned zero and a positive sign.
5942 /// - If exactly one product is infinite, the result is that product's infinity, the second
5943 /// product's sign counting as flipped.
5944 /// - If both products are infinite, the result is their common infinity if their signs differ,
5945 /// and `NaN` otherwise.
5946 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
5947 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
5948 /// `Floor`
5949 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
5950 ///
5951 /// Overflow and underflow:
5952 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5953 /// returned instead.
5954 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
5955 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5956 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5957 /// returned instead.
5958 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5959 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5960 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
5961 /// instead.
5962 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5963 /// instead.
5964 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5965 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5966 /// returned instead.
5967 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5968 /// instead.
5969 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5970 /// instead.
5971 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
5972 /// instead.
5973 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5974 /// returned instead.
5975 ///
5976 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_rational_prec`]
5977 /// instead. If you know that your target precision is the maximum of the precisions of the
5978 /// inputs, consider using [`Float::mul_sub_mul_rational_round`] instead. If both of these
5979 /// things are true, consider using
5980 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
5981 ///
5982 /// # Worst-case complexity
5983 /// $T(n, m) = O(n \log n \log\log n + m)$
5984 ///
5985 /// $M(n, m) = O(n \log n + m)$
5986 ///
5987 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5988 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
5989 /// `max(self.significant_bits(), prec)`.
5990 ///
5991 /// # Panics
5992 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
5993 /// representable with `prec` bits.
5994 ///
5995 /// # Examples
5996 /// ```
5997 /// use core::f64::consts::{E, PI, SQRT_2};
5998 /// use malachite_base::rounding_modes::RoundingMode::*;
5999 /// use malachite_float::Float;
6000 /// use malachite_q::Rational;
6001 /// use std::cmp::Ordering::*;
6002 ///
6003 /// let x = Float::from(PI);
6004 /// let y = Float::from(E);
6005 /// let z = Float::from(SQRT_2);
6006 /// let w = Rational::from_signeds(22, 7);
6007 ///
6008 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_ref_val_val(
6009 /// &y,
6010 /// z.clone(),
6011 /// w.clone(),
6012 /// 5,
6013 /// Floor,
6014 /// );
6015 /// assert_eq!(diff.to_string(), "4.00");
6016 /// assert_eq!(o, Less);
6017 ///
6018 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_ref_val_val(
6019 /// &y,
6020 /// z.clone(),
6021 /// w.clone(),
6022 /// 5,
6023 /// Ceiling,
6024 /// );
6025 /// assert_eq!(diff.to_string(), "4.25");
6026 /// assert_eq!(o, Greater);
6027 ///
6028 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_ref_val_val(
6029 /// &y,
6030 /// z.clone(),
6031 /// w.clone(),
6032 /// 5,
6033 /// Nearest,
6034 /// );
6035 /// assert_eq!(diff.to_string(), "4.00");
6036 /// assert_eq!(o, Less);
6037 ///
6038 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_ref_val_val(
6039 /// &y,
6040 /// z.clone(),
6041 /// w.clone(),
6042 /// 20,
6043 /// Floor,
6044 /// );
6045 /// assert_eq!(diff.to_string(), "4.0950623");
6046 /// assert_eq!(o, Less);
6047 ///
6048 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_ref_val_val(
6049 /// &y,
6050 /// z.clone(),
6051 /// w.clone(),
6052 /// 20,
6053 /// Ceiling,
6054 /// );
6055 /// assert_eq!(diff.to_string(), "4.0950699");
6056 /// assert_eq!(o, Greater);
6057 ///
6058 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_ref_val_val(
6059 /// &y,
6060 /// z.clone(),
6061 /// w.clone(),
6062 /// 20,
6063 /// Nearest,
6064 /// );
6065 /// assert_eq!(diff.to_string(), "4.0950623");
6066 /// assert_eq!(o, Less);
6067 /// ```
6068 #[allow(clippy::needless_pass_by_value)]
6069 #[inline]
6070 pub fn mul_sub_mul_rational_prec_round_val_ref_val_val(
6071 self,
6072 y: &Self,
6073 z: Self,
6074 w: Rational,
6075 prec: u64,
6076 rm: RoundingMode,
6077 ) -> (Self, Ordering) {
6078 mul_add_mul_rational_helper(&self, y, &z, &w, true, prec, rm)
6079 }
6080
6081 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
6082 /// rounding the result to the specified precision and with the specified rounding mode; the
6083 /// [`Rational`] enters its product exactly and the products are not rounded before the final
6084 /// subtraction, so there is a single rounding. The second [`Float`] and the [`Rational`] are
6085 /// taken by reference and the other operands by value. An [`Ordering`] is also returned,
6086 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
6087 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
6088 /// it also returns `Equal`.
6089 ///
6090 /// See [`RoundingMode`] for a description of the possible rounding modes.
6091 ///
6092 /// $$
6093 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
6094 /// $$
6095 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6096 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6097 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
6098 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6099 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
6100 ///
6101 /// If the output has a precision, it is `prec`.
6102 ///
6103 /// Special cases:
6104 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6105 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6106 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6107 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6108 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
6109 /// [`Rational`] counts as an unsigned zero and a positive sign.
6110 /// - If exactly one product is infinite, the result is that product's infinity, the second
6111 /// product's sign counting as flipped.
6112 /// - If both products are infinite, the result is their common infinity if their signs differ,
6113 /// and `NaN` otherwise.
6114 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
6115 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
6116 /// `Floor`
6117 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
6118 ///
6119 /// Overflow and underflow:
6120 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
6121 /// returned instead.
6122 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
6123 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6124 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
6125 /// returned instead.
6126 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
6127 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6128 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
6129 /// instead.
6130 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
6131 /// instead.
6132 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
6133 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
6134 /// returned instead.
6135 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
6136 /// instead.
6137 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
6138 /// instead.
6139 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
6140 /// instead.
6141 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
6142 /// returned instead.
6143 ///
6144 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_rational_prec`]
6145 /// instead. If you know that your target precision is the maximum of the precisions of the
6146 /// inputs, consider using [`Float::mul_sub_mul_rational_round`] instead. If both of these
6147 /// things are true, consider using
6148 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
6149 ///
6150 /// # Worst-case complexity
6151 /// $T(n, m) = O(n \log n \log\log n + m)$
6152 ///
6153 /// $M(n, m) = O(n \log n + m)$
6154 ///
6155 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6156 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
6157 /// `max(self.significant_bits(), prec)`.
6158 ///
6159 /// # Panics
6160 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
6161 /// representable with `prec` bits.
6162 ///
6163 /// # Examples
6164 /// ```
6165 /// use core::f64::consts::{E, PI, SQRT_2};
6166 /// use malachite_base::rounding_modes::RoundingMode::*;
6167 /// use malachite_float::Float;
6168 /// use malachite_q::Rational;
6169 /// use std::cmp::Ordering::*;
6170 ///
6171 /// let x = Float::from(PI);
6172 /// let y = Float::from(E);
6173 /// let z = Float::from(SQRT_2);
6174 /// let w = Rational::from_signeds(22, 7);
6175 ///
6176 /// let (diff, o) =
6177 /// x.clone()
6178 /// .mul_sub_mul_rational_prec_round_val_ref_val_ref(&y, z.clone(), &w, 5, Floor);
6179 /// assert_eq!(diff.to_string(), "4.00");
6180 /// assert_eq!(o, Less);
6181 ///
6182 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_ref_val_ref(
6183 /// &y,
6184 /// z.clone(),
6185 /// &w,
6186 /// 5,
6187 /// Ceiling,
6188 /// );
6189 /// assert_eq!(diff.to_string(), "4.25");
6190 /// assert_eq!(o, Greater);
6191 ///
6192 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_ref_val_ref(
6193 /// &y,
6194 /// z.clone(),
6195 /// &w,
6196 /// 5,
6197 /// Nearest,
6198 /// );
6199 /// assert_eq!(diff.to_string(), "4.00");
6200 /// assert_eq!(o, Less);
6201 ///
6202 /// let (diff, o) =
6203 /// x.clone()
6204 /// .mul_sub_mul_rational_prec_round_val_ref_val_ref(&y, z.clone(), &w, 20, Floor);
6205 /// assert_eq!(diff.to_string(), "4.0950623");
6206 /// assert_eq!(o, Less);
6207 ///
6208 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_ref_val_ref(
6209 /// &y,
6210 /// z.clone(),
6211 /// &w,
6212 /// 20,
6213 /// Ceiling,
6214 /// );
6215 /// assert_eq!(diff.to_string(), "4.0950699");
6216 /// assert_eq!(o, Greater);
6217 ///
6218 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_ref_val_ref(
6219 /// &y,
6220 /// z.clone(),
6221 /// &w,
6222 /// 20,
6223 /// Nearest,
6224 /// );
6225 /// assert_eq!(diff.to_string(), "4.0950623");
6226 /// assert_eq!(o, Less);
6227 /// ```
6228 #[allow(clippy::needless_pass_by_value)]
6229 #[inline]
6230 pub fn mul_sub_mul_rational_prec_round_val_ref_val_ref(
6231 self,
6232 y: &Self,
6233 z: Self,
6234 w: &Rational,
6235 prec: u64,
6236 rm: RoundingMode,
6237 ) -> (Self, Ordering) {
6238 mul_add_mul_rational_helper(&self, y, &z, w, true, prec, rm)
6239 }
6240
6241 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
6242 /// rounding the result to the specified precision and with the specified rounding mode; the
6243 /// [`Rational`] enters its product exactly and the products are not rounded before the final
6244 /// subtraction, so there is a single rounding. The second and third [`Float`]s are taken by
6245 /// reference and the other operands by value. An [`Ordering`] is also returned, indicating
6246 /// whether the rounded diff is less than, equal to, or greater than the exact diff. Although
6247 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
6248 /// returns `Equal`.
6249 ///
6250 /// See [`RoundingMode`] for a description of the possible rounding modes.
6251 ///
6252 /// $$
6253 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
6254 /// $$
6255 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6256 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6257 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
6258 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6259 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
6260 ///
6261 /// If the output has a precision, it is `prec`.
6262 ///
6263 /// Special cases:
6264 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6265 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6266 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6267 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6268 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
6269 /// [`Rational`] counts as an unsigned zero and a positive sign.
6270 /// - If exactly one product is infinite, the result is that product's infinity, the second
6271 /// product's sign counting as flipped.
6272 /// - If both products are infinite, the result is their common infinity if their signs differ,
6273 /// and `NaN` otherwise.
6274 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
6275 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
6276 /// `Floor`
6277 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
6278 ///
6279 /// Overflow and underflow:
6280 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
6281 /// returned instead.
6282 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
6283 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6284 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
6285 /// returned instead.
6286 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
6287 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6288 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
6289 /// instead.
6290 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
6291 /// instead.
6292 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
6293 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
6294 /// returned instead.
6295 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
6296 /// instead.
6297 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
6298 /// instead.
6299 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
6300 /// instead.
6301 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
6302 /// returned instead.
6303 ///
6304 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_rational_prec`]
6305 /// instead. If you know that your target precision is the maximum of the precisions of the
6306 /// inputs, consider using [`Float::mul_sub_mul_rational_round`] instead. If both of these
6307 /// things are true, consider using
6308 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
6309 ///
6310 /// # Worst-case complexity
6311 /// $T(n, m) = O(n \log n \log\log n + m)$
6312 ///
6313 /// $M(n, m) = O(n \log n + m)$
6314 ///
6315 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6316 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
6317 /// `max(self.significant_bits(), prec)`.
6318 ///
6319 /// # Panics
6320 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
6321 /// representable with `prec` bits.
6322 ///
6323 /// # Examples
6324 /// ```
6325 /// use core::f64::consts::{E, PI, SQRT_2};
6326 /// use malachite_base::rounding_modes::RoundingMode::*;
6327 /// use malachite_float::Float;
6328 /// use malachite_q::Rational;
6329 /// use std::cmp::Ordering::*;
6330 ///
6331 /// let x = Float::from(PI);
6332 /// let y = Float::from(E);
6333 /// let z = Float::from(SQRT_2);
6334 /// let w = Rational::from_signeds(22, 7);
6335 ///
6336 /// let (diff, o) =
6337 /// x.clone()
6338 /// .mul_sub_mul_rational_prec_round_val_ref_ref_val(&y, &z, w.clone(), 5, Floor);
6339 /// assert_eq!(diff.to_string(), "4.00");
6340 /// assert_eq!(o, Less);
6341 ///
6342 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_ref_ref_val(
6343 /// &y,
6344 /// &z,
6345 /// w.clone(),
6346 /// 5,
6347 /// Ceiling,
6348 /// );
6349 /// assert_eq!(diff.to_string(), "4.25");
6350 /// assert_eq!(o, Greater);
6351 ///
6352 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_ref_ref_val(
6353 /// &y,
6354 /// &z,
6355 /// w.clone(),
6356 /// 5,
6357 /// Nearest,
6358 /// );
6359 /// assert_eq!(diff.to_string(), "4.00");
6360 /// assert_eq!(o, Less);
6361 ///
6362 /// let (diff, o) =
6363 /// x.clone()
6364 /// .mul_sub_mul_rational_prec_round_val_ref_ref_val(&y, &z, w.clone(), 20, Floor);
6365 /// assert_eq!(diff.to_string(), "4.0950623");
6366 /// assert_eq!(o, Less);
6367 ///
6368 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_ref_ref_val(
6369 /// &y,
6370 /// &z,
6371 /// w.clone(),
6372 /// 20,
6373 /// Ceiling,
6374 /// );
6375 /// assert_eq!(diff.to_string(), "4.0950699");
6376 /// assert_eq!(o, Greater);
6377 ///
6378 /// let (diff, o) = x.clone().mul_sub_mul_rational_prec_round_val_ref_ref_val(
6379 /// &y,
6380 /// &z,
6381 /// w.clone(),
6382 /// 20,
6383 /// Nearest,
6384 /// );
6385 /// assert_eq!(diff.to_string(), "4.0950623");
6386 /// assert_eq!(o, Less);
6387 /// ```
6388 #[allow(clippy::needless_pass_by_value)]
6389 #[inline]
6390 pub fn mul_sub_mul_rational_prec_round_val_ref_ref_val(
6391 self,
6392 y: &Self,
6393 z: &Self,
6394 w: Rational,
6395 prec: u64,
6396 rm: RoundingMode,
6397 ) -> (Self, Ordering) {
6398 mul_add_mul_rational_helper(&self, y, z, &w, true, prec, rm)
6399 }
6400
6401 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
6402 /// rounding the result to the specified precision and with the specified rounding mode; the
6403 /// [`Rational`] enters its product exactly and the products are not rounded before the final
6404 /// subtraction, so there is a single rounding. The first [`Float`] is taken by value and the
6405 /// other operands by reference. An [`Ordering`] is also returned, indicating whether the
6406 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
6407 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
6408 ///
6409 /// See [`RoundingMode`] for a description of the possible rounding modes.
6410 ///
6411 /// $$
6412 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
6413 /// $$
6414 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6415 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6416 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
6417 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6418 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
6419 ///
6420 /// If the output has a precision, it is `prec`.
6421 ///
6422 /// Special cases:
6423 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6424 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6425 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6426 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6427 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
6428 /// [`Rational`] counts as an unsigned zero and a positive sign.
6429 /// - If exactly one product is infinite, the result is that product's infinity, the second
6430 /// product's sign counting as flipped.
6431 /// - If both products are infinite, the result is their common infinity if their signs differ,
6432 /// and `NaN` otherwise.
6433 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
6434 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
6435 /// `Floor`
6436 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
6437 ///
6438 /// Overflow and underflow:
6439 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
6440 /// returned instead.
6441 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
6442 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6443 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
6444 /// returned instead.
6445 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
6446 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6447 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
6448 /// instead.
6449 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
6450 /// instead.
6451 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
6452 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
6453 /// returned instead.
6454 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
6455 /// instead.
6456 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
6457 /// instead.
6458 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
6459 /// instead.
6460 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
6461 /// returned instead.
6462 ///
6463 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_rational_prec`]
6464 /// instead. If you know that your target precision is the maximum of the precisions of the
6465 /// inputs, consider using [`Float::mul_sub_mul_rational_round`] instead. If both of these
6466 /// things are true, consider using
6467 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
6468 ///
6469 /// # Worst-case complexity
6470 /// $T(n, m) = O(n \log n \log\log n + m)$
6471 ///
6472 /// $M(n, m) = O(n \log n + m)$
6473 ///
6474 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6475 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
6476 /// `max(self.significant_bits(), prec)`.
6477 ///
6478 /// # Panics
6479 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
6480 /// representable with `prec` bits.
6481 ///
6482 /// # Examples
6483 /// ```
6484 /// use core::f64::consts::{E, PI, SQRT_2};
6485 /// use malachite_base::rounding_modes::RoundingMode::*;
6486 /// use malachite_float::Float;
6487 /// use malachite_q::Rational;
6488 /// use std::cmp::Ordering::*;
6489 ///
6490 /// let x = Float::from(PI);
6491 /// let y = Float::from(E);
6492 /// let z = Float::from(SQRT_2);
6493 /// let w = Rational::from_signeds(22, 7);
6494 ///
6495 /// let (diff, o) = x
6496 /// .clone()
6497 /// .mul_sub_mul_rational_prec_round_val_ref_ref_ref(&y, &z, &w, 5, Floor);
6498 /// assert_eq!(diff.to_string(), "4.00");
6499 /// assert_eq!(o, Less);
6500 ///
6501 /// let (diff, o) = x
6502 /// .clone()
6503 /// .mul_sub_mul_rational_prec_round_val_ref_ref_ref(&y, &z, &w, 5, Ceiling);
6504 /// assert_eq!(diff.to_string(), "4.25");
6505 /// assert_eq!(o, Greater);
6506 ///
6507 /// let (diff, o) = x
6508 /// .clone()
6509 /// .mul_sub_mul_rational_prec_round_val_ref_ref_ref(&y, &z, &w, 5, Nearest);
6510 /// assert_eq!(diff.to_string(), "4.00");
6511 /// assert_eq!(o, Less);
6512 ///
6513 /// let (diff, o) = x
6514 /// .clone()
6515 /// .mul_sub_mul_rational_prec_round_val_ref_ref_ref(&y, &z, &w, 20, Floor);
6516 /// assert_eq!(diff.to_string(), "4.0950623");
6517 /// assert_eq!(o, Less);
6518 ///
6519 /// let (diff, o) = x
6520 /// .clone()
6521 /// .mul_sub_mul_rational_prec_round_val_ref_ref_ref(&y, &z, &w, 20, Ceiling);
6522 /// assert_eq!(diff.to_string(), "4.0950699");
6523 /// assert_eq!(o, Greater);
6524 ///
6525 /// let (diff, o) = x
6526 /// .clone()
6527 /// .mul_sub_mul_rational_prec_round_val_ref_ref_ref(&y, &z, &w, 20, Nearest);
6528 /// assert_eq!(diff.to_string(), "4.0950623");
6529 /// assert_eq!(o, Less);
6530 /// ```
6531 #[allow(clippy::needless_pass_by_value)]
6532 #[inline]
6533 pub fn mul_sub_mul_rational_prec_round_val_ref_ref_ref(
6534 self,
6535 y: &Self,
6536 z: &Self,
6537 w: &Rational,
6538 prec: u64,
6539 rm: RoundingMode,
6540 ) -> (Self, Ordering) {
6541 mul_add_mul_rational_helper(&self, y, z, w, true, prec, rm)
6542 }
6543
6544 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
6545 /// rounding the result to the specified precision and with the specified rounding mode; the
6546 /// [`Rational`] enters its product exactly and the products are not rounded before the final
6547 /// subtraction, so there is a single rounding. The [`Float`]s and the [`Rational`] are all
6548 /// taken by reference. An [`Ordering`] is also returned, indicating whether the rounded diff is
6549 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
6550 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
6551 ///
6552 /// See [`RoundingMode`] for a description of the possible rounding modes.
6553 ///
6554 /// $$
6555 /// f(x,y,z,w,p,m) = xy-zw+\varepsilon.
6556 /// $$
6557 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6558 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6559 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
6560 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6561 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
6562 ///
6563 /// If the output has a precision, it is `prec`.
6564 ///
6565 /// Special cases:
6566 /// - $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6567 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6568 /// $f(\text{NaN},y,z,w,p,m)=f(x,\text{NaN},z,w,p,m)=f(x,y,\text{NaN},w,p,m)=
6569 /// f(x,y,z,\text{NaN},p,m)=\text{NaN}$
6570 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
6571 /// [`Rational`] counts as an unsigned zero and a positive sign.
6572 /// - If exactly one product is infinite, the result is that product's infinity, the second
6573 /// product's sign counting as flipped.
6574 /// - If both products are infinite, the result is their common infinity if their signs differ,
6575 /// and `NaN` otherwise.
6576 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
6577 /// - $f(x,y,z,w,p,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not
6578 /// `Floor`
6579 /// - $f(x,y,z,w,p,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
6580 ///
6581 /// Overflow and underflow:
6582 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
6583 /// returned instead.
6584 /// - If $f(x,y,z,w,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`,
6585 /// $(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6586 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
6587 /// returned instead.
6588 /// - If $f(x,y,z,w,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
6589 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6590 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned
6591 /// instead.
6592 /// - If $0<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
6593 /// instead.
6594 /// - If $0<f(x,y,z,w,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
6595 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
6596 /// returned instead.
6597 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
6598 /// instead.
6599 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
6600 /// instead.
6601 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned
6602 /// instead.
6603 /// - If $-2^{-2^{30}}<f(x,y,z,w,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
6604 /// returned instead.
6605 ///
6606 /// If you know you'll be using `Nearest`, consider using [`Float::mul_sub_mul_rational_prec`]
6607 /// instead. If you know that your target precision is the maximum of the precisions of the
6608 /// inputs, consider using [`Float::mul_sub_mul_rational_round`] instead. If both of these
6609 /// things are true, consider using
6610 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
6611 ///
6612 /// # Worst-case complexity
6613 /// $T(n, m) = O(n \log n \log\log n + m)$
6614 ///
6615 /// $M(n, m) = O(n \log n + m)$
6616 ///
6617 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6618 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
6619 /// `max(self.significant_bits(), prec)`.
6620 ///
6621 /// # Panics
6622 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
6623 /// representable with `prec` bits.
6624 ///
6625 /// # Examples
6626 /// ```
6627 /// use core::f64::consts::{E, PI, SQRT_2};
6628 /// use malachite_base::rounding_modes::RoundingMode::*;
6629 /// use malachite_float::Float;
6630 /// use malachite_q::Rational;
6631 /// use std::cmp::Ordering::*;
6632 ///
6633 /// let x = Float::from(PI);
6634 /// let y = Float::from(E);
6635 /// let z = Float::from(SQRT_2);
6636 /// let w = Rational::from_signeds(22, 7);
6637 ///
6638 /// let (diff, o) = x.mul_sub_mul_rational_prec_round_ref_ref_ref_ref(&y, &z, &w, 5, Floor);
6639 /// assert_eq!(diff.to_string(), "4.00");
6640 /// assert_eq!(o, Less);
6641 ///
6642 /// let (diff, o) = x.mul_sub_mul_rational_prec_round_ref_ref_ref_ref(&y, &z, &w, 5, Ceiling);
6643 /// assert_eq!(diff.to_string(), "4.25");
6644 /// assert_eq!(o, Greater);
6645 ///
6646 /// let (diff, o) = x.mul_sub_mul_rational_prec_round_ref_ref_ref_ref(&y, &z, &w, 5, Nearest);
6647 /// assert_eq!(diff.to_string(), "4.00");
6648 /// assert_eq!(o, Less);
6649 ///
6650 /// let (diff, o) = x.mul_sub_mul_rational_prec_round_ref_ref_ref_ref(&y, &z, &w, 20, Floor);
6651 /// assert_eq!(diff.to_string(), "4.0950623");
6652 /// assert_eq!(o, Less);
6653 ///
6654 /// let (diff, o) = x.mul_sub_mul_rational_prec_round_ref_ref_ref_ref(&y, &z, &w, 20, Ceiling);
6655 /// assert_eq!(diff.to_string(), "4.0950699");
6656 /// assert_eq!(o, Greater);
6657 ///
6658 /// let (diff, o) = x.mul_sub_mul_rational_prec_round_ref_ref_ref_ref(&y, &z, &w, 20, Nearest);
6659 /// assert_eq!(diff.to_string(), "4.0950623");
6660 /// assert_eq!(o, Less);
6661 /// ```
6662 #[allow(clippy::needless_pass_by_value)]
6663 #[inline]
6664 pub fn mul_sub_mul_rational_prec_round_ref_ref_ref_ref(
6665 &self,
6666 y: &Self,
6667 z: &Self,
6668 w: &Rational,
6669 prec: u64,
6670 rm: RoundingMode,
6671 ) -> (Self, Ordering) {
6672 mul_add_mul_rational_helper(self, y, z, w, true, prec, rm)
6673 }
6674
6675 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
6676 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
6677 /// the specified rounding mode. The [`Float`]s on the right-hand side are all taken by value.
6678 /// An [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
6679 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
6680 /// this function assigns a `NaN` it also returns `Equal`.
6681 ///
6682 /// See [`RoundingMode`] for a description of the possible rounding modes.
6683 ///
6684 /// $$
6685 /// x \gets xy-zw+\varepsilon.
6686 /// $$
6687 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6688 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6689 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
6690 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6691 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
6692 ///
6693 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
6694 /// overflow, and underflow.
6695 ///
6696 /// If you know you'll be using `Nearest`, consider using
6697 /// [`Float::mul_sub_mul_rational_prec_assign`] instead. If you know that your target precision
6698 /// is the maximum of the precisions of the inputs, consider using
6699 /// [`Float::mul_sub_mul_rational_round_assign`] instead. If both of these things are true,
6700 /// consider using
6701 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
6702 ///
6703 /// # Worst-case complexity
6704 /// $T(n, m) = O(n \log n \log\log n + m)$
6705 ///
6706 /// $M(n, m) = O(n \log n + m)$
6707 ///
6708 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6709 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
6710 /// `max(self.significant_bits(), prec)`.
6711 ///
6712 /// # Panics
6713 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
6714 /// representable with `prec` bits.
6715 ///
6716 /// # Examples
6717 /// ```
6718 /// use core::f64::consts::{E, PI, SQRT_2};
6719 /// use malachite_base::rounding_modes::RoundingMode::*;
6720 /// use malachite_float::Float;
6721 /// use malachite_q::Rational;
6722 /// use std::cmp::Ordering::*;
6723 ///
6724 /// let y = Float::from(E);
6725 /// let z = Float::from(SQRT_2);
6726 /// let w = Rational::from_signeds(22, 7);
6727 ///
6728 /// let mut x = Float::from(PI);
6729 /// assert_eq!(
6730 /// x.mul_sub_mul_rational_prec_round_assign(y.clone(), z.clone(), w.clone(), 5, Floor),
6731 /// Less
6732 /// );
6733 /// assert_eq!(x.to_string(), "4.00");
6734 ///
6735 /// let mut x = Float::from(PI);
6736 /// assert_eq!(
6737 /// x.mul_sub_mul_rational_prec_round_assign(y.clone(), z.clone(), w.clone(), 5, Ceiling),
6738 /// Greater
6739 /// );
6740 /// assert_eq!(x.to_string(), "4.25");
6741 ///
6742 /// let mut x = Float::from(PI);
6743 /// assert_eq!(
6744 /// x.mul_sub_mul_rational_prec_round_assign(y.clone(), z.clone(), w.clone(), 5, Nearest),
6745 /// Less
6746 /// );
6747 /// assert_eq!(x.to_string(), "4.00");
6748 /// ```
6749 #[allow(clippy::needless_pass_by_value)]
6750 #[inline]
6751 pub fn mul_sub_mul_rational_prec_round_assign(
6752 &mut self,
6753 y: Self,
6754 z: Self,
6755 w: Rational,
6756 prec: u64,
6757 rm: RoundingMode,
6758 ) -> Ordering {
6759 let (s, o) = mul_add_mul_rational_helper(self, &y, &z, &w, true, prec, rm);
6760 *self = s;
6761 o
6762 }
6763
6764 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
6765 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
6766 /// the specified rounding mode. The last [`Float`] on the right-hand side is taken by reference
6767 /// and the others by value. An [`Ordering`] is returned, indicating whether the rounded diff is
6768 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
6769 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
6770 ///
6771 /// See [`RoundingMode`] for a description of the possible rounding modes.
6772 ///
6773 /// $$
6774 /// x \gets xy-zw+\varepsilon.
6775 /// $$
6776 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6777 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6778 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
6779 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6780 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
6781 ///
6782 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
6783 /// overflow, and underflow.
6784 ///
6785 /// If you know you'll be using `Nearest`, consider using
6786 /// [`Float::mul_sub_mul_rational_prec_assign`] instead. If you know that your target precision
6787 /// is the maximum of the precisions of the inputs, consider using
6788 /// [`Float::mul_sub_mul_rational_round_assign`] instead. If both of these things are true,
6789 /// consider using
6790 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
6791 ///
6792 /// # Worst-case complexity
6793 /// $T(n, m) = O(n \log n \log\log n + m)$
6794 ///
6795 /// $M(n, m) = O(n \log n + m)$
6796 ///
6797 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6798 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
6799 /// `max(self.significant_bits(), prec)`.
6800 ///
6801 /// # Panics
6802 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
6803 /// representable with `prec` bits.
6804 ///
6805 /// # Examples
6806 /// ```
6807 /// use core::f64::consts::{E, PI, SQRT_2};
6808 /// use malachite_base::rounding_modes::RoundingMode::*;
6809 /// use malachite_float::Float;
6810 /// use malachite_q::Rational;
6811 /// use std::cmp::Ordering::*;
6812 ///
6813 /// let y = Float::from(E);
6814 /// let z = Float::from(SQRT_2);
6815 /// let w = Rational::from_signeds(22, 7);
6816 ///
6817 /// let mut x = Float::from(PI);
6818 /// assert_eq!(
6819 /// x.mul_sub_mul_rational_prec_round_assign_val_val_ref(
6820 /// y.clone(),
6821 /// z.clone(),
6822 /// &w,
6823 /// 5,
6824 /// Floor
6825 /// ),
6826 /// Less
6827 /// );
6828 /// assert_eq!(x.to_string(), "4.00");
6829 ///
6830 /// let mut x = Float::from(PI);
6831 /// assert_eq!(
6832 /// x.mul_sub_mul_rational_prec_round_assign_val_val_ref(
6833 /// y.clone(),
6834 /// z.clone(),
6835 /// &w,
6836 /// 5,
6837 /// Ceiling
6838 /// ),
6839 /// Greater
6840 /// );
6841 /// assert_eq!(x.to_string(), "4.25");
6842 ///
6843 /// let mut x = Float::from(PI);
6844 /// assert_eq!(
6845 /// x.mul_sub_mul_rational_prec_round_assign_val_val_ref(
6846 /// y.clone(),
6847 /// z.clone(),
6848 /// &w,
6849 /// 5,
6850 /// Nearest
6851 /// ),
6852 /// Less
6853 /// );
6854 /// assert_eq!(x.to_string(), "4.00");
6855 /// ```
6856 #[allow(clippy::needless_pass_by_value)]
6857 #[inline]
6858 pub fn mul_sub_mul_rational_prec_round_assign_val_val_ref(
6859 &mut self,
6860 y: Self,
6861 z: Self,
6862 w: &Rational,
6863 prec: u64,
6864 rm: RoundingMode,
6865 ) -> Ordering {
6866 let (s, o) = mul_add_mul_rational_helper(self, &y, &z, w, true, prec, rm);
6867 *self = s;
6868 o
6869 }
6870
6871 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
6872 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
6873 /// the specified rounding mode. The middle [`Float`] on the right-hand side is taken by
6874 /// reference and the others by value. An [`Ordering`] is returned, indicating whether the
6875 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
6876 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
6877 ///
6878 /// See [`RoundingMode`] for a description of the possible rounding modes.
6879 ///
6880 /// $$
6881 /// x \gets xy-zw+\varepsilon.
6882 /// $$
6883 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6884 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6885 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
6886 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6887 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
6888 ///
6889 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
6890 /// overflow, and underflow.
6891 ///
6892 /// If you know you'll be using `Nearest`, consider using
6893 /// [`Float::mul_sub_mul_rational_prec_assign`] instead. If you know that your target precision
6894 /// is the maximum of the precisions of the inputs, consider using
6895 /// [`Float::mul_sub_mul_rational_round_assign`] instead. If both of these things are true,
6896 /// consider using
6897 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
6898 ///
6899 /// # Worst-case complexity
6900 /// $T(n, m) = O(n \log n \log\log n + m)$
6901 ///
6902 /// $M(n, m) = O(n \log n + m)$
6903 ///
6904 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6905 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
6906 /// `max(self.significant_bits(), prec)`.
6907 ///
6908 /// # Panics
6909 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
6910 /// representable with `prec` bits.
6911 ///
6912 /// # Examples
6913 /// ```
6914 /// use core::f64::consts::{E, PI, SQRT_2};
6915 /// use malachite_base::rounding_modes::RoundingMode::*;
6916 /// use malachite_float::Float;
6917 /// use malachite_q::Rational;
6918 /// use std::cmp::Ordering::*;
6919 ///
6920 /// let y = Float::from(E);
6921 /// let z = Float::from(SQRT_2);
6922 /// let w = Rational::from_signeds(22, 7);
6923 ///
6924 /// let mut x = Float::from(PI);
6925 /// assert_eq!(
6926 /// x.mul_sub_mul_rational_prec_round_assign_val_ref_val(
6927 /// y.clone(),
6928 /// &z,
6929 /// w.clone(),
6930 /// 5,
6931 /// Floor
6932 /// ),
6933 /// Less
6934 /// );
6935 /// assert_eq!(x.to_string(), "4.00");
6936 ///
6937 /// let mut x = Float::from(PI);
6938 /// assert_eq!(
6939 /// x.mul_sub_mul_rational_prec_round_assign_val_ref_val(
6940 /// y.clone(),
6941 /// &z,
6942 /// w.clone(),
6943 /// 5,
6944 /// Ceiling
6945 /// ),
6946 /// Greater
6947 /// );
6948 /// assert_eq!(x.to_string(), "4.25");
6949 ///
6950 /// let mut x = Float::from(PI);
6951 /// assert_eq!(
6952 /// x.mul_sub_mul_rational_prec_round_assign_val_ref_val(
6953 /// y.clone(),
6954 /// &z,
6955 /// w.clone(),
6956 /// 5,
6957 /// Nearest
6958 /// ),
6959 /// Less
6960 /// );
6961 /// assert_eq!(x.to_string(), "4.00");
6962 /// ```
6963 #[allow(clippy::needless_pass_by_value)]
6964 #[inline]
6965 pub fn mul_sub_mul_rational_prec_round_assign_val_ref_val(
6966 &mut self,
6967 y: Self,
6968 z: &Self,
6969 w: Rational,
6970 prec: u64,
6971 rm: RoundingMode,
6972 ) -> Ordering {
6973 let (s, o) = mul_add_mul_rational_helper(self, &y, z, &w, true, prec, rm);
6974 *self = s;
6975 o
6976 }
6977
6978 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
6979 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
6980 /// the specified rounding mode. The first [`Float`] on the right-hand side is taken by value
6981 /// and the others by reference. An [`Ordering`] is returned, indicating whether the rounded
6982 /// diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
6983 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
6984 ///
6985 /// See [`RoundingMode`] for a description of the possible rounding modes.
6986 ///
6987 /// $$
6988 /// x \gets xy-zw+\varepsilon.
6989 /// $$
6990 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6991 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6992 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
6993 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6994 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
6995 ///
6996 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
6997 /// overflow, and underflow.
6998 ///
6999 /// If you know you'll be using `Nearest`, consider using
7000 /// [`Float::mul_sub_mul_rational_prec_assign`] instead. If you know that your target precision
7001 /// is the maximum of the precisions of the inputs, consider using
7002 /// [`Float::mul_sub_mul_rational_round_assign`] instead. If both of these things are true,
7003 /// consider using
7004 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
7005 ///
7006 /// # Worst-case complexity
7007 /// $T(n, m) = O(n \log n \log\log n + m)$
7008 ///
7009 /// $M(n, m) = O(n \log n + m)$
7010 ///
7011 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7012 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7013 /// `max(self.significant_bits(), prec)`.
7014 ///
7015 /// # Panics
7016 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
7017 /// representable with `prec` bits.
7018 ///
7019 /// # Examples
7020 /// ```
7021 /// use core::f64::consts::{E, PI, SQRT_2};
7022 /// use malachite_base::rounding_modes::RoundingMode::*;
7023 /// use malachite_float::Float;
7024 /// use malachite_q::Rational;
7025 /// use std::cmp::Ordering::*;
7026 ///
7027 /// let y = Float::from(E);
7028 /// let z = Float::from(SQRT_2);
7029 /// let w = Rational::from_signeds(22, 7);
7030 ///
7031 /// let mut x = Float::from(PI);
7032 /// assert_eq!(
7033 /// x.mul_sub_mul_rational_prec_round_assign_val_ref_ref(y.clone(), &z, &w, 5, Floor),
7034 /// Less
7035 /// );
7036 /// assert_eq!(x.to_string(), "4.00");
7037 ///
7038 /// let mut x = Float::from(PI);
7039 /// assert_eq!(
7040 /// x.mul_sub_mul_rational_prec_round_assign_val_ref_ref(y.clone(), &z, &w, 5, Ceiling),
7041 /// Greater
7042 /// );
7043 /// assert_eq!(x.to_string(), "4.25");
7044 ///
7045 /// let mut x = Float::from(PI);
7046 /// assert_eq!(
7047 /// x.mul_sub_mul_rational_prec_round_assign_val_ref_ref(y.clone(), &z, &w, 5, Nearest),
7048 /// Less
7049 /// );
7050 /// assert_eq!(x.to_string(), "4.00");
7051 /// ```
7052 #[allow(clippy::needless_pass_by_value)]
7053 #[inline]
7054 pub fn mul_sub_mul_rational_prec_round_assign_val_ref_ref(
7055 &mut self,
7056 y: Self,
7057 z: &Self,
7058 w: &Rational,
7059 prec: u64,
7060 rm: RoundingMode,
7061 ) -> Ordering {
7062 let (s, o) = mul_add_mul_rational_helper(self, &y, z, w, true, prec, rm);
7063 *self = s;
7064 o
7065 }
7066
7067 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
7068 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
7069 /// the specified rounding mode. The first [`Float`] on the right-hand side is taken by
7070 /// reference and the others by value. An [`Ordering`] is returned, indicating whether the
7071 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
7072 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
7073 ///
7074 /// See [`RoundingMode`] for a description of the possible rounding modes.
7075 ///
7076 /// $$
7077 /// x \gets xy-zw+\varepsilon.
7078 /// $$
7079 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7080 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7081 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
7082 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7083 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
7084 ///
7085 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
7086 /// overflow, and underflow.
7087 ///
7088 /// If you know you'll be using `Nearest`, consider using
7089 /// [`Float::mul_sub_mul_rational_prec_assign`] instead. If you know that your target precision
7090 /// is the maximum of the precisions of the inputs, consider using
7091 /// [`Float::mul_sub_mul_rational_round_assign`] instead. If both of these things are true,
7092 /// consider using
7093 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
7094 ///
7095 /// # Worst-case complexity
7096 /// $T(n, m) = O(n \log n \log\log n + m)$
7097 ///
7098 /// $M(n, m) = O(n \log n + m)$
7099 ///
7100 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7101 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7102 /// `max(self.significant_bits(), prec)`.
7103 ///
7104 /// # Panics
7105 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
7106 /// representable with `prec` bits.
7107 ///
7108 /// # Examples
7109 /// ```
7110 /// use core::f64::consts::{E, PI, SQRT_2};
7111 /// use malachite_base::rounding_modes::RoundingMode::*;
7112 /// use malachite_float::Float;
7113 /// use malachite_q::Rational;
7114 /// use std::cmp::Ordering::*;
7115 ///
7116 /// let y = Float::from(E);
7117 /// let z = Float::from(SQRT_2);
7118 /// let w = Rational::from_signeds(22, 7);
7119 ///
7120 /// let mut x = Float::from(PI);
7121 /// assert_eq!(
7122 /// x.mul_sub_mul_rational_prec_round_assign_ref_val_val(
7123 /// &y,
7124 /// z.clone(),
7125 /// w.clone(),
7126 /// 5,
7127 /// Floor
7128 /// ),
7129 /// Less
7130 /// );
7131 /// assert_eq!(x.to_string(), "4.00");
7132 ///
7133 /// let mut x = Float::from(PI);
7134 /// assert_eq!(
7135 /// x.mul_sub_mul_rational_prec_round_assign_ref_val_val(
7136 /// &y,
7137 /// z.clone(),
7138 /// w.clone(),
7139 /// 5,
7140 /// Ceiling
7141 /// ),
7142 /// Greater
7143 /// );
7144 /// assert_eq!(x.to_string(), "4.25");
7145 ///
7146 /// let mut x = Float::from(PI);
7147 /// assert_eq!(
7148 /// x.mul_sub_mul_rational_prec_round_assign_ref_val_val(
7149 /// &y,
7150 /// z.clone(),
7151 /// w.clone(),
7152 /// 5,
7153 /// Nearest
7154 /// ),
7155 /// Less
7156 /// );
7157 /// assert_eq!(x.to_string(), "4.00");
7158 /// ```
7159 #[allow(clippy::needless_pass_by_value)]
7160 #[inline]
7161 pub fn mul_sub_mul_rational_prec_round_assign_ref_val_val(
7162 &mut self,
7163 y: &Self,
7164 z: Self,
7165 w: Rational,
7166 prec: u64,
7167 rm: RoundingMode,
7168 ) -> Ordering {
7169 let (s, o) = mul_add_mul_rational_helper(self, y, &z, &w, true, prec, rm);
7170 *self = s;
7171 o
7172 }
7173
7174 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
7175 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
7176 /// the specified rounding mode. The middle [`Float`] on the right-hand side is taken by value
7177 /// and the others by reference. An [`Ordering`] is returned, indicating whether the rounded
7178 /// diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
7179 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
7180 ///
7181 /// See [`RoundingMode`] for a description of the possible rounding modes.
7182 ///
7183 /// $$
7184 /// x \gets xy-zw+\varepsilon.
7185 /// $$
7186 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7187 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7188 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
7189 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7190 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
7191 ///
7192 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
7193 /// overflow, and underflow.
7194 ///
7195 /// If you know you'll be using `Nearest`, consider using
7196 /// [`Float::mul_sub_mul_rational_prec_assign`] instead. If you know that your target precision
7197 /// is the maximum of the precisions of the inputs, consider using
7198 /// [`Float::mul_sub_mul_rational_round_assign`] instead. If both of these things are true,
7199 /// consider using
7200 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
7201 ///
7202 /// # Worst-case complexity
7203 /// $T(n, m) = O(n \log n \log\log n + m)$
7204 ///
7205 /// $M(n, m) = O(n \log n + m)$
7206 ///
7207 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7208 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7209 /// `max(self.significant_bits(), prec)`.
7210 ///
7211 /// # Panics
7212 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
7213 /// representable with `prec` bits.
7214 ///
7215 /// # Examples
7216 /// ```
7217 /// use core::f64::consts::{E, PI, SQRT_2};
7218 /// use malachite_base::rounding_modes::RoundingMode::*;
7219 /// use malachite_float::Float;
7220 /// use malachite_q::Rational;
7221 /// use std::cmp::Ordering::*;
7222 ///
7223 /// let y = Float::from(E);
7224 /// let z = Float::from(SQRT_2);
7225 /// let w = Rational::from_signeds(22, 7);
7226 ///
7227 /// let mut x = Float::from(PI);
7228 /// assert_eq!(
7229 /// x.mul_sub_mul_rational_prec_round_assign_ref_val_ref(&y, z.clone(), &w, 5, Floor),
7230 /// Less
7231 /// );
7232 /// assert_eq!(x.to_string(), "4.00");
7233 ///
7234 /// let mut x = Float::from(PI);
7235 /// assert_eq!(
7236 /// x.mul_sub_mul_rational_prec_round_assign_ref_val_ref(&y, z.clone(), &w, 5, Ceiling),
7237 /// Greater
7238 /// );
7239 /// assert_eq!(x.to_string(), "4.25");
7240 ///
7241 /// let mut x = Float::from(PI);
7242 /// assert_eq!(
7243 /// x.mul_sub_mul_rational_prec_round_assign_ref_val_ref(&y, z.clone(), &w, 5, Nearest),
7244 /// Less
7245 /// );
7246 /// assert_eq!(x.to_string(), "4.00");
7247 /// ```
7248 #[allow(clippy::needless_pass_by_value)]
7249 #[inline]
7250 pub fn mul_sub_mul_rational_prec_round_assign_ref_val_ref(
7251 &mut self,
7252 y: &Self,
7253 z: Self,
7254 w: &Rational,
7255 prec: u64,
7256 rm: RoundingMode,
7257 ) -> Ordering {
7258 let (s, o) = mul_add_mul_rational_helper(self, y, &z, w, true, prec, rm);
7259 *self = s;
7260 o
7261 }
7262
7263 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
7264 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
7265 /// the specified rounding mode. The last [`Float`] on the right-hand side is taken by value and
7266 /// the others by reference. An [`Ordering`] is returned, indicating whether the rounded diff is
7267 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
7268 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
7269 ///
7270 /// See [`RoundingMode`] for a description of the possible rounding modes.
7271 ///
7272 /// $$
7273 /// x \gets xy-zw+\varepsilon.
7274 /// $$
7275 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7276 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7277 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
7278 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7279 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
7280 ///
7281 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
7282 /// overflow, and underflow.
7283 ///
7284 /// If you know you'll be using `Nearest`, consider using
7285 /// [`Float::mul_sub_mul_rational_prec_assign`] instead. If you know that your target precision
7286 /// is the maximum of the precisions of the inputs, consider using
7287 /// [`Float::mul_sub_mul_rational_round_assign`] instead. If both of these things are true,
7288 /// consider using
7289 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
7290 ///
7291 /// # Worst-case complexity
7292 /// $T(n, m) = O(n \log n \log\log n + m)$
7293 ///
7294 /// $M(n, m) = O(n \log n + m)$
7295 ///
7296 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7297 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7298 /// `max(self.significant_bits(), prec)`.
7299 ///
7300 /// # Panics
7301 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
7302 /// representable with `prec` bits.
7303 ///
7304 /// # Examples
7305 /// ```
7306 /// use core::f64::consts::{E, PI, SQRT_2};
7307 /// use malachite_base::rounding_modes::RoundingMode::*;
7308 /// use malachite_float::Float;
7309 /// use malachite_q::Rational;
7310 /// use std::cmp::Ordering::*;
7311 ///
7312 /// let y = Float::from(E);
7313 /// let z = Float::from(SQRT_2);
7314 /// let w = Rational::from_signeds(22, 7);
7315 ///
7316 /// let mut x = Float::from(PI);
7317 /// assert_eq!(
7318 /// x.mul_sub_mul_rational_prec_round_assign_ref_ref_val(&y, &z, w.clone(), 5, Floor),
7319 /// Less
7320 /// );
7321 /// assert_eq!(x.to_string(), "4.00");
7322 ///
7323 /// let mut x = Float::from(PI);
7324 /// assert_eq!(
7325 /// x.mul_sub_mul_rational_prec_round_assign_ref_ref_val(&y, &z, w.clone(), 5, Ceiling),
7326 /// Greater
7327 /// );
7328 /// assert_eq!(x.to_string(), "4.25");
7329 ///
7330 /// let mut x = Float::from(PI);
7331 /// assert_eq!(
7332 /// x.mul_sub_mul_rational_prec_round_assign_ref_ref_val(&y, &z, w.clone(), 5, Nearest),
7333 /// Less
7334 /// );
7335 /// assert_eq!(x.to_string(), "4.00");
7336 /// ```
7337 #[allow(clippy::needless_pass_by_value)]
7338 #[inline]
7339 pub fn mul_sub_mul_rational_prec_round_assign_ref_ref_val(
7340 &mut self,
7341 y: &Self,
7342 z: &Self,
7343 w: Rational,
7344 prec: u64,
7345 rm: RoundingMode,
7346 ) -> Ordering {
7347 let (s, o) = mul_add_mul_rational_helper(self, y, z, &w, true, prec, rm);
7348 *self = s;
7349 o
7350 }
7351
7352 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
7353 /// [`Float`]s, with a single rounding, rounding the result to the specified precision and with
7354 /// the specified rounding mode. The [`Float`]s on the right-hand side are all taken by
7355 /// reference. An [`Ordering`] is returned, indicating whether the rounded diff is less than,
7356 /// equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
7357 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
7358 ///
7359 /// See [`RoundingMode`] for a description of the possible rounding modes.
7360 ///
7361 /// $$
7362 /// x \gets xy-zw+\varepsilon.
7363 /// $$
7364 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7365 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7366 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$.
7367 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7368 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$.
7369 ///
7370 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
7371 /// overflow, and underflow.
7372 ///
7373 /// If you know you'll be using `Nearest`, consider using
7374 /// [`Float::mul_sub_mul_rational_prec_assign`] instead. If you know that your target precision
7375 /// is the maximum of the precisions of the inputs, consider using
7376 /// [`Float::mul_sub_mul_rational_round_assign`] instead. If both of these things are true,
7377 /// consider using
7378 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
7379 ///
7380 /// # Worst-case complexity
7381 /// $T(n, m) = O(n \log n \log\log n + m)$
7382 ///
7383 /// $M(n, m) = O(n \log n + m)$
7384 ///
7385 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7386 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7387 /// `max(self.significant_bits(), prec)`.
7388 ///
7389 /// # Panics
7390 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused operation is not exactly
7391 /// representable with `prec` bits.
7392 ///
7393 /// # Examples
7394 /// ```
7395 /// use core::f64::consts::{E, PI, SQRT_2};
7396 /// use malachite_base::rounding_modes::RoundingMode::*;
7397 /// use malachite_float::Float;
7398 /// use malachite_q::Rational;
7399 /// use std::cmp::Ordering::*;
7400 ///
7401 /// let y = Float::from(E);
7402 /// let z = Float::from(SQRT_2);
7403 /// let w = Rational::from_signeds(22, 7);
7404 ///
7405 /// let mut x = Float::from(PI);
7406 /// assert_eq!(
7407 /// x.mul_sub_mul_rational_prec_round_assign_ref_ref_ref(&y, &z, &w, 5, Floor),
7408 /// Less
7409 /// );
7410 /// assert_eq!(x.to_string(), "4.00");
7411 ///
7412 /// let mut x = Float::from(PI);
7413 /// assert_eq!(
7414 /// x.mul_sub_mul_rational_prec_round_assign_ref_ref_ref(&y, &z, &w, 5, Ceiling),
7415 /// Greater
7416 /// );
7417 /// assert_eq!(x.to_string(), "4.25");
7418 ///
7419 /// let mut x = Float::from(PI);
7420 /// assert_eq!(
7421 /// x.mul_sub_mul_rational_prec_round_assign_ref_ref_ref(&y, &z, &w, 5, Nearest),
7422 /// Less
7423 /// );
7424 /// assert_eq!(x.to_string(), "4.00");
7425 /// ```
7426 #[allow(clippy::needless_pass_by_value)]
7427 #[inline]
7428 pub fn mul_sub_mul_rational_prec_round_assign_ref_ref_ref(
7429 &mut self,
7430 y: &Self,
7431 z: &Self,
7432 w: &Rational,
7433 prec: u64,
7434 rm: RoundingMode,
7435 ) -> Ordering {
7436 let (s, o) = mul_add_mul_rational_helper(self, y, z, w, true, prec, rm);
7437 *self = s;
7438 o
7439 }
7440
7441 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
7442 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
7443 /// its product exactly and the products are not rounded before the final subtraction, so there
7444 /// is a single rounding. The [`Float`]s and the [`Rational`] are all taken by value. An
7445 /// [`Ordering`] is also returned, indicating whether the rounded diff is less than, equal to,
7446 /// or greater than the exact diff. Although `NaN`s are not comparable to any [`Float`],
7447 /// whenever this function returns a `NaN` it also returns `Equal`.
7448 ///
7449 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
7450 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
7451 /// the `Nearest` rounding mode.
7452 ///
7453 /// $$
7454 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
7455 /// $$
7456 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7457 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
7458 /// |xy-zw|\rfloor-p}$.
7459 ///
7460 /// If the output has a precision, it is `prec`.
7461 ///
7462 /// Special cases:
7463 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7464 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7465 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7466 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7467 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
7468 /// [`Rational`] counts as an unsigned zero and a positive sign.
7469 /// - If exactly one product is infinite, the result is that product's infinity, the second
7470 /// product's sign counting as flipped.
7471 /// - If both products are infinite, the result is their common infinity if their signs differ,
7472 /// and `NaN` otherwise.
7473 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
7474 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
7475 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
7476 ///
7477 /// Overflow and underflow:
7478 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
7479 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
7480 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
7481 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
7482 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
7483 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
7484 ///
7485 /// If you want to use a rounding mode other than `Nearest`, consider using
7486 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know that your target precision
7487 /// is the maximum of the precisions of the inputs, consider using
7488 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
7489 ///
7490 /// # Worst-case complexity
7491 /// $T(n, m) = O(n \log n \log\log n + m)$
7492 ///
7493 /// $M(n, m) = O(n \log n + m)$
7494 ///
7495 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7496 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7497 /// `max(self.significant_bits(), prec)`.
7498 ///
7499 /// # Panics
7500 /// Panics if `prec` is zero.
7501 ///
7502 /// # Examples
7503 /// ```
7504 /// use core::f64::consts::{E, PI, SQRT_2};
7505 /// use malachite_float::Float;
7506 /// use malachite_q::Rational;
7507 /// use std::cmp::Ordering::*;
7508 ///
7509 /// let x = Float::from(PI);
7510 /// let y = Float::from(E);
7511 /// let z = Float::from(SQRT_2);
7512 /// let w = Rational::from_signeds(22, 7);
7513 ///
7514 /// let (diff, o) = x
7515 /// .clone()
7516 /// .mul_sub_mul_rational_prec(y.clone(), z.clone(), w.clone(), 5);
7517 /// assert_eq!(diff.to_string(), "4.00");
7518 /// assert_eq!(o, Less);
7519 ///
7520 /// let (diff, o) = x
7521 /// .clone()
7522 /// .mul_sub_mul_rational_prec(y.clone(), z.clone(), w.clone(), 20);
7523 /// assert_eq!(diff.to_string(), "4.0950623");
7524 /// assert_eq!(o, Less);
7525 /// ```
7526 #[allow(clippy::needless_pass_by_value)]
7527 #[inline]
7528 pub fn mul_sub_mul_rational_prec(
7529 self,
7530 y: Self,
7531 z: Self,
7532 w: Rational,
7533 prec: u64,
7534 ) -> (Self, Ordering) {
7535 self.mul_sub_mul_rational_prec_round(y, z, w, prec, Nearest)
7536 }
7537
7538 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
7539 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
7540 /// its product exactly and the products are not rounded before the final subtraction, so there
7541 /// is a single rounding. The [`Float`]s are taken by value and the [`Rational`] by reference.
7542 /// An [`Ordering`] is also returned, indicating whether the rounded diff is less than, equal
7543 /// to, or greater than the exact diff. Although `NaN`s are not comparable to any [`Float`],
7544 /// whenever this function returns a `NaN` it also returns `Equal`.
7545 ///
7546 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
7547 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
7548 /// the `Nearest` rounding mode.
7549 ///
7550 /// $$
7551 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
7552 /// $$
7553 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7554 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
7555 /// |xy-zw|\rfloor-p}$.
7556 ///
7557 /// If the output has a precision, it is `prec`.
7558 ///
7559 /// Special cases:
7560 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7561 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7562 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7563 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7564 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
7565 /// [`Rational`] counts as an unsigned zero and a positive sign.
7566 /// - If exactly one product is infinite, the result is that product's infinity, the second
7567 /// product's sign counting as flipped.
7568 /// - If both products are infinite, the result is their common infinity if their signs differ,
7569 /// and `NaN` otherwise.
7570 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
7571 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
7572 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
7573 ///
7574 /// Overflow and underflow:
7575 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
7576 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
7577 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
7578 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
7579 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
7580 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
7581 ///
7582 /// If you want to use a rounding mode other than `Nearest`, consider using
7583 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know that your target precision
7584 /// is the maximum of the precisions of the inputs, consider using
7585 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
7586 ///
7587 /// # Worst-case complexity
7588 /// $T(n, m) = O(n \log n \log\log n + m)$
7589 ///
7590 /// $M(n, m) = O(n \log n + m)$
7591 ///
7592 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7593 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7594 /// `max(self.significant_bits(), prec)`.
7595 ///
7596 /// # Panics
7597 /// Panics if `prec` is zero.
7598 ///
7599 /// # Examples
7600 /// ```
7601 /// use core::f64::consts::{E, PI, SQRT_2};
7602 /// use malachite_float::Float;
7603 /// use malachite_q::Rational;
7604 /// use std::cmp::Ordering::*;
7605 ///
7606 /// let x = Float::from(PI);
7607 /// let y = Float::from(E);
7608 /// let z = Float::from(SQRT_2);
7609 /// let w = Rational::from_signeds(22, 7);
7610 ///
7611 /// let (diff, o) =
7612 /// x.clone()
7613 /// .mul_sub_mul_rational_prec_val_val_val_ref(y.clone(), z.clone(), &w, 5);
7614 /// assert_eq!(diff.to_string(), "4.00");
7615 /// assert_eq!(o, Less);
7616 ///
7617 /// let (diff, o) =
7618 /// x.clone()
7619 /// .mul_sub_mul_rational_prec_val_val_val_ref(y.clone(), z.clone(), &w, 20);
7620 /// assert_eq!(diff.to_string(), "4.0950623");
7621 /// assert_eq!(o, Less);
7622 /// ```
7623 #[allow(clippy::needless_pass_by_value)]
7624 #[inline]
7625 pub fn mul_sub_mul_rational_prec_val_val_val_ref(
7626 self,
7627 y: Self,
7628 z: Self,
7629 w: &Rational,
7630 prec: u64,
7631 ) -> (Self, Ordering) {
7632 self.mul_sub_mul_rational_prec_round_val_val_val_ref(y, z, w, prec, Nearest)
7633 }
7634
7635 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
7636 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
7637 /// its product exactly and the products are not rounded before the final subtraction, so there
7638 /// is a single rounding. The third [`Float`] is taken by reference and the other operands by
7639 /// value. An [`Ordering`] is also returned, indicating whether the rounded diff is less than,
7640 /// equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
7641 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
7642 ///
7643 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
7644 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
7645 /// the `Nearest` rounding mode.
7646 ///
7647 /// $$
7648 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
7649 /// $$
7650 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7651 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
7652 /// |xy-zw|\rfloor-p}$.
7653 ///
7654 /// If the output has a precision, it is `prec`.
7655 ///
7656 /// Special cases:
7657 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7658 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7659 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7660 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7661 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
7662 /// [`Rational`] counts as an unsigned zero and a positive sign.
7663 /// - If exactly one product is infinite, the result is that product's infinity, the second
7664 /// product's sign counting as flipped.
7665 /// - If both products are infinite, the result is their common infinity if their signs differ,
7666 /// and `NaN` otherwise.
7667 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
7668 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
7669 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
7670 ///
7671 /// Overflow and underflow:
7672 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
7673 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
7674 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
7675 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
7676 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
7677 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
7678 ///
7679 /// If you want to use a rounding mode other than `Nearest`, consider using
7680 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know that your target precision
7681 /// is the maximum of the precisions of the inputs, consider using
7682 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
7683 ///
7684 /// # Worst-case complexity
7685 /// $T(n, m) = O(n \log n \log\log n + m)$
7686 ///
7687 /// $M(n, m) = O(n \log n + m)$
7688 ///
7689 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7690 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7691 /// `max(self.significant_bits(), prec)`.
7692 ///
7693 /// # Panics
7694 /// Panics if `prec` is zero.
7695 ///
7696 /// # Examples
7697 /// ```
7698 /// use core::f64::consts::{E, PI, SQRT_2};
7699 /// use malachite_float::Float;
7700 /// use malachite_q::Rational;
7701 /// use std::cmp::Ordering::*;
7702 ///
7703 /// let x = Float::from(PI);
7704 /// let y = Float::from(E);
7705 /// let z = Float::from(SQRT_2);
7706 /// let w = Rational::from_signeds(22, 7);
7707 ///
7708 /// let (diff, o) =
7709 /// x.clone()
7710 /// .mul_sub_mul_rational_prec_val_val_ref_val(y.clone(), &z, w.clone(), 5);
7711 /// assert_eq!(diff.to_string(), "4.00");
7712 /// assert_eq!(o, Less);
7713 ///
7714 /// let (diff, o) =
7715 /// x.clone()
7716 /// .mul_sub_mul_rational_prec_val_val_ref_val(y.clone(), &z, w.clone(), 20);
7717 /// assert_eq!(diff.to_string(), "4.0950623");
7718 /// assert_eq!(o, Less);
7719 /// ```
7720 #[allow(clippy::needless_pass_by_value)]
7721 #[inline]
7722 pub fn mul_sub_mul_rational_prec_val_val_ref_val(
7723 self,
7724 y: Self,
7725 z: &Self,
7726 w: Rational,
7727 prec: u64,
7728 ) -> (Self, Ordering) {
7729 self.mul_sub_mul_rational_prec_round_val_val_ref_val(y, z, w, prec, Nearest)
7730 }
7731
7732 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
7733 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
7734 /// its product exactly and the products are not rounded before the final subtraction, so there
7735 /// is a single rounding. The first two [`Float`]s are taken by value and the third [`Float`]
7736 /// and the [`Rational`] by reference. An [`Ordering`] is also returned, indicating whether the
7737 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
7738 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
7739 ///
7740 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
7741 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
7742 /// the `Nearest` rounding mode.
7743 ///
7744 /// $$
7745 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
7746 /// $$
7747 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7748 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
7749 /// |xy-zw|\rfloor-p}$.
7750 ///
7751 /// If the output has a precision, it is `prec`.
7752 ///
7753 /// Special cases:
7754 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7755 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7756 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7757 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7758 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
7759 /// [`Rational`] counts as an unsigned zero and a positive sign.
7760 /// - If exactly one product is infinite, the result is that product's infinity, the second
7761 /// product's sign counting as flipped.
7762 /// - If both products are infinite, the result is their common infinity if their signs differ,
7763 /// and `NaN` otherwise.
7764 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
7765 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
7766 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
7767 ///
7768 /// Overflow and underflow:
7769 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
7770 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
7771 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
7772 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
7773 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
7774 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
7775 ///
7776 /// If you want to use a rounding mode other than `Nearest`, consider using
7777 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know that your target precision
7778 /// is the maximum of the precisions of the inputs, consider using
7779 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
7780 ///
7781 /// # Worst-case complexity
7782 /// $T(n, m) = O(n \log n \log\log n + m)$
7783 ///
7784 /// $M(n, m) = O(n \log n + m)$
7785 ///
7786 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7787 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7788 /// `max(self.significant_bits(), prec)`.
7789 ///
7790 /// # Panics
7791 /// Panics if `prec` is zero.
7792 ///
7793 /// # Examples
7794 /// ```
7795 /// use core::f64::consts::{E, PI, SQRT_2};
7796 /// use malachite_float::Float;
7797 /// use malachite_q::Rational;
7798 /// use std::cmp::Ordering::*;
7799 ///
7800 /// let x = Float::from(PI);
7801 /// let y = Float::from(E);
7802 /// let z = Float::from(SQRT_2);
7803 /// let w = Rational::from_signeds(22, 7);
7804 ///
7805 /// let (diff, o) = x
7806 /// .clone()
7807 /// .mul_sub_mul_rational_prec_val_val_ref_ref(y.clone(), &z, &w, 5);
7808 /// assert_eq!(diff.to_string(), "4.00");
7809 /// assert_eq!(o, Less);
7810 ///
7811 /// let (diff, o) = x
7812 /// .clone()
7813 /// .mul_sub_mul_rational_prec_val_val_ref_ref(y.clone(), &z, &w, 20);
7814 /// assert_eq!(diff.to_string(), "4.0950623");
7815 /// assert_eq!(o, Less);
7816 /// ```
7817 #[allow(clippy::needless_pass_by_value)]
7818 #[inline]
7819 pub fn mul_sub_mul_rational_prec_val_val_ref_ref(
7820 self,
7821 y: Self,
7822 z: &Self,
7823 w: &Rational,
7824 prec: u64,
7825 ) -> (Self, Ordering) {
7826 self.mul_sub_mul_rational_prec_round_val_val_ref_ref(y, z, w, prec, Nearest)
7827 }
7828
7829 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
7830 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
7831 /// its product exactly and the products are not rounded before the final subtraction, so there
7832 /// is a single rounding. The second [`Float`] is taken by reference and the other operands by
7833 /// value. An [`Ordering`] is also returned, indicating whether the rounded diff is less than,
7834 /// equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
7835 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
7836 ///
7837 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
7838 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
7839 /// the `Nearest` rounding mode.
7840 ///
7841 /// $$
7842 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
7843 /// $$
7844 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7845 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
7846 /// |xy-zw|\rfloor-p}$.
7847 ///
7848 /// If the output has a precision, it is `prec`.
7849 ///
7850 /// Special cases:
7851 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7852 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7853 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7854 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7855 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
7856 /// [`Rational`] counts as an unsigned zero and a positive sign.
7857 /// - If exactly one product is infinite, the result is that product's infinity, the second
7858 /// product's sign counting as flipped.
7859 /// - If both products are infinite, the result is their common infinity if their signs differ,
7860 /// and `NaN` otherwise.
7861 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
7862 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
7863 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
7864 ///
7865 /// Overflow and underflow:
7866 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
7867 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
7868 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
7869 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
7870 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
7871 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
7872 ///
7873 /// If you want to use a rounding mode other than `Nearest`, consider using
7874 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know that your target precision
7875 /// is the maximum of the precisions of the inputs, consider using
7876 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
7877 ///
7878 /// # Worst-case complexity
7879 /// $T(n, m) = O(n \log n \log\log n + m)$
7880 ///
7881 /// $M(n, m) = O(n \log n + m)$
7882 ///
7883 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7884 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7885 /// `max(self.significant_bits(), prec)`.
7886 ///
7887 /// # Panics
7888 /// Panics if `prec` is zero.
7889 ///
7890 /// # Examples
7891 /// ```
7892 /// use core::f64::consts::{E, PI, SQRT_2};
7893 /// use malachite_float::Float;
7894 /// use malachite_q::Rational;
7895 /// use std::cmp::Ordering::*;
7896 ///
7897 /// let x = Float::from(PI);
7898 /// let y = Float::from(E);
7899 /// let z = Float::from(SQRT_2);
7900 /// let w = Rational::from_signeds(22, 7);
7901 ///
7902 /// let (diff, o) =
7903 /// x.clone()
7904 /// .mul_sub_mul_rational_prec_val_ref_val_val(&y, z.clone(), w.clone(), 5);
7905 /// assert_eq!(diff.to_string(), "4.00");
7906 /// assert_eq!(o, Less);
7907 ///
7908 /// let (diff, o) =
7909 /// x.clone()
7910 /// .mul_sub_mul_rational_prec_val_ref_val_val(&y, z.clone(), w.clone(), 20);
7911 /// assert_eq!(diff.to_string(), "4.0950623");
7912 /// assert_eq!(o, Less);
7913 /// ```
7914 #[allow(clippy::needless_pass_by_value)]
7915 #[inline]
7916 pub fn mul_sub_mul_rational_prec_val_ref_val_val(
7917 self,
7918 y: &Self,
7919 z: Self,
7920 w: Rational,
7921 prec: u64,
7922 ) -> (Self, Ordering) {
7923 self.mul_sub_mul_rational_prec_round_val_ref_val_val(y, z, w, prec, Nearest)
7924 }
7925
7926 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
7927 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
7928 /// its product exactly and the products are not rounded before the final subtraction, so there
7929 /// is a single rounding. The second [`Float`] and the [`Rational`] are taken by reference and
7930 /// the other operands by value. An [`Ordering`] is also returned, indicating whether the
7931 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
7932 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
7933 ///
7934 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
7935 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
7936 /// the `Nearest` rounding mode.
7937 ///
7938 /// $$
7939 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
7940 /// $$
7941 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7942 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
7943 /// |xy-zw|\rfloor-p}$.
7944 ///
7945 /// If the output has a precision, it is `prec`.
7946 ///
7947 /// Special cases:
7948 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7949 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7950 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
7951 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
7952 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
7953 /// [`Rational`] counts as an unsigned zero and a positive sign.
7954 /// - If exactly one product is infinite, the result is that product's infinity, the second
7955 /// product's sign counting as flipped.
7956 /// - If both products are infinite, the result is their common infinity if their signs differ,
7957 /// and `NaN` otherwise.
7958 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
7959 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
7960 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
7961 ///
7962 /// Overflow and underflow:
7963 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
7964 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
7965 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
7966 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
7967 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
7968 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
7969 ///
7970 /// If you want to use a rounding mode other than `Nearest`, consider using
7971 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know that your target precision
7972 /// is the maximum of the precisions of the inputs, consider using
7973 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
7974 ///
7975 /// # Worst-case complexity
7976 /// $T(n, m) = O(n \log n \log\log n + m)$
7977 ///
7978 /// $M(n, m) = O(n \log n + m)$
7979 ///
7980 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7981 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
7982 /// `max(self.significant_bits(), prec)`.
7983 ///
7984 /// # Panics
7985 /// Panics if `prec` is zero.
7986 ///
7987 /// # Examples
7988 /// ```
7989 /// use core::f64::consts::{E, PI, SQRT_2};
7990 /// use malachite_float::Float;
7991 /// use malachite_q::Rational;
7992 /// use std::cmp::Ordering::*;
7993 ///
7994 /// let x = Float::from(PI);
7995 /// let y = Float::from(E);
7996 /// let z = Float::from(SQRT_2);
7997 /// let w = Rational::from_signeds(22, 7);
7998 ///
7999 /// let (diff, o) = x
8000 /// .clone()
8001 /// .mul_sub_mul_rational_prec_val_ref_val_ref(&y, z.clone(), &w, 5);
8002 /// assert_eq!(diff.to_string(), "4.00");
8003 /// assert_eq!(o, Less);
8004 ///
8005 /// let (diff, o) = x
8006 /// .clone()
8007 /// .mul_sub_mul_rational_prec_val_ref_val_ref(&y, z.clone(), &w, 20);
8008 /// assert_eq!(diff.to_string(), "4.0950623");
8009 /// assert_eq!(o, Less);
8010 /// ```
8011 #[allow(clippy::needless_pass_by_value)]
8012 #[inline]
8013 pub fn mul_sub_mul_rational_prec_val_ref_val_ref(
8014 self,
8015 y: &Self,
8016 z: Self,
8017 w: &Rational,
8018 prec: u64,
8019 ) -> (Self, Ordering) {
8020 self.mul_sub_mul_rational_prec_round_val_ref_val_ref(y, z, w, prec, Nearest)
8021 }
8022
8023 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
8024 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
8025 /// its product exactly and the products are not rounded before the final subtraction, so there
8026 /// is a single rounding. The second and third [`Float`]s are taken by reference and the other
8027 /// operands by value. An [`Ordering`] is also returned, indicating whether the rounded diff is
8028 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
8029 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
8030 ///
8031 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8032 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8033 /// the `Nearest` rounding mode.
8034 ///
8035 /// $$
8036 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
8037 /// $$
8038 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8039 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8040 /// |xy-zw|\rfloor-p}$.
8041 ///
8042 /// If the output has a precision, it is `prec`.
8043 ///
8044 /// Special cases:
8045 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8046 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8047 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8048 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8049 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
8050 /// [`Rational`] counts as an unsigned zero and a positive sign.
8051 /// - If exactly one product is infinite, the result is that product's infinity, the second
8052 /// product's sign counting as flipped.
8053 /// - If both products are infinite, the result is their common infinity if their signs differ,
8054 /// and `NaN` otherwise.
8055 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
8056 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
8057 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
8058 ///
8059 /// Overflow and underflow:
8060 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8061 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8062 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8063 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8064 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
8065 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8066 ///
8067 /// If you want to use a rounding mode other than `Nearest`, consider using
8068 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know that your target precision
8069 /// is the maximum of the precisions of the inputs, consider using
8070 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
8071 ///
8072 /// # Worst-case complexity
8073 /// $T(n, m) = O(n \log n \log\log n + m)$
8074 ///
8075 /// $M(n, m) = O(n \log n + m)$
8076 ///
8077 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8078 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8079 /// `max(self.significant_bits(), prec)`.
8080 ///
8081 /// # Panics
8082 /// Panics if `prec` is zero.
8083 ///
8084 /// # Examples
8085 /// ```
8086 /// use core::f64::consts::{E, PI, SQRT_2};
8087 /// use malachite_float::Float;
8088 /// use malachite_q::Rational;
8089 /// use std::cmp::Ordering::*;
8090 ///
8091 /// let x = Float::from(PI);
8092 /// let y = Float::from(E);
8093 /// let z = Float::from(SQRT_2);
8094 /// let w = Rational::from_signeds(22, 7);
8095 ///
8096 /// let (diff, o) = x
8097 /// .clone()
8098 /// .mul_sub_mul_rational_prec_val_ref_ref_val(&y, &z, w.clone(), 5);
8099 /// assert_eq!(diff.to_string(), "4.00");
8100 /// assert_eq!(o, Less);
8101 ///
8102 /// let (diff, o) = x
8103 /// .clone()
8104 /// .mul_sub_mul_rational_prec_val_ref_ref_val(&y, &z, w.clone(), 20);
8105 /// assert_eq!(diff.to_string(), "4.0950623");
8106 /// assert_eq!(o, Less);
8107 /// ```
8108 #[allow(clippy::needless_pass_by_value)]
8109 #[inline]
8110 pub fn mul_sub_mul_rational_prec_val_ref_ref_val(
8111 self,
8112 y: &Self,
8113 z: &Self,
8114 w: Rational,
8115 prec: u64,
8116 ) -> (Self, Ordering) {
8117 self.mul_sub_mul_rational_prec_round_val_ref_ref_val(y, z, w, prec, Nearest)
8118 }
8119
8120 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
8121 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
8122 /// its product exactly and the products are not rounded before the final subtraction, so there
8123 /// is a single rounding. The first [`Float`] is taken by value and the other operands by
8124 /// reference. An [`Ordering`] is also returned, indicating whether the rounded diff is less
8125 /// than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
8126 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
8127 ///
8128 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8129 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8130 /// the `Nearest` rounding mode.
8131 ///
8132 /// $$
8133 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
8134 /// $$
8135 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8136 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8137 /// |xy-zw|\rfloor-p}$.
8138 ///
8139 /// If the output has a precision, it is `prec`.
8140 ///
8141 /// Special cases:
8142 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8143 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8144 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8145 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8146 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
8147 /// [`Rational`] counts as an unsigned zero and a positive sign.
8148 /// - If exactly one product is infinite, the result is that product's infinity, the second
8149 /// product's sign counting as flipped.
8150 /// - If both products are infinite, the result is their common infinity if their signs differ,
8151 /// and `NaN` otherwise.
8152 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
8153 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
8154 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
8155 ///
8156 /// Overflow and underflow:
8157 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8158 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8159 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8160 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8161 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
8162 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8163 ///
8164 /// If you want to use a rounding mode other than `Nearest`, consider using
8165 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know that your target precision
8166 /// is the maximum of the precisions of the inputs, consider using
8167 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
8168 ///
8169 /// # Worst-case complexity
8170 /// $T(n, m) = O(n \log n \log\log n + m)$
8171 ///
8172 /// $M(n, m) = O(n \log n + m)$
8173 ///
8174 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8175 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8176 /// `max(self.significant_bits(), prec)`.
8177 ///
8178 /// # Panics
8179 /// Panics if `prec` is zero.
8180 ///
8181 /// # Examples
8182 /// ```
8183 /// use core::f64::consts::{E, PI, SQRT_2};
8184 /// use malachite_float::Float;
8185 /// use malachite_q::Rational;
8186 /// use std::cmp::Ordering::*;
8187 ///
8188 /// let x = Float::from(PI);
8189 /// let y = Float::from(E);
8190 /// let z = Float::from(SQRT_2);
8191 /// let w = Rational::from_signeds(22, 7);
8192 ///
8193 /// let (diff, o) = x
8194 /// .clone()
8195 /// .mul_sub_mul_rational_prec_val_ref_ref_ref(&y, &z, &w, 5);
8196 /// assert_eq!(diff.to_string(), "4.00");
8197 /// assert_eq!(o, Less);
8198 ///
8199 /// let (diff, o) = x
8200 /// .clone()
8201 /// .mul_sub_mul_rational_prec_val_ref_ref_ref(&y, &z, &w, 20);
8202 /// assert_eq!(diff.to_string(), "4.0950623");
8203 /// assert_eq!(o, Less);
8204 /// ```
8205 #[allow(clippy::needless_pass_by_value)]
8206 #[inline]
8207 pub fn mul_sub_mul_rational_prec_val_ref_ref_ref(
8208 self,
8209 y: &Self,
8210 z: &Self,
8211 w: &Rational,
8212 prec: u64,
8213 ) -> (Self, Ordering) {
8214 self.mul_sub_mul_rational_prec_round_val_ref_ref_ref(y, z, w, prec, Nearest)
8215 }
8216
8217 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
8218 /// rounding the result to the nearest value of the specified precision; the [`Rational`] enters
8219 /// its product exactly and the products are not rounded before the final subtraction, so there
8220 /// is a single rounding. The [`Float`]s and the [`Rational`] are all taken by reference. An
8221 /// [`Ordering`] is also returned, indicating whether the rounded diff is less than, equal to,
8222 /// or greater than the exact diff. Although `NaN`s are not comparable to any [`Float`],
8223 /// whenever this function returns a `NaN` it also returns `Equal`.
8224 ///
8225 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8226 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8227 /// the `Nearest` rounding mode.
8228 ///
8229 /// $$
8230 /// f(x,y,z,w,p) = xy-zw+\varepsilon.
8231 /// $$
8232 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8233 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8234 /// |xy-zw|\rfloor-p}$.
8235 ///
8236 /// If the output has a precision, it is `prec`.
8237 ///
8238 /// Special cases:
8239 /// - $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8240 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8241 /// $f(\text{NaN},y,z,w,p)=f(x,\text{NaN},z,w,p)=f(x,y,\text{NaN},w,p)=
8242 /// f(x,y,z,\text{NaN},p)=\text{NaN}$
8243 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
8244 /// [`Rational`] counts as an unsigned zero and a positive sign.
8245 /// - If exactly one product is infinite, the result is that product's infinity, the second
8246 /// product's sign counting as flipped.
8247 /// - If both products are infinite, the result is their common infinity if their signs differ,
8248 /// and `NaN` otherwise.
8249 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
8250 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$, the products are
8251 /// - $f(x,y,z,w,p)=0.0$ if $xy=zw$ and the products are finite and nonzero
8252 ///
8253 /// Overflow and underflow:
8254 /// - If $f(x,y,z,w,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8255 /// - If $f(x,y,z,w,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8256 /// - If $0<f(x,y,z,w,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8257 /// - If $2^{-2^{30}-1}<f(x,y,z,w,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8258 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,p)<0$, $-0.0$ is returned instead.
8259 /// - If $-2^{-2^{30}}<f(x,y,z,w,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8260 ///
8261 /// If you want to use a rounding mode other than `Nearest`, consider using
8262 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know that your target precision
8263 /// is the maximum of the precisions of the inputs, consider using
8264 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
8265 ///
8266 /// # Worst-case complexity
8267 /// $T(n, m) = O(n \log n \log\log n + m)$
8268 ///
8269 /// $M(n, m) = O(n \log n + m)$
8270 ///
8271 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8272 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8273 /// `max(self.significant_bits(), prec)`.
8274 ///
8275 /// # Panics
8276 /// Panics if `prec` is zero.
8277 ///
8278 /// # Examples
8279 /// ```
8280 /// use core::f64::consts::{E, PI, SQRT_2};
8281 /// use malachite_float::Float;
8282 /// use malachite_q::Rational;
8283 /// use std::cmp::Ordering::*;
8284 ///
8285 /// let x = Float::from(PI);
8286 /// let y = Float::from(E);
8287 /// let z = Float::from(SQRT_2);
8288 /// let w = Rational::from_signeds(22, 7);
8289 ///
8290 /// let (diff, o) = x.mul_sub_mul_rational_prec_ref_ref_ref_ref(&y, &z, &w, 5);
8291 /// assert_eq!(diff.to_string(), "4.00");
8292 /// assert_eq!(o, Less);
8293 ///
8294 /// let (diff, o) = x.mul_sub_mul_rational_prec_ref_ref_ref_ref(&y, &z, &w, 20);
8295 /// assert_eq!(diff.to_string(), "4.0950623");
8296 /// assert_eq!(o, Less);
8297 /// ```
8298 #[allow(clippy::needless_pass_by_value)]
8299 #[inline]
8300 pub fn mul_sub_mul_rational_prec_ref_ref_ref_ref(
8301 &self,
8302 y: &Self,
8303 z: &Self,
8304 w: &Rational,
8305 prec: u64,
8306 ) -> (Self, Ordering) {
8307 self.mul_sub_mul_rational_prec_round_ref_ref_ref_ref(y, z, w, prec, Nearest)
8308 }
8309
8310 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
8311 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
8312 /// specified precision. The [`Float`]s on the right-hand side are all taken by value. An
8313 /// [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
8314 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
8315 /// this function assigns a `NaN` it also returns `Equal`.
8316 ///
8317 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8318 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8319 /// the `Nearest` rounding mode.
8320 ///
8321 /// $$
8322 /// x \gets xy-zw+\varepsilon.
8323 /// $$
8324 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8325 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8326 /// |xy-zw|\rfloor-p}$.
8327 ///
8328 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
8329 /// overflow, and underflow.
8330 ///
8331 /// If you want to use a rounding mode other than `Nearest`, consider using
8332 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know that your target
8333 /// precision is the maximum of the precisions of the inputs, consider using
8334 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
8335 ///
8336 /// # Worst-case complexity
8337 /// $T(n, m) = O(n \log n \log\log n + m)$
8338 ///
8339 /// $M(n, m) = O(n \log n + m)$
8340 ///
8341 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8342 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8343 /// `max(self.significant_bits(), prec)`.
8344 ///
8345 /// # Panics
8346 /// Panics if `prec` is zero.
8347 ///
8348 /// # Examples
8349 /// ```
8350 /// use core::f64::consts::{E, PI, SQRT_2};
8351 /// use malachite_float::Float;
8352 /// use malachite_q::Rational;
8353 /// use std::cmp::Ordering::*;
8354 ///
8355 /// let y = Float::from(E);
8356 /// let z = Float::from(SQRT_2);
8357 /// let w = Rational::from_signeds(22, 7);
8358 ///
8359 /// let mut x = Float::from(PI);
8360 /// assert_eq!(
8361 /// x.mul_sub_mul_rational_prec_assign(y.clone(), z.clone(), w.clone(), 5),
8362 /// Less
8363 /// );
8364 /// assert_eq!(x.to_string(), "4.00");
8365 ///
8366 /// let mut x = Float::from(PI);
8367 /// assert_eq!(
8368 /// x.mul_sub_mul_rational_prec_assign(y.clone(), z.clone(), w.clone(), 20),
8369 /// Less
8370 /// );
8371 /// assert_eq!(x.to_string(), "4.0950623");
8372 /// ```
8373 #[allow(clippy::needless_pass_by_value)]
8374 #[inline]
8375 pub fn mul_sub_mul_rational_prec_assign(
8376 &mut self,
8377 y: Self,
8378 z: Self,
8379 w: Rational,
8380 prec: u64,
8381 ) -> Ordering {
8382 self.mul_sub_mul_rational_prec_round_assign(y, z, w, prec, Nearest)
8383 }
8384
8385 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
8386 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
8387 /// specified precision. The last [`Float`] on the right-hand side is taken by reference and the
8388 /// others by value. An [`Ordering`] is returned, indicating whether the rounded diff is less
8389 /// than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
8390 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
8391 ///
8392 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8393 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8394 /// the `Nearest` rounding mode.
8395 ///
8396 /// $$
8397 /// x \gets xy-zw+\varepsilon.
8398 /// $$
8399 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8400 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8401 /// |xy-zw|\rfloor-p}$.
8402 ///
8403 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
8404 /// overflow, and underflow.
8405 ///
8406 /// If you want to use a rounding mode other than `Nearest`, consider using
8407 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know that your target
8408 /// precision is the maximum of the precisions of the inputs, consider using
8409 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
8410 ///
8411 /// # Worst-case complexity
8412 /// $T(n, m) = O(n \log n \log\log n + m)$
8413 ///
8414 /// $M(n, m) = O(n \log n + m)$
8415 ///
8416 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8417 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8418 /// `max(self.significant_bits(), prec)`.
8419 ///
8420 /// # Panics
8421 /// Panics if `prec` is zero.
8422 ///
8423 /// # Examples
8424 /// ```
8425 /// use core::f64::consts::{E, PI, SQRT_2};
8426 /// use malachite_float::Float;
8427 /// use malachite_q::Rational;
8428 /// use std::cmp::Ordering::*;
8429 ///
8430 /// let y = Float::from(E);
8431 /// let z = Float::from(SQRT_2);
8432 /// let w = Rational::from_signeds(22, 7);
8433 ///
8434 /// let mut x = Float::from(PI);
8435 /// assert_eq!(
8436 /// x.mul_sub_mul_rational_prec_assign_val_val_ref(y.clone(), z.clone(), &w, 5),
8437 /// Less
8438 /// );
8439 /// assert_eq!(x.to_string(), "4.00");
8440 ///
8441 /// let mut x = Float::from(PI);
8442 /// assert_eq!(
8443 /// x.mul_sub_mul_rational_prec_assign_val_val_ref(y.clone(), z.clone(), &w, 20),
8444 /// Less
8445 /// );
8446 /// assert_eq!(x.to_string(), "4.0950623");
8447 /// ```
8448 #[allow(clippy::needless_pass_by_value)]
8449 #[inline]
8450 pub fn mul_sub_mul_rational_prec_assign_val_val_ref(
8451 &mut self,
8452 y: Self,
8453 z: Self,
8454 w: &Rational,
8455 prec: u64,
8456 ) -> Ordering {
8457 self.mul_sub_mul_rational_prec_round_assign_val_val_ref(y, z, w, prec, Nearest)
8458 }
8459
8460 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
8461 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
8462 /// specified precision. The middle [`Float`] on the right-hand side is taken by reference and
8463 /// the others by value. An [`Ordering`] is returned, indicating whether the rounded diff is
8464 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
8465 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
8466 ///
8467 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8468 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8469 /// the `Nearest` rounding mode.
8470 ///
8471 /// $$
8472 /// x \gets xy-zw+\varepsilon.
8473 /// $$
8474 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8475 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8476 /// |xy-zw|\rfloor-p}$.
8477 ///
8478 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
8479 /// overflow, and underflow.
8480 ///
8481 /// If you want to use a rounding mode other than `Nearest`, consider using
8482 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know that your target
8483 /// precision is the maximum of the precisions of the inputs, consider using
8484 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
8485 ///
8486 /// # Worst-case complexity
8487 /// $T(n, m) = O(n \log n \log\log n + m)$
8488 ///
8489 /// $M(n, m) = O(n \log n + m)$
8490 ///
8491 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8492 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8493 /// `max(self.significant_bits(), prec)`.
8494 ///
8495 /// # Panics
8496 /// Panics if `prec` is zero.
8497 ///
8498 /// # Examples
8499 /// ```
8500 /// use core::f64::consts::{E, PI, SQRT_2};
8501 /// use malachite_float::Float;
8502 /// use malachite_q::Rational;
8503 /// use std::cmp::Ordering::*;
8504 ///
8505 /// let y = Float::from(E);
8506 /// let z = Float::from(SQRT_2);
8507 /// let w = Rational::from_signeds(22, 7);
8508 ///
8509 /// let mut x = Float::from(PI);
8510 /// assert_eq!(
8511 /// x.mul_sub_mul_rational_prec_assign_val_ref_val(y.clone(), &z, w.clone(), 5),
8512 /// Less
8513 /// );
8514 /// assert_eq!(x.to_string(), "4.00");
8515 ///
8516 /// let mut x = Float::from(PI);
8517 /// assert_eq!(
8518 /// x.mul_sub_mul_rational_prec_assign_val_ref_val(y.clone(), &z, w.clone(), 20),
8519 /// Less
8520 /// );
8521 /// assert_eq!(x.to_string(), "4.0950623");
8522 /// ```
8523 #[allow(clippy::needless_pass_by_value)]
8524 #[inline]
8525 pub fn mul_sub_mul_rational_prec_assign_val_ref_val(
8526 &mut self,
8527 y: Self,
8528 z: &Self,
8529 w: Rational,
8530 prec: u64,
8531 ) -> Ordering {
8532 self.mul_sub_mul_rational_prec_round_assign_val_ref_val(y, z, w, prec, Nearest)
8533 }
8534
8535 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
8536 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
8537 /// specified precision. The first [`Float`] on the right-hand side is taken by value and the
8538 /// others by reference. An [`Ordering`] is returned, indicating whether the rounded diff is
8539 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
8540 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
8541 ///
8542 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8543 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8544 /// the `Nearest` rounding mode.
8545 ///
8546 /// $$
8547 /// x \gets xy-zw+\varepsilon.
8548 /// $$
8549 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8550 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8551 /// |xy-zw|\rfloor-p}$.
8552 ///
8553 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
8554 /// overflow, and underflow.
8555 ///
8556 /// If you want to use a rounding mode other than `Nearest`, consider using
8557 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know that your target
8558 /// precision is the maximum of the precisions of the inputs, consider using
8559 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
8560 ///
8561 /// # Worst-case complexity
8562 /// $T(n, m) = O(n \log n \log\log n + m)$
8563 ///
8564 /// $M(n, m) = O(n \log n + m)$
8565 ///
8566 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8567 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8568 /// `max(self.significant_bits(), prec)`.
8569 ///
8570 /// # Panics
8571 /// Panics if `prec` is zero.
8572 ///
8573 /// # Examples
8574 /// ```
8575 /// use core::f64::consts::{E, PI, SQRT_2};
8576 /// use malachite_float::Float;
8577 /// use malachite_q::Rational;
8578 /// use std::cmp::Ordering::*;
8579 ///
8580 /// let y = Float::from(E);
8581 /// let z = Float::from(SQRT_2);
8582 /// let w = Rational::from_signeds(22, 7);
8583 ///
8584 /// let mut x = Float::from(PI);
8585 /// assert_eq!(
8586 /// x.mul_sub_mul_rational_prec_assign_val_ref_ref(y.clone(), &z, &w, 5),
8587 /// Less
8588 /// );
8589 /// assert_eq!(x.to_string(), "4.00");
8590 ///
8591 /// let mut x = Float::from(PI);
8592 /// assert_eq!(
8593 /// x.mul_sub_mul_rational_prec_assign_val_ref_ref(y.clone(), &z, &w, 20),
8594 /// Less
8595 /// );
8596 /// assert_eq!(x.to_string(), "4.0950623");
8597 /// ```
8598 #[allow(clippy::needless_pass_by_value)]
8599 #[inline]
8600 pub fn mul_sub_mul_rational_prec_assign_val_ref_ref(
8601 &mut self,
8602 y: Self,
8603 z: &Self,
8604 w: &Rational,
8605 prec: u64,
8606 ) -> Ordering {
8607 self.mul_sub_mul_rational_prec_round_assign_val_ref_ref(y, z, w, prec, Nearest)
8608 }
8609
8610 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
8611 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
8612 /// specified precision. The first [`Float`] on the right-hand side is taken by reference and
8613 /// the others by value. An [`Ordering`] is returned, indicating whether the rounded diff is
8614 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
8615 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
8616 ///
8617 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8618 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8619 /// the `Nearest` rounding mode.
8620 ///
8621 /// $$
8622 /// x \gets xy-zw+\varepsilon.
8623 /// $$
8624 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8625 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8626 /// |xy-zw|\rfloor-p}$.
8627 ///
8628 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
8629 /// overflow, and underflow.
8630 ///
8631 /// If you want to use a rounding mode other than `Nearest`, consider using
8632 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know that your target
8633 /// precision is the maximum of the precisions of the inputs, consider using
8634 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
8635 ///
8636 /// # Worst-case complexity
8637 /// $T(n, m) = O(n \log n \log\log n + m)$
8638 ///
8639 /// $M(n, m) = O(n \log n + m)$
8640 ///
8641 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8642 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8643 /// `max(self.significant_bits(), prec)`.
8644 ///
8645 /// # Panics
8646 /// Panics if `prec` is zero.
8647 ///
8648 /// # Examples
8649 /// ```
8650 /// use core::f64::consts::{E, PI, SQRT_2};
8651 /// use malachite_float::Float;
8652 /// use malachite_q::Rational;
8653 /// use std::cmp::Ordering::*;
8654 ///
8655 /// let y = Float::from(E);
8656 /// let z = Float::from(SQRT_2);
8657 /// let w = Rational::from_signeds(22, 7);
8658 ///
8659 /// let mut x = Float::from(PI);
8660 /// assert_eq!(
8661 /// x.mul_sub_mul_rational_prec_assign_ref_val_val(&y, z.clone(), w.clone(), 5),
8662 /// Less
8663 /// );
8664 /// assert_eq!(x.to_string(), "4.00");
8665 ///
8666 /// let mut x = Float::from(PI);
8667 /// assert_eq!(
8668 /// x.mul_sub_mul_rational_prec_assign_ref_val_val(&y, z.clone(), w.clone(), 20),
8669 /// Less
8670 /// );
8671 /// assert_eq!(x.to_string(), "4.0950623");
8672 /// ```
8673 #[allow(clippy::needless_pass_by_value)]
8674 #[inline]
8675 pub fn mul_sub_mul_rational_prec_assign_ref_val_val(
8676 &mut self,
8677 y: &Self,
8678 z: Self,
8679 w: Rational,
8680 prec: u64,
8681 ) -> Ordering {
8682 self.mul_sub_mul_rational_prec_round_assign_ref_val_val(y, z, w, prec, Nearest)
8683 }
8684
8685 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
8686 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
8687 /// specified precision. The middle [`Float`] on the right-hand side is taken by value and the
8688 /// others by reference. An [`Ordering`] is returned, indicating whether the rounded diff is
8689 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
8690 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
8691 ///
8692 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8693 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8694 /// the `Nearest` rounding mode.
8695 ///
8696 /// $$
8697 /// x \gets xy-zw+\varepsilon.
8698 /// $$
8699 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8700 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8701 /// |xy-zw|\rfloor-p}$.
8702 ///
8703 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
8704 /// overflow, and underflow.
8705 ///
8706 /// If you want to use a rounding mode other than `Nearest`, consider using
8707 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know that your target
8708 /// precision is the maximum of the precisions of the inputs, consider using
8709 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
8710 ///
8711 /// # Worst-case complexity
8712 /// $T(n, m) = O(n \log n \log\log n + m)$
8713 ///
8714 /// $M(n, m) = O(n \log n + m)$
8715 ///
8716 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8717 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8718 /// `max(self.significant_bits(), prec)`.
8719 ///
8720 /// # Panics
8721 /// Panics if `prec` is zero.
8722 ///
8723 /// # Examples
8724 /// ```
8725 /// use core::f64::consts::{E, PI, SQRT_2};
8726 /// use malachite_float::Float;
8727 /// use malachite_q::Rational;
8728 /// use std::cmp::Ordering::*;
8729 ///
8730 /// let y = Float::from(E);
8731 /// let z = Float::from(SQRT_2);
8732 /// let w = Rational::from_signeds(22, 7);
8733 ///
8734 /// let mut x = Float::from(PI);
8735 /// assert_eq!(
8736 /// x.mul_sub_mul_rational_prec_assign_ref_val_ref(&y, z.clone(), &w, 5),
8737 /// Less
8738 /// );
8739 /// assert_eq!(x.to_string(), "4.00");
8740 ///
8741 /// let mut x = Float::from(PI);
8742 /// assert_eq!(
8743 /// x.mul_sub_mul_rational_prec_assign_ref_val_ref(&y, z.clone(), &w, 20),
8744 /// Less
8745 /// );
8746 /// assert_eq!(x.to_string(), "4.0950623");
8747 /// ```
8748 #[allow(clippy::needless_pass_by_value)]
8749 #[inline]
8750 pub fn mul_sub_mul_rational_prec_assign_ref_val_ref(
8751 &mut self,
8752 y: &Self,
8753 z: Self,
8754 w: &Rational,
8755 prec: u64,
8756 ) -> Ordering {
8757 self.mul_sub_mul_rational_prec_round_assign_ref_val_ref(y, z, w, prec, Nearest)
8758 }
8759
8760 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
8761 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
8762 /// specified precision. The last [`Float`] on the right-hand side is taken by value and the
8763 /// others by reference. An [`Ordering`] is returned, indicating whether the rounded diff is
8764 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
8765 /// any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
8766 ///
8767 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8768 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8769 /// the `Nearest` rounding mode.
8770 ///
8771 /// $$
8772 /// x \gets xy-zw+\varepsilon.
8773 /// $$
8774 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8775 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8776 /// |xy-zw|\rfloor-p}$.
8777 ///
8778 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
8779 /// overflow, and underflow.
8780 ///
8781 /// If you want to use a rounding mode other than `Nearest`, consider using
8782 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know that your target
8783 /// precision is the maximum of the precisions of the inputs, consider using
8784 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
8785 ///
8786 /// # Worst-case complexity
8787 /// $T(n, m) = O(n \log n \log\log n + m)$
8788 ///
8789 /// $M(n, m) = O(n \log n + m)$
8790 ///
8791 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8792 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8793 /// `max(self.significant_bits(), prec)`.
8794 ///
8795 /// # Panics
8796 /// Panics if `prec` is zero.
8797 ///
8798 /// # Examples
8799 /// ```
8800 /// use core::f64::consts::{E, PI, SQRT_2};
8801 /// use malachite_float::Float;
8802 /// use malachite_q::Rational;
8803 /// use std::cmp::Ordering::*;
8804 ///
8805 /// let y = Float::from(E);
8806 /// let z = Float::from(SQRT_2);
8807 /// let w = Rational::from_signeds(22, 7);
8808 ///
8809 /// let mut x = Float::from(PI);
8810 /// assert_eq!(
8811 /// x.mul_sub_mul_rational_prec_assign_ref_ref_val(&y, &z, w.clone(), 5),
8812 /// Less
8813 /// );
8814 /// assert_eq!(x.to_string(), "4.00");
8815 ///
8816 /// let mut x = Float::from(PI);
8817 /// assert_eq!(
8818 /// x.mul_sub_mul_rational_prec_assign_ref_ref_val(&y, &z, w.clone(), 20),
8819 /// Less
8820 /// );
8821 /// assert_eq!(x.to_string(), "4.0950623");
8822 /// ```
8823 #[allow(clippy::needless_pass_by_value)]
8824 #[inline]
8825 pub fn mul_sub_mul_rational_prec_assign_ref_ref_val(
8826 &mut self,
8827 y: &Self,
8828 z: &Self,
8829 w: Rational,
8830 prec: u64,
8831 ) -> Ordering {
8832 self.mul_sub_mul_rational_prec_round_assign_ref_ref_val(y, z, w, prec, Nearest)
8833 }
8834
8835 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
8836 /// [`Float`]s, with a single rounding, rounding the result to the nearest value of the
8837 /// specified precision. The [`Float`]s on the right-hand side are all taken by reference. An
8838 /// [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
8839 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
8840 /// this function assigns a `NaN` it also returns `Equal`.
8841 ///
8842 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8843 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8844 /// the `Nearest` rounding mode.
8845 ///
8846 /// $$
8847 /// x \gets xy-zw+\varepsilon.
8848 /// $$
8849 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8850 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8851 /// |xy-zw|\rfloor-p}$.
8852 ///
8853 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
8854 /// overflow, and underflow.
8855 ///
8856 /// If you want to use a rounding mode other than `Nearest`, consider using
8857 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know that your target
8858 /// precision is the maximum of the precisions of the inputs, consider using
8859 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
8860 ///
8861 /// # Worst-case complexity
8862 /// $T(n, m) = O(n \log n \log\log n + m)$
8863 ///
8864 /// $M(n, m) = O(n \log n + m)$
8865 ///
8866 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8867 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8868 /// `max(self.significant_bits(), prec)`.
8869 ///
8870 /// # Panics
8871 /// Panics if `prec` is zero.
8872 ///
8873 /// # Examples
8874 /// ```
8875 /// use core::f64::consts::{E, PI, SQRT_2};
8876 /// use malachite_float::Float;
8877 /// use malachite_q::Rational;
8878 /// use std::cmp::Ordering::*;
8879 ///
8880 /// let y = Float::from(E);
8881 /// let z = Float::from(SQRT_2);
8882 /// let w = Rational::from_signeds(22, 7);
8883 ///
8884 /// let mut x = Float::from(PI);
8885 /// assert_eq!(
8886 /// x.mul_sub_mul_rational_prec_assign_ref_ref_ref(&y, &z, &w, 5),
8887 /// Less
8888 /// );
8889 /// assert_eq!(x.to_string(), "4.00");
8890 ///
8891 /// let mut x = Float::from(PI);
8892 /// assert_eq!(
8893 /// x.mul_sub_mul_rational_prec_assign_ref_ref_ref(&y, &z, &w, 20),
8894 /// Less
8895 /// );
8896 /// assert_eq!(x.to_string(), "4.0950623");
8897 /// ```
8898 #[allow(clippy::needless_pass_by_value)]
8899 #[inline]
8900 pub fn mul_sub_mul_rational_prec_assign_ref_ref_ref(
8901 &mut self,
8902 y: &Self,
8903 z: &Self,
8904 w: &Rational,
8905 prec: u64,
8906 ) -> Ordering {
8907 self.mul_sub_mul_rational_prec_round_assign_ref_ref_ref(y, z, w, prec, Nearest)
8908 }
8909
8910 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
8911 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
8912 /// exactly and the products are not rounded before the final subtraction, so there is a single
8913 /// rounding. The [`Float`]s and the [`Rational`] are all taken by value. An [`Ordering`] is
8914 /// also returned, indicating whether the rounded diff is less than, equal to, or greater than
8915 /// the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
8916 /// returns a `NaN` it also returns `Equal`.
8917 ///
8918 /// The precision of the output is the maximum of the precisions of the inputs. See
8919 /// [`RoundingMode`] for a description of the possible rounding modes.
8920 ///
8921 /// $$
8922 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
8923 /// $$
8924 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8925 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
8926 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
8927 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
8928 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
8929 ///
8930 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8931 ///
8932 /// Special cases:
8933 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
8934 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
8935 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
8936 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
8937 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
8938 /// [`Rational`] counts as an unsigned zero and a positive sign.
8939 /// - If exactly one product is infinite, the result is that product's infinity, the second
8940 /// product's sign counting as flipped.
8941 /// - If both products are infinite, the result is their common infinity if their signs differ,
8942 /// and `NaN` otherwise.
8943 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
8944 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
8945 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
8946 ///
8947 /// Overflow and underflow:
8948 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
8949 /// returned instead.
8950 /// - 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}$
8951 /// is returned instead, where `p` is the precision of the output.
8952 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
8953 /// returned instead.
8954 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
8955 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
8956 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
8957 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
8958 /// instead.
8959 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
8960 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
8961 /// returned instead.
8962 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
8963 /// instead.
8964 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
8965 /// instead.
8966 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
8967 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
8968 /// returned instead.
8969 ///
8970 /// If you want to specify an output precision, consider using
8971 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know you'll be using the
8972 /// `Nearest` rounding mode, consider using
8973 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
8974 ///
8975 /// # Worst-case complexity
8976 /// $T(n, m) = O(n \log n \log\log n + m)$
8977 ///
8978 /// $M(n, m) = O(n \log n + m)$
8979 ///
8980 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8981 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
8982 /// `self.significant_bits()`.
8983 ///
8984 /// # Panics
8985 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
8986 /// represent the output.
8987 ///
8988 /// # Examples
8989 /// ```
8990 /// use core::f64::consts::{E, PI, SQRT_2};
8991 /// use malachite_base::rounding_modes::RoundingMode::*;
8992 /// use malachite_float::Float;
8993 /// use malachite_q::Rational;
8994 /// use std::cmp::Ordering::*;
8995 ///
8996 /// let x = Float::from(PI);
8997 /// let y = Float::from(E);
8998 /// let z = Float::from(SQRT_2);
8999 /// let w = Rational::from_signeds(22, 7);
9000 ///
9001 /// let (diff, o) =
9002 /// x.clone()
9003 /// .mul_sub_mul_rational_round(y.clone(), z.clone(), w.clone(), Floor);
9004 /// assert_eq!(diff.to_string(), "4.0950630266438379");
9005 /// assert_eq!(o, Less);
9006 ///
9007 /// let (diff, o) =
9008 /// x.clone()
9009 /// .mul_sub_mul_rational_round(y.clone(), z.clone(), w.clone(), Ceiling);
9010 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9011 /// assert_eq!(o, Greater);
9012 ///
9013 /// let (diff, o) =
9014 /// x.clone()
9015 /// .mul_sub_mul_rational_round(y.clone(), z.clone(), w.clone(), Nearest);
9016 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9017 /// assert_eq!(o, Greater);
9018 /// ```
9019 #[allow(clippy::needless_pass_by_value)]
9020 #[inline]
9021 pub fn mul_sub_mul_rational_round(
9022 self,
9023 y: Self,
9024 z: Self,
9025 w: Rational,
9026 rm: RoundingMode,
9027 ) -> (Self, Ordering) {
9028 let prec = max!(
9029 self.significant_bits(),
9030 y.significant_bits(),
9031 z.significant_bits()
9032 );
9033 self.mul_sub_mul_rational_prec_round(y, z, w, prec, rm)
9034 }
9035
9036 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
9037 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9038 /// exactly and the products are not rounded before the final subtraction, so there is a single
9039 /// rounding. The [`Float`]s are taken by value and the [`Rational`] by reference. An
9040 /// [`Ordering`] is also returned, indicating whether the rounded diff is less than, equal to,
9041 /// or greater than the exact diff. Although `NaN`s are not comparable to any [`Float`],
9042 /// whenever this function returns a `NaN` it also returns `Equal`.
9043 ///
9044 /// The precision of the output is the maximum of the precisions of the inputs. See
9045 /// [`RoundingMode`] for a description of the possible rounding modes.
9046 ///
9047 /// $$
9048 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
9049 /// $$
9050 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9051 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
9052 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
9053 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
9054 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
9055 ///
9056 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9057 ///
9058 /// Special cases:
9059 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9060 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9061 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9062 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9063 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
9064 /// [`Rational`] counts as an unsigned zero and a positive sign.
9065 /// - If exactly one product is infinite, the result is that product's infinity, the second
9066 /// product's sign counting as flipped.
9067 /// - If both products are infinite, the result is their common infinity if their signs differ,
9068 /// and `NaN` otherwise.
9069 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
9070 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
9071 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
9072 ///
9073 /// Overflow and underflow:
9074 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
9075 /// returned instead.
9076 /// - 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}$
9077 /// is returned instead, where `p` is the precision of the output.
9078 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
9079 /// returned instead.
9080 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
9081 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
9082 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
9083 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
9084 /// instead.
9085 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
9086 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
9087 /// returned instead.
9088 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
9089 /// instead.
9090 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
9091 /// instead.
9092 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
9093 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
9094 /// returned instead.
9095 ///
9096 /// If you want to specify an output precision, consider using
9097 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know you'll be using the
9098 /// `Nearest` rounding mode, consider using
9099 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
9100 ///
9101 /// # Worst-case complexity
9102 /// $T(n, m) = O(n \log n \log\log n + m)$
9103 ///
9104 /// $M(n, m) = O(n \log n + m)$
9105 ///
9106 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9107 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9108 /// `self.significant_bits()`.
9109 ///
9110 /// # Panics
9111 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
9112 /// represent the output.
9113 ///
9114 /// # Examples
9115 /// ```
9116 /// use core::f64::consts::{E, PI, SQRT_2};
9117 /// use malachite_base::rounding_modes::RoundingMode::*;
9118 /// use malachite_float::Float;
9119 /// use malachite_q::Rational;
9120 /// use std::cmp::Ordering::*;
9121 ///
9122 /// let x = Float::from(PI);
9123 /// let y = Float::from(E);
9124 /// let z = Float::from(SQRT_2);
9125 /// let w = Rational::from_signeds(22, 7);
9126 ///
9127 /// let (diff, o) =
9128 /// x.clone()
9129 /// .mul_sub_mul_rational_round_val_val_val_ref(y.clone(), z.clone(), &w, Floor);
9130 /// assert_eq!(diff.to_string(), "4.0950630266438379");
9131 /// assert_eq!(o, Less);
9132 ///
9133 /// let (diff, o) =
9134 /// x.clone()
9135 /// .mul_sub_mul_rational_round_val_val_val_ref(y.clone(), z.clone(), &w, Ceiling);
9136 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9137 /// assert_eq!(o, Greater);
9138 ///
9139 /// let (diff, o) =
9140 /// x.clone()
9141 /// .mul_sub_mul_rational_round_val_val_val_ref(y.clone(), z.clone(), &w, Nearest);
9142 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9143 /// assert_eq!(o, Greater);
9144 /// ```
9145 #[allow(clippy::needless_pass_by_value)]
9146 #[inline]
9147 pub fn mul_sub_mul_rational_round_val_val_val_ref(
9148 self,
9149 y: Self,
9150 z: Self,
9151 w: &Rational,
9152 rm: RoundingMode,
9153 ) -> (Self, Ordering) {
9154 let prec = max!(
9155 self.significant_bits(),
9156 y.significant_bits(),
9157 z.significant_bits()
9158 );
9159 self.mul_sub_mul_rational_prec_round_val_val_val_ref(y, z, w, prec, rm)
9160 }
9161
9162 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
9163 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9164 /// exactly and the products are not rounded before the final subtraction, so there is a single
9165 /// rounding. The third [`Float`] is taken by reference and the other operands by value. An
9166 /// [`Ordering`] is also returned, indicating whether the rounded diff is less than, equal to,
9167 /// or greater than the exact diff. Although `NaN`s are not comparable to any [`Float`],
9168 /// whenever this function returns a `NaN` it also returns `Equal`.
9169 ///
9170 /// The precision of the output is the maximum of the precisions of the inputs. See
9171 /// [`RoundingMode`] for a description of the possible rounding modes.
9172 ///
9173 /// $$
9174 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
9175 /// $$
9176 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9177 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
9178 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
9179 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
9180 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
9181 ///
9182 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9183 ///
9184 /// Special cases:
9185 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9186 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9187 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9188 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9189 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
9190 /// [`Rational`] counts as an unsigned zero and a positive sign.
9191 /// - If exactly one product is infinite, the result is that product's infinity, the second
9192 /// product's sign counting as flipped.
9193 /// - If both products are infinite, the result is their common infinity if their signs differ,
9194 /// and `NaN` otherwise.
9195 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
9196 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
9197 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
9198 ///
9199 /// Overflow and underflow:
9200 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
9201 /// returned instead.
9202 /// - 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}$
9203 /// is returned instead, where `p` is the precision of the output.
9204 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
9205 /// returned instead.
9206 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
9207 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
9208 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
9209 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
9210 /// instead.
9211 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
9212 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
9213 /// returned instead.
9214 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
9215 /// instead.
9216 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
9217 /// instead.
9218 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
9219 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
9220 /// returned instead.
9221 ///
9222 /// If you want to specify an output precision, consider using
9223 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know you'll be using the
9224 /// `Nearest` rounding mode, consider using
9225 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
9226 ///
9227 /// # Worst-case complexity
9228 /// $T(n, m) = O(n \log n \log\log n + m)$
9229 ///
9230 /// $M(n, m) = O(n \log n + m)$
9231 ///
9232 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9233 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9234 /// `self.significant_bits()`.
9235 ///
9236 /// # Panics
9237 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
9238 /// represent the output.
9239 ///
9240 /// # Examples
9241 /// ```
9242 /// use core::f64::consts::{E, PI, SQRT_2};
9243 /// use malachite_base::rounding_modes::RoundingMode::*;
9244 /// use malachite_float::Float;
9245 /// use malachite_q::Rational;
9246 /// use std::cmp::Ordering::*;
9247 ///
9248 /// let x = Float::from(PI);
9249 /// let y = Float::from(E);
9250 /// let z = Float::from(SQRT_2);
9251 /// let w = Rational::from_signeds(22, 7);
9252 ///
9253 /// let (diff, o) =
9254 /// x.clone()
9255 /// .mul_sub_mul_rational_round_val_val_ref_val(y.clone(), &z, w.clone(), Floor);
9256 /// assert_eq!(diff.to_string(), "4.0950630266438379");
9257 /// assert_eq!(o, Less);
9258 ///
9259 /// let (diff, o) =
9260 /// x.clone()
9261 /// .mul_sub_mul_rational_round_val_val_ref_val(y.clone(), &z, w.clone(), Ceiling);
9262 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9263 /// assert_eq!(o, Greater);
9264 ///
9265 /// let (diff, o) =
9266 /// x.clone()
9267 /// .mul_sub_mul_rational_round_val_val_ref_val(y.clone(), &z, w.clone(), Nearest);
9268 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9269 /// assert_eq!(o, Greater);
9270 /// ```
9271 #[allow(clippy::needless_pass_by_value)]
9272 #[inline]
9273 pub fn mul_sub_mul_rational_round_val_val_ref_val(
9274 self,
9275 y: Self,
9276 z: &Self,
9277 w: Rational,
9278 rm: RoundingMode,
9279 ) -> (Self, Ordering) {
9280 let prec = max!(
9281 self.significant_bits(),
9282 y.significant_bits(),
9283 z.significant_bits()
9284 );
9285 self.mul_sub_mul_rational_prec_round_val_val_ref_val(y, z, w, prec, rm)
9286 }
9287
9288 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
9289 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9290 /// exactly and the products are not rounded before the final subtraction, so there is a single
9291 /// rounding. The first two [`Float`]s are taken by value and the third [`Float`] and the
9292 /// [`Rational`] by reference. An [`Ordering`] is also returned, indicating whether the rounded
9293 /// diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
9294 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
9295 ///
9296 /// The precision of the output is the maximum of the precisions of the inputs. See
9297 /// [`RoundingMode`] for a description of the possible rounding modes.
9298 ///
9299 /// $$
9300 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
9301 /// $$
9302 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9303 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
9304 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
9305 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
9306 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
9307 ///
9308 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9309 ///
9310 /// Special cases:
9311 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9312 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9313 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9314 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9315 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
9316 /// [`Rational`] counts as an unsigned zero and a positive sign.
9317 /// - If exactly one product is infinite, the result is that product's infinity, the second
9318 /// product's sign counting as flipped.
9319 /// - If both products are infinite, the result is their common infinity if their signs differ,
9320 /// and `NaN` otherwise.
9321 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
9322 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
9323 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
9324 ///
9325 /// Overflow and underflow:
9326 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
9327 /// returned instead.
9328 /// - 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}$
9329 /// is returned instead, where `p` is the precision of the output.
9330 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
9331 /// returned instead.
9332 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
9333 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
9334 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
9335 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
9336 /// instead.
9337 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
9338 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
9339 /// returned instead.
9340 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
9341 /// instead.
9342 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
9343 /// instead.
9344 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
9345 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
9346 /// returned instead.
9347 ///
9348 /// If you want to specify an output precision, consider using
9349 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know you'll be using the
9350 /// `Nearest` rounding mode, consider using
9351 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
9352 ///
9353 /// # Worst-case complexity
9354 /// $T(n, m) = O(n \log n \log\log n + m)$
9355 ///
9356 /// $M(n, m) = O(n \log n + m)$
9357 ///
9358 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9359 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9360 /// `self.significant_bits()`.
9361 ///
9362 /// # Panics
9363 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
9364 /// represent the output.
9365 ///
9366 /// # Examples
9367 /// ```
9368 /// use core::f64::consts::{E, PI, SQRT_2};
9369 /// use malachite_base::rounding_modes::RoundingMode::*;
9370 /// use malachite_float::Float;
9371 /// use malachite_q::Rational;
9372 /// use std::cmp::Ordering::*;
9373 ///
9374 /// let x = Float::from(PI);
9375 /// let y = Float::from(E);
9376 /// let z = Float::from(SQRT_2);
9377 /// let w = Rational::from_signeds(22, 7);
9378 ///
9379 /// let (diff, o) =
9380 /// x.clone()
9381 /// .mul_sub_mul_rational_round_val_val_ref_ref(y.clone(), &z, &w, Floor);
9382 /// assert_eq!(diff.to_string(), "4.0950630266438379");
9383 /// assert_eq!(o, Less);
9384 ///
9385 /// let (diff, o) =
9386 /// x.clone()
9387 /// .mul_sub_mul_rational_round_val_val_ref_ref(y.clone(), &z, &w, Ceiling);
9388 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9389 /// assert_eq!(o, Greater);
9390 ///
9391 /// let (diff, o) =
9392 /// x.clone()
9393 /// .mul_sub_mul_rational_round_val_val_ref_ref(y.clone(), &z, &w, Nearest);
9394 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9395 /// assert_eq!(o, Greater);
9396 /// ```
9397 #[allow(clippy::needless_pass_by_value)]
9398 #[inline]
9399 pub fn mul_sub_mul_rational_round_val_val_ref_ref(
9400 self,
9401 y: Self,
9402 z: &Self,
9403 w: &Rational,
9404 rm: RoundingMode,
9405 ) -> (Self, Ordering) {
9406 let prec = max!(
9407 self.significant_bits(),
9408 y.significant_bits(),
9409 z.significant_bits()
9410 );
9411 self.mul_sub_mul_rational_prec_round_val_val_ref_ref(y, z, w, prec, rm)
9412 }
9413
9414 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
9415 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9416 /// exactly and the products are not rounded before the final subtraction, so there is a single
9417 /// rounding. The second [`Float`] is taken by reference and the other operands by value. An
9418 /// [`Ordering`] is also returned, indicating whether the rounded diff is less than, equal to,
9419 /// or greater than the exact diff. Although `NaN`s are not comparable to any [`Float`],
9420 /// whenever this function returns a `NaN` it also returns `Equal`.
9421 ///
9422 /// The precision of the output is the maximum of the precisions of the inputs. See
9423 /// [`RoundingMode`] for a description of the possible rounding modes.
9424 ///
9425 /// $$
9426 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
9427 /// $$
9428 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9429 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
9430 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
9431 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
9432 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
9433 ///
9434 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9435 ///
9436 /// Special cases:
9437 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9438 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9439 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9440 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9441 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
9442 /// [`Rational`] counts as an unsigned zero and a positive sign.
9443 /// - If exactly one product is infinite, the result is that product's infinity, the second
9444 /// product's sign counting as flipped.
9445 /// - If both products are infinite, the result is their common infinity if their signs differ,
9446 /// and `NaN` otherwise.
9447 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
9448 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
9449 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
9450 ///
9451 /// Overflow and underflow:
9452 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
9453 /// returned instead.
9454 /// - 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}$
9455 /// is returned instead, where `p` is the precision of the output.
9456 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
9457 /// returned instead.
9458 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
9459 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
9460 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
9461 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
9462 /// instead.
9463 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
9464 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
9465 /// returned instead.
9466 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
9467 /// instead.
9468 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
9469 /// instead.
9470 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
9471 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
9472 /// returned instead.
9473 ///
9474 /// If you want to specify an output precision, consider using
9475 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know you'll be using the
9476 /// `Nearest` rounding mode, consider using
9477 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
9478 ///
9479 /// # Worst-case complexity
9480 /// $T(n, m) = O(n \log n \log\log n + m)$
9481 ///
9482 /// $M(n, m) = O(n \log n + m)$
9483 ///
9484 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9485 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9486 /// `self.significant_bits()`.
9487 ///
9488 /// # Panics
9489 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
9490 /// represent the output.
9491 ///
9492 /// # Examples
9493 /// ```
9494 /// use core::f64::consts::{E, PI, SQRT_2};
9495 /// use malachite_base::rounding_modes::RoundingMode::*;
9496 /// use malachite_float::Float;
9497 /// use malachite_q::Rational;
9498 /// use std::cmp::Ordering::*;
9499 ///
9500 /// let x = Float::from(PI);
9501 /// let y = Float::from(E);
9502 /// let z = Float::from(SQRT_2);
9503 /// let w = Rational::from_signeds(22, 7);
9504 ///
9505 /// let (diff, o) =
9506 /// x.clone()
9507 /// .mul_sub_mul_rational_round_val_ref_val_val(&y, z.clone(), w.clone(), Floor);
9508 /// assert_eq!(diff.to_string(), "4.0950630266438379");
9509 /// assert_eq!(o, Less);
9510 ///
9511 /// let (diff, o) =
9512 /// x.clone()
9513 /// .mul_sub_mul_rational_round_val_ref_val_val(&y, z.clone(), w.clone(), Ceiling);
9514 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9515 /// assert_eq!(o, Greater);
9516 ///
9517 /// let (diff, o) =
9518 /// x.clone()
9519 /// .mul_sub_mul_rational_round_val_ref_val_val(&y, z.clone(), w.clone(), Nearest);
9520 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9521 /// assert_eq!(o, Greater);
9522 /// ```
9523 #[allow(clippy::needless_pass_by_value)]
9524 #[inline]
9525 pub fn mul_sub_mul_rational_round_val_ref_val_val(
9526 self,
9527 y: &Self,
9528 z: Self,
9529 w: Rational,
9530 rm: RoundingMode,
9531 ) -> (Self, Ordering) {
9532 let prec = max!(
9533 self.significant_bits(),
9534 y.significant_bits(),
9535 z.significant_bits()
9536 );
9537 self.mul_sub_mul_rational_prec_round_val_ref_val_val(y, z, w, prec, rm)
9538 }
9539
9540 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
9541 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9542 /// exactly and the products are not rounded before the final subtraction, so there is a single
9543 /// rounding. The second [`Float`] and the [`Rational`] are taken by reference and the other
9544 /// operands by value. An [`Ordering`] is also returned, indicating whether the rounded diff is
9545 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
9546 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
9547 ///
9548 /// The precision of the output is the maximum of the precisions of the inputs. See
9549 /// [`RoundingMode`] for a description of the possible rounding modes.
9550 ///
9551 /// $$
9552 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
9553 /// $$
9554 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9555 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
9556 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
9557 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
9558 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
9559 ///
9560 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9561 ///
9562 /// Special cases:
9563 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9564 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9565 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9566 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9567 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
9568 /// [`Rational`] counts as an unsigned zero and a positive sign.
9569 /// - If exactly one product is infinite, the result is that product's infinity, the second
9570 /// product's sign counting as flipped.
9571 /// - If both products are infinite, the result is their common infinity if their signs differ,
9572 /// and `NaN` otherwise.
9573 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
9574 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
9575 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
9576 ///
9577 /// Overflow and underflow:
9578 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
9579 /// returned instead.
9580 /// - 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}$
9581 /// is returned instead, where `p` is the precision of the output.
9582 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
9583 /// returned instead.
9584 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
9585 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
9586 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
9587 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
9588 /// instead.
9589 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
9590 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
9591 /// returned instead.
9592 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
9593 /// instead.
9594 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
9595 /// instead.
9596 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
9597 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
9598 /// returned instead.
9599 ///
9600 /// If you want to specify an output precision, consider using
9601 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know you'll be using the
9602 /// `Nearest` rounding mode, consider using
9603 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
9604 ///
9605 /// # Worst-case complexity
9606 /// $T(n, m) = O(n \log n \log\log n + m)$
9607 ///
9608 /// $M(n, m) = O(n \log n + m)$
9609 ///
9610 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9611 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9612 /// `self.significant_bits()`.
9613 ///
9614 /// # Panics
9615 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
9616 /// represent the output.
9617 ///
9618 /// # Examples
9619 /// ```
9620 /// use core::f64::consts::{E, PI, SQRT_2};
9621 /// use malachite_base::rounding_modes::RoundingMode::*;
9622 /// use malachite_float::Float;
9623 /// use malachite_q::Rational;
9624 /// use std::cmp::Ordering::*;
9625 ///
9626 /// let x = Float::from(PI);
9627 /// let y = Float::from(E);
9628 /// let z = Float::from(SQRT_2);
9629 /// let w = Rational::from_signeds(22, 7);
9630 ///
9631 /// let (diff, o) =
9632 /// x.clone()
9633 /// .mul_sub_mul_rational_round_val_ref_val_ref(&y, z.clone(), &w, Floor);
9634 /// assert_eq!(diff.to_string(), "4.0950630266438379");
9635 /// assert_eq!(o, Less);
9636 ///
9637 /// let (diff, o) =
9638 /// x.clone()
9639 /// .mul_sub_mul_rational_round_val_ref_val_ref(&y, z.clone(), &w, Ceiling);
9640 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9641 /// assert_eq!(o, Greater);
9642 ///
9643 /// let (diff, o) =
9644 /// x.clone()
9645 /// .mul_sub_mul_rational_round_val_ref_val_ref(&y, z.clone(), &w, Nearest);
9646 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9647 /// assert_eq!(o, Greater);
9648 /// ```
9649 #[allow(clippy::needless_pass_by_value)]
9650 #[inline]
9651 pub fn mul_sub_mul_rational_round_val_ref_val_ref(
9652 self,
9653 y: &Self,
9654 z: Self,
9655 w: &Rational,
9656 rm: RoundingMode,
9657 ) -> (Self, Ordering) {
9658 let prec = max!(
9659 self.significant_bits(),
9660 y.significant_bits(),
9661 z.significant_bits()
9662 );
9663 self.mul_sub_mul_rational_prec_round_val_ref_val_ref(y, z, w, prec, rm)
9664 }
9665
9666 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
9667 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9668 /// exactly and the products are not rounded before the final subtraction, so there is a single
9669 /// rounding. The second and third [`Float`]s are taken by reference and the other operands by
9670 /// value. An [`Ordering`] is also returned, indicating whether the rounded diff is less than,
9671 /// equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
9672 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
9673 ///
9674 /// The precision of the output is the maximum of the precisions of the inputs. See
9675 /// [`RoundingMode`] for a description of the possible rounding modes.
9676 ///
9677 /// $$
9678 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
9679 /// $$
9680 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9681 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
9682 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
9683 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
9684 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
9685 ///
9686 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9687 ///
9688 /// Special cases:
9689 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9690 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9691 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9692 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9693 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
9694 /// [`Rational`] counts as an unsigned zero and a positive sign.
9695 /// - If exactly one product is infinite, the result is that product's infinity, the second
9696 /// product's sign counting as flipped.
9697 /// - If both products are infinite, the result is their common infinity if their signs differ,
9698 /// and `NaN` otherwise.
9699 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
9700 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
9701 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
9702 ///
9703 /// Overflow and underflow:
9704 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
9705 /// returned instead.
9706 /// - 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}$
9707 /// is returned instead, where `p` is the precision of the output.
9708 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
9709 /// returned instead.
9710 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
9711 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
9712 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
9713 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
9714 /// instead.
9715 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
9716 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
9717 /// returned instead.
9718 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
9719 /// instead.
9720 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
9721 /// instead.
9722 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
9723 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
9724 /// returned instead.
9725 ///
9726 /// If you want to specify an output precision, consider using
9727 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know you'll be using the
9728 /// `Nearest` rounding mode, consider using
9729 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
9730 ///
9731 /// # Worst-case complexity
9732 /// $T(n, m) = O(n \log n \log\log n + m)$
9733 ///
9734 /// $M(n, m) = O(n \log n + m)$
9735 ///
9736 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9737 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9738 /// `self.significant_bits()`.
9739 ///
9740 /// # Panics
9741 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
9742 /// represent the output.
9743 ///
9744 /// # Examples
9745 /// ```
9746 /// use core::f64::consts::{E, PI, SQRT_2};
9747 /// use malachite_base::rounding_modes::RoundingMode::*;
9748 /// use malachite_float::Float;
9749 /// use malachite_q::Rational;
9750 /// use std::cmp::Ordering::*;
9751 ///
9752 /// let x = Float::from(PI);
9753 /// let y = Float::from(E);
9754 /// let z = Float::from(SQRT_2);
9755 /// let w = Rational::from_signeds(22, 7);
9756 ///
9757 /// let (diff, o) =
9758 /// x.clone()
9759 /// .mul_sub_mul_rational_round_val_ref_ref_val(&y, &z, w.clone(), Floor);
9760 /// assert_eq!(diff.to_string(), "4.0950630266438379");
9761 /// assert_eq!(o, Less);
9762 ///
9763 /// let (diff, o) =
9764 /// x.clone()
9765 /// .mul_sub_mul_rational_round_val_ref_ref_val(&y, &z, w.clone(), Ceiling);
9766 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9767 /// assert_eq!(o, Greater);
9768 ///
9769 /// let (diff, o) =
9770 /// x.clone()
9771 /// .mul_sub_mul_rational_round_val_ref_ref_val(&y, &z, w.clone(), Nearest);
9772 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9773 /// assert_eq!(o, Greater);
9774 /// ```
9775 #[allow(clippy::needless_pass_by_value)]
9776 #[inline]
9777 pub fn mul_sub_mul_rational_round_val_ref_ref_val(
9778 self,
9779 y: &Self,
9780 z: &Self,
9781 w: Rational,
9782 rm: RoundingMode,
9783 ) -> (Self, Ordering) {
9784 let prec = max!(
9785 self.significant_bits(),
9786 y.significant_bits(),
9787 z.significant_bits()
9788 );
9789 self.mul_sub_mul_rational_prec_round_val_ref_ref_val(y, z, w, prec, rm)
9790 }
9791
9792 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
9793 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9794 /// exactly and the products are not rounded before the final subtraction, so there is a single
9795 /// rounding. The first [`Float`] is taken by value and the other operands by reference. An
9796 /// [`Ordering`] is also returned, indicating whether the rounded diff is less than, equal to,
9797 /// or greater than the exact diff. Although `NaN`s are not comparable to any [`Float`],
9798 /// whenever this function returns a `NaN` it also returns `Equal`.
9799 ///
9800 /// The precision of the output is the maximum of the precisions of the inputs. See
9801 /// [`RoundingMode`] for a description of the possible rounding modes.
9802 ///
9803 /// $$
9804 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
9805 /// $$
9806 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9807 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
9808 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
9809 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
9810 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
9811 ///
9812 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9813 ///
9814 /// Special cases:
9815 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9816 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9817 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9818 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9819 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
9820 /// [`Rational`] counts as an unsigned zero and a positive sign.
9821 /// - If exactly one product is infinite, the result is that product's infinity, the second
9822 /// product's sign counting as flipped.
9823 /// - If both products are infinite, the result is their common infinity if their signs differ,
9824 /// and `NaN` otherwise.
9825 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
9826 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
9827 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
9828 ///
9829 /// Overflow and underflow:
9830 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
9831 /// returned instead.
9832 /// - 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}$
9833 /// is returned instead, where `p` is the precision of the output.
9834 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
9835 /// returned instead.
9836 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
9837 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
9838 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
9839 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
9840 /// instead.
9841 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
9842 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
9843 /// returned instead.
9844 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
9845 /// instead.
9846 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
9847 /// instead.
9848 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
9849 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
9850 /// returned instead.
9851 ///
9852 /// If you want to specify an output precision, consider using
9853 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know you'll be using the
9854 /// `Nearest` rounding mode, consider using
9855 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
9856 ///
9857 /// # Worst-case complexity
9858 /// $T(n, m) = O(n \log n \log\log n + m)$
9859 ///
9860 /// $M(n, m) = O(n \log n + m)$
9861 ///
9862 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9863 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9864 /// `self.significant_bits()`.
9865 ///
9866 /// # Panics
9867 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
9868 /// represent the output.
9869 ///
9870 /// # Examples
9871 /// ```
9872 /// use core::f64::consts::{E, PI, SQRT_2};
9873 /// use malachite_base::rounding_modes::RoundingMode::*;
9874 /// use malachite_float::Float;
9875 /// use malachite_q::Rational;
9876 /// use std::cmp::Ordering::*;
9877 ///
9878 /// let x = Float::from(PI);
9879 /// let y = Float::from(E);
9880 /// let z = Float::from(SQRT_2);
9881 /// let w = Rational::from_signeds(22, 7);
9882 ///
9883 /// let (diff, o) = x
9884 /// .clone()
9885 /// .mul_sub_mul_rational_round_val_ref_ref_ref(&y, &z, &w, Floor);
9886 /// assert_eq!(diff.to_string(), "4.0950630266438379");
9887 /// assert_eq!(o, Less);
9888 ///
9889 /// let (diff, o) = x
9890 /// .clone()
9891 /// .mul_sub_mul_rational_round_val_ref_ref_ref(&y, &z, &w, Ceiling);
9892 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9893 /// assert_eq!(o, Greater);
9894 ///
9895 /// let (diff, o) = x
9896 /// .clone()
9897 /// .mul_sub_mul_rational_round_val_ref_ref_ref(&y, &z, &w, Nearest);
9898 /// assert_eq!(diff.to_string(), "4.0950630266438388");
9899 /// assert_eq!(o, Greater);
9900 /// ```
9901 #[allow(clippy::needless_pass_by_value)]
9902 #[inline]
9903 pub fn mul_sub_mul_rational_round_val_ref_ref_ref(
9904 self,
9905 y: &Self,
9906 z: &Self,
9907 w: &Rational,
9908 rm: RoundingMode,
9909 ) -> (Self, Ordering) {
9910 let prec = max!(
9911 self.significant_bits(),
9912 y.significant_bits(),
9913 z.significant_bits()
9914 );
9915 self.mul_sub_mul_rational_prec_round_val_ref_ref_ref(y, z, w, prec, rm)
9916 }
9917
9918 /// Subtracts the product of a [`Float`] and a [`Rational`] from the product of two [`Float`]s,
9919 /// rounding the result with the specified rounding mode; the [`Rational`] enters its product
9920 /// exactly and the products are not rounded before the final subtraction, so there is a single
9921 /// rounding. The [`Float`]s and the [`Rational`] are all taken by reference. An [`Ordering`] is
9922 /// also returned, indicating whether the rounded diff is less than, equal to, or greater than
9923 /// the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
9924 /// returns a `NaN` it also returns `Equal`.
9925 ///
9926 /// The precision of the output is the maximum of the precisions of the inputs. See
9927 /// [`RoundingMode`] for a description of the possible rounding modes.
9928 ///
9929 /// $$
9930 /// f(x,y,z,w,m) = xy-zw+\varepsilon.
9931 /// $$
9932 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
9933 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
9934 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
9935 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
9936 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
9937 ///
9938 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
9939 ///
9940 /// Special cases:
9941 /// - $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9942 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9943 /// $f(\text{NaN},y,z,w,m)=f(x,\text{NaN},z,w,m)=f(x,y,\text{NaN},w,m)=
9944 /// f(x,y,z,\text{NaN},m)=\text{NaN}$
9945 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
9946 /// [`Rational`] counts as an unsigned zero and a positive sign.
9947 /// - If exactly one product is infinite, the result is that product's infinity, the second
9948 /// product's sign counting as flipped.
9949 /// - If both products are infinite, the result is their common infinity if their signs differ,
9950 /// and `NaN` otherwise.
9951 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
9952 /// - $f(x,y,z,w,m)=0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is not `Floor`
9953 /// - $f(x,y,z,w,m)=-0.0$ if $xy=zw$, the products are finite and nonzero, and $m$ is `Floor`
9954 ///
9955 /// Overflow and underflow:
9956 /// - If $f(x,y,z,w,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
9957 /// returned instead.
9958 /// - 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}$
9959 /// is returned instead, where `p` is the precision of the output.
9960 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
9961 /// returned instead.
9962 /// - If $f(x,y,z,w,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
9963 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
9964 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
9965 /// - If $0<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
9966 /// instead.
9967 /// - If $0<f(x,y,z,w,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
9968 /// - If $2^{-2^{30}-1}<f(x,y,z,w,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
9969 /// returned instead.
9970 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
9971 /// instead.
9972 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
9973 /// instead.
9974 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
9975 /// - If $-2^{-2^{30}}<f(x,y,z,w,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
9976 /// returned instead.
9977 ///
9978 /// If you want to specify an output precision, consider using
9979 /// [`Float::mul_sub_mul_rational_prec_round`] instead. If you know you'll be using the
9980 /// `Nearest` rounding mode, consider using
9981 /// [`mul_sub_mul`](malachite_base::num::arithmetic::traits::MulSubMul::mul_sub_mul) instead.
9982 ///
9983 /// # Worst-case complexity
9984 /// $T(n, m) = O(n \log n \log\log n + m)$
9985 ///
9986 /// $M(n, m) = O(n \log n + m)$
9987 ///
9988 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
9989 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
9990 /// `self.significant_bits()`.
9991 ///
9992 /// # Panics
9993 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
9994 /// represent the output.
9995 ///
9996 /// # Examples
9997 /// ```
9998 /// use core::f64::consts::{E, PI, SQRT_2};
9999 /// use malachite_base::rounding_modes::RoundingMode::*;
10000 /// use malachite_float::Float;
10001 /// use malachite_q::Rational;
10002 /// use std::cmp::Ordering::*;
10003 ///
10004 /// let x = Float::from(PI);
10005 /// let y = Float::from(E);
10006 /// let z = Float::from(SQRT_2);
10007 /// let w = Rational::from_signeds(22, 7);
10008 ///
10009 /// let (diff, o) = x.mul_sub_mul_rational_round_ref_ref_ref_ref(&y, &z, &w, Floor);
10010 /// assert_eq!(diff.to_string(), "4.0950630266438379");
10011 /// assert_eq!(o, Less);
10012 ///
10013 /// let (diff, o) = x.mul_sub_mul_rational_round_ref_ref_ref_ref(&y, &z, &w, Ceiling);
10014 /// assert_eq!(diff.to_string(), "4.0950630266438388");
10015 /// assert_eq!(o, Greater);
10016 ///
10017 /// let (diff, o) = x.mul_sub_mul_rational_round_ref_ref_ref_ref(&y, &z, &w, Nearest);
10018 /// assert_eq!(diff.to_string(), "4.0950630266438388");
10019 /// assert_eq!(o, Greater);
10020 /// ```
10021 #[allow(clippy::needless_pass_by_value)]
10022 #[inline]
10023 pub fn mul_sub_mul_rational_round_ref_ref_ref_ref(
10024 &self,
10025 y: &Self,
10026 z: &Self,
10027 w: &Rational,
10028 rm: RoundingMode,
10029 ) -> (Self, Ordering) {
10030 let prec = max!(
10031 self.significant_bits(),
10032 y.significant_bits(),
10033 z.significant_bits()
10034 );
10035 self.mul_sub_mul_rational_prec_round_ref_ref_ref_ref(y, z, w, prec, rm)
10036 }
10037
10038 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
10039 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10040 /// The [`Float`]s on the right-hand side are all taken by value. An [`Ordering`] is returned,
10041 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
10042 /// Although `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN`
10043 /// it also returns `Equal`.
10044 ///
10045 /// The precision of the output is the maximum of the precisions of the inputs. See
10046 /// [`RoundingMode`] for a description of the possible rounding modes.
10047 ///
10048 /// $$
10049 /// x \gets xy-zw+\varepsilon.
10050 /// $$
10051 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10052 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10053 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10054 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10055 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10056 ///
10057 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
10058 /// overflow, and underflow.
10059 ///
10060 /// If you want to specify an output precision, consider using
10061 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10062 /// `Nearest` rounding mode, consider using
10063 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
10064 ///
10065 /// # Worst-case complexity
10066 /// $T(n, m) = O(n \log n \log\log n + m)$
10067 ///
10068 /// $M(n, m) = O(n \log n + m)$
10069 ///
10070 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10071 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10072 /// `self.significant_bits()`.
10073 ///
10074 /// # Panics
10075 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10076 /// represent the output.
10077 ///
10078 /// # Examples
10079 /// ```
10080 /// use core::f64::consts::{E, PI, SQRT_2};
10081 /// use malachite_base::rounding_modes::RoundingMode::*;
10082 /// use malachite_float::Float;
10083 /// use malachite_q::Rational;
10084 /// use std::cmp::Ordering::*;
10085 ///
10086 /// let y = Float::from(E);
10087 /// let z = Float::from(SQRT_2);
10088 /// let w = Rational::from_signeds(22, 7);
10089 ///
10090 /// let mut x = Float::from(PI);
10091 /// assert_eq!(
10092 /// x.mul_sub_mul_rational_round_assign(y.clone(), z.clone(), w.clone(), Floor),
10093 /// Less
10094 /// );
10095 /// assert_eq!(x.to_string(), "4.0950630266438379");
10096 ///
10097 /// let mut x = Float::from(PI);
10098 /// assert_eq!(
10099 /// x.mul_sub_mul_rational_round_assign(y.clone(), z.clone(), w.clone(), Ceiling),
10100 /// Greater
10101 /// );
10102 /// assert_eq!(x.to_string(), "4.0950630266438388");
10103 ///
10104 /// let mut x = Float::from(PI);
10105 /// assert_eq!(
10106 /// x.mul_sub_mul_rational_round_assign(y.clone(), z.clone(), w.clone(), Nearest),
10107 /// Greater
10108 /// );
10109 /// assert_eq!(x.to_string(), "4.0950630266438388");
10110 /// ```
10111 #[allow(clippy::needless_pass_by_value)]
10112 #[inline]
10113 pub fn mul_sub_mul_rational_round_assign(
10114 &mut self,
10115 y: Self,
10116 z: Self,
10117 w: Rational,
10118 rm: RoundingMode,
10119 ) -> Ordering {
10120 let prec = max!(
10121 self.significant_bits(),
10122 y.significant_bits(),
10123 z.significant_bits()
10124 );
10125 self.mul_sub_mul_rational_prec_round_assign(y, z, w, prec, rm)
10126 }
10127
10128 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
10129 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10130 /// The last [`Float`] on the right-hand side is taken by reference and the others by value. An
10131 /// [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
10132 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
10133 /// this function assigns a `NaN` it also returns `Equal`.
10134 ///
10135 /// The precision of the output is the maximum of the precisions of the inputs. See
10136 /// [`RoundingMode`] for a description of the possible rounding modes.
10137 ///
10138 /// $$
10139 /// x \gets xy-zw+\varepsilon.
10140 /// $$
10141 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10142 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10143 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10144 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10145 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10146 ///
10147 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
10148 /// overflow, and underflow.
10149 ///
10150 /// If you want to specify an output precision, consider using
10151 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10152 /// `Nearest` rounding mode, consider using
10153 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
10154 ///
10155 /// # Worst-case complexity
10156 /// $T(n, m) = O(n \log n \log\log n + m)$
10157 ///
10158 /// $M(n, m) = O(n \log n + m)$
10159 ///
10160 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10161 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10162 /// `self.significant_bits()`.
10163 ///
10164 /// # Panics
10165 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10166 /// represent the output.
10167 ///
10168 /// # Examples
10169 /// ```
10170 /// use core::f64::consts::{E, PI, SQRT_2};
10171 /// use malachite_base::rounding_modes::RoundingMode::*;
10172 /// use malachite_float::Float;
10173 /// use malachite_q::Rational;
10174 /// use std::cmp::Ordering::*;
10175 ///
10176 /// let y = Float::from(E);
10177 /// let z = Float::from(SQRT_2);
10178 /// let w = Rational::from_signeds(22, 7);
10179 ///
10180 /// let mut x = Float::from(PI);
10181 /// assert_eq!(
10182 /// x.mul_sub_mul_rational_round_assign_val_val_ref(y.clone(), z.clone(), &w, Floor),
10183 /// Less
10184 /// );
10185 /// assert_eq!(x.to_string(), "4.0950630266438379");
10186 ///
10187 /// let mut x = Float::from(PI);
10188 /// assert_eq!(
10189 /// x.mul_sub_mul_rational_round_assign_val_val_ref(y.clone(), z.clone(), &w, Ceiling),
10190 /// Greater
10191 /// );
10192 /// assert_eq!(x.to_string(), "4.0950630266438388");
10193 ///
10194 /// let mut x = Float::from(PI);
10195 /// assert_eq!(
10196 /// x.mul_sub_mul_rational_round_assign_val_val_ref(y.clone(), z.clone(), &w, Nearest),
10197 /// Greater
10198 /// );
10199 /// assert_eq!(x.to_string(), "4.0950630266438388");
10200 /// ```
10201 #[allow(clippy::needless_pass_by_value)]
10202 #[inline]
10203 pub fn mul_sub_mul_rational_round_assign_val_val_ref(
10204 &mut self,
10205 y: Self,
10206 z: Self,
10207 w: &Rational,
10208 rm: RoundingMode,
10209 ) -> Ordering {
10210 let prec = max!(
10211 self.significant_bits(),
10212 y.significant_bits(),
10213 z.significant_bits()
10214 );
10215 self.mul_sub_mul_rational_prec_round_assign_val_val_ref(y, z, w, prec, rm)
10216 }
10217
10218 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
10219 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10220 /// The middle [`Float`] on the right-hand side is taken by reference and the others by value.
10221 /// An [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
10222 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
10223 /// this function assigns a `NaN` it also returns `Equal`.
10224 ///
10225 /// The precision of the output is the maximum of the precisions of the inputs. See
10226 /// [`RoundingMode`] for a description of the possible rounding modes.
10227 ///
10228 /// $$
10229 /// x \gets xy-zw+\varepsilon.
10230 /// $$
10231 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10232 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10233 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10234 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10235 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10236 ///
10237 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
10238 /// overflow, and underflow.
10239 ///
10240 /// If you want to specify an output precision, consider using
10241 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10242 /// `Nearest` rounding mode, consider using
10243 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
10244 ///
10245 /// # Worst-case complexity
10246 /// $T(n, m) = O(n \log n \log\log n + m)$
10247 ///
10248 /// $M(n, m) = O(n \log n + m)$
10249 ///
10250 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10251 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10252 /// `self.significant_bits()`.
10253 ///
10254 /// # Panics
10255 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10256 /// represent the output.
10257 ///
10258 /// # Examples
10259 /// ```
10260 /// use core::f64::consts::{E, PI, SQRT_2};
10261 /// use malachite_base::rounding_modes::RoundingMode::*;
10262 /// use malachite_float::Float;
10263 /// use malachite_q::Rational;
10264 /// use std::cmp::Ordering::*;
10265 ///
10266 /// let y = Float::from(E);
10267 /// let z = Float::from(SQRT_2);
10268 /// let w = Rational::from_signeds(22, 7);
10269 ///
10270 /// let mut x = Float::from(PI);
10271 /// assert_eq!(
10272 /// x.mul_sub_mul_rational_round_assign_val_ref_val(y.clone(), &z, w.clone(), Floor),
10273 /// Less
10274 /// );
10275 /// assert_eq!(x.to_string(), "4.0950630266438379");
10276 ///
10277 /// let mut x = Float::from(PI);
10278 /// assert_eq!(
10279 /// x.mul_sub_mul_rational_round_assign_val_ref_val(y.clone(), &z, w.clone(), Ceiling),
10280 /// Greater
10281 /// );
10282 /// assert_eq!(x.to_string(), "4.0950630266438388");
10283 ///
10284 /// let mut x = Float::from(PI);
10285 /// assert_eq!(
10286 /// x.mul_sub_mul_rational_round_assign_val_ref_val(y.clone(), &z, w.clone(), Nearest),
10287 /// Greater
10288 /// );
10289 /// assert_eq!(x.to_string(), "4.0950630266438388");
10290 /// ```
10291 #[allow(clippy::needless_pass_by_value)]
10292 #[inline]
10293 pub fn mul_sub_mul_rational_round_assign_val_ref_val(
10294 &mut self,
10295 y: Self,
10296 z: &Self,
10297 w: Rational,
10298 rm: RoundingMode,
10299 ) -> Ordering {
10300 let prec = max!(
10301 self.significant_bits(),
10302 y.significant_bits(),
10303 z.significant_bits()
10304 );
10305 self.mul_sub_mul_rational_prec_round_assign_val_ref_val(y, z, w, prec, rm)
10306 }
10307
10308 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
10309 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10310 /// The first [`Float`] on the right-hand side is taken by value and the others by reference. An
10311 /// [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
10312 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
10313 /// this function assigns a `NaN` it also returns `Equal`.
10314 ///
10315 /// The precision of the output is the maximum of the precisions of the inputs. See
10316 /// [`RoundingMode`] for a description of the possible rounding modes.
10317 ///
10318 /// $$
10319 /// x \gets xy-zw+\varepsilon.
10320 /// $$
10321 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10322 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10323 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10324 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10325 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10326 ///
10327 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
10328 /// overflow, and underflow.
10329 ///
10330 /// If you want to specify an output precision, consider using
10331 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10332 /// `Nearest` rounding mode, consider using
10333 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
10334 ///
10335 /// # Worst-case complexity
10336 /// $T(n, m) = O(n \log n \log\log n + m)$
10337 ///
10338 /// $M(n, m) = O(n \log n + m)$
10339 ///
10340 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10341 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10342 /// `self.significant_bits()`.
10343 ///
10344 /// # Panics
10345 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10346 /// represent the output.
10347 ///
10348 /// # Examples
10349 /// ```
10350 /// use core::f64::consts::{E, PI, SQRT_2};
10351 /// use malachite_base::rounding_modes::RoundingMode::*;
10352 /// use malachite_float::Float;
10353 /// use malachite_q::Rational;
10354 /// use std::cmp::Ordering::*;
10355 ///
10356 /// let y = Float::from(E);
10357 /// let z = Float::from(SQRT_2);
10358 /// let w = Rational::from_signeds(22, 7);
10359 ///
10360 /// let mut x = Float::from(PI);
10361 /// assert_eq!(
10362 /// x.mul_sub_mul_rational_round_assign_val_ref_ref(y.clone(), &z, &w, Floor),
10363 /// Less
10364 /// );
10365 /// assert_eq!(x.to_string(), "4.0950630266438379");
10366 ///
10367 /// let mut x = Float::from(PI);
10368 /// assert_eq!(
10369 /// x.mul_sub_mul_rational_round_assign_val_ref_ref(y.clone(), &z, &w, Ceiling),
10370 /// Greater
10371 /// );
10372 /// assert_eq!(x.to_string(), "4.0950630266438388");
10373 ///
10374 /// let mut x = Float::from(PI);
10375 /// assert_eq!(
10376 /// x.mul_sub_mul_rational_round_assign_val_ref_ref(y.clone(), &z, &w, Nearest),
10377 /// Greater
10378 /// );
10379 /// assert_eq!(x.to_string(), "4.0950630266438388");
10380 /// ```
10381 #[allow(clippy::needless_pass_by_value)]
10382 #[inline]
10383 pub fn mul_sub_mul_rational_round_assign_val_ref_ref(
10384 &mut self,
10385 y: Self,
10386 z: &Self,
10387 w: &Rational,
10388 rm: RoundingMode,
10389 ) -> Ordering {
10390 let prec = max!(
10391 self.significant_bits(),
10392 y.significant_bits(),
10393 z.significant_bits()
10394 );
10395 self.mul_sub_mul_rational_prec_round_assign_val_ref_ref(y, z, w, prec, rm)
10396 }
10397
10398 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
10399 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10400 /// The first [`Float`] on the right-hand side is taken by reference and the others by value. An
10401 /// [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
10402 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
10403 /// this function assigns a `NaN` it also returns `Equal`.
10404 ///
10405 /// The precision of the output is the maximum of the precisions of the inputs. See
10406 /// [`RoundingMode`] for a description of the possible rounding modes.
10407 ///
10408 /// $$
10409 /// x \gets xy-zw+\varepsilon.
10410 /// $$
10411 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10412 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10413 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10414 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10415 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10416 ///
10417 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
10418 /// overflow, and underflow.
10419 ///
10420 /// If you want to specify an output precision, consider using
10421 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10422 /// `Nearest` rounding mode, consider using
10423 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
10424 ///
10425 /// # Worst-case complexity
10426 /// $T(n, m) = O(n \log n \log\log n + m)$
10427 ///
10428 /// $M(n, m) = O(n \log n + m)$
10429 ///
10430 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10431 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10432 /// `self.significant_bits()`.
10433 ///
10434 /// # Panics
10435 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10436 /// represent the output.
10437 ///
10438 /// # Examples
10439 /// ```
10440 /// use core::f64::consts::{E, PI, SQRT_2};
10441 /// use malachite_base::rounding_modes::RoundingMode::*;
10442 /// use malachite_float::Float;
10443 /// use malachite_q::Rational;
10444 /// use std::cmp::Ordering::*;
10445 ///
10446 /// let y = Float::from(E);
10447 /// let z = Float::from(SQRT_2);
10448 /// let w = Rational::from_signeds(22, 7);
10449 ///
10450 /// let mut x = Float::from(PI);
10451 /// assert_eq!(
10452 /// x.mul_sub_mul_rational_round_assign_ref_val_val(&y, z.clone(), w.clone(), Floor),
10453 /// Less
10454 /// );
10455 /// assert_eq!(x.to_string(), "4.0950630266438379");
10456 ///
10457 /// let mut x = Float::from(PI);
10458 /// assert_eq!(
10459 /// x.mul_sub_mul_rational_round_assign_ref_val_val(&y, z.clone(), w.clone(), Ceiling),
10460 /// Greater
10461 /// );
10462 /// assert_eq!(x.to_string(), "4.0950630266438388");
10463 ///
10464 /// let mut x = Float::from(PI);
10465 /// assert_eq!(
10466 /// x.mul_sub_mul_rational_round_assign_ref_val_val(&y, z.clone(), w.clone(), Nearest),
10467 /// Greater
10468 /// );
10469 /// assert_eq!(x.to_string(), "4.0950630266438388");
10470 /// ```
10471 #[allow(clippy::needless_pass_by_value)]
10472 #[inline]
10473 pub fn mul_sub_mul_rational_round_assign_ref_val_val(
10474 &mut self,
10475 y: &Self,
10476 z: Self,
10477 w: Rational,
10478 rm: RoundingMode,
10479 ) -> Ordering {
10480 let prec = max!(
10481 self.significant_bits(),
10482 y.significant_bits(),
10483 z.significant_bits()
10484 );
10485 self.mul_sub_mul_rational_prec_round_assign_ref_val_val(y, z, w, prec, rm)
10486 }
10487
10488 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
10489 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10490 /// The middle [`Float`] on the right-hand side is taken by value and the others by reference.
10491 /// An [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
10492 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
10493 /// this function assigns a `NaN` it also returns `Equal`.
10494 ///
10495 /// The precision of the output is the maximum of the precisions of the inputs. See
10496 /// [`RoundingMode`] for a description of the possible rounding modes.
10497 ///
10498 /// $$
10499 /// x \gets xy-zw+\varepsilon.
10500 /// $$
10501 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10502 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10503 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10504 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10505 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10506 ///
10507 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
10508 /// overflow, and underflow.
10509 ///
10510 /// If you want to specify an output precision, consider using
10511 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10512 /// `Nearest` rounding mode, consider using
10513 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
10514 ///
10515 /// # Worst-case complexity
10516 /// $T(n, m) = O(n \log n \log\log n + m)$
10517 ///
10518 /// $M(n, m) = O(n \log n + m)$
10519 ///
10520 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10521 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10522 /// `self.significant_bits()`.
10523 ///
10524 /// # Panics
10525 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10526 /// represent the output.
10527 ///
10528 /// # Examples
10529 /// ```
10530 /// use core::f64::consts::{E, PI, SQRT_2};
10531 /// use malachite_base::rounding_modes::RoundingMode::*;
10532 /// use malachite_float::Float;
10533 /// use malachite_q::Rational;
10534 /// use std::cmp::Ordering::*;
10535 ///
10536 /// let y = Float::from(E);
10537 /// let z = Float::from(SQRT_2);
10538 /// let w = Rational::from_signeds(22, 7);
10539 ///
10540 /// let mut x = Float::from(PI);
10541 /// assert_eq!(
10542 /// x.mul_sub_mul_rational_round_assign_ref_val_ref(&y, z.clone(), &w, Floor),
10543 /// Less
10544 /// );
10545 /// assert_eq!(x.to_string(), "4.0950630266438379");
10546 ///
10547 /// let mut x = Float::from(PI);
10548 /// assert_eq!(
10549 /// x.mul_sub_mul_rational_round_assign_ref_val_ref(&y, z.clone(), &w, Ceiling),
10550 /// Greater
10551 /// );
10552 /// assert_eq!(x.to_string(), "4.0950630266438388");
10553 ///
10554 /// let mut x = Float::from(PI);
10555 /// assert_eq!(
10556 /// x.mul_sub_mul_rational_round_assign_ref_val_ref(&y, z.clone(), &w, Nearest),
10557 /// Greater
10558 /// );
10559 /// assert_eq!(x.to_string(), "4.0950630266438388");
10560 /// ```
10561 #[allow(clippy::needless_pass_by_value)]
10562 #[inline]
10563 pub fn mul_sub_mul_rational_round_assign_ref_val_ref(
10564 &mut self,
10565 y: &Self,
10566 z: Self,
10567 w: &Rational,
10568 rm: RoundingMode,
10569 ) -> Ordering {
10570 let prec = max!(
10571 self.significant_bits(),
10572 y.significant_bits(),
10573 z.significant_bits()
10574 );
10575 self.mul_sub_mul_rational_prec_round_assign_ref_val_ref(y, z, w, prec, rm)
10576 }
10577
10578 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
10579 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10580 /// The last [`Float`] on the right-hand side is taken by value and the others by reference. An
10581 /// [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
10582 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
10583 /// this function assigns a `NaN` it also returns `Equal`.
10584 ///
10585 /// The precision of the output is the maximum of the precisions of the inputs. See
10586 /// [`RoundingMode`] for a description of the possible rounding modes.
10587 ///
10588 /// $$
10589 /// x \gets xy-zw+\varepsilon.
10590 /// $$
10591 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10592 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10593 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10594 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10595 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10596 ///
10597 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
10598 /// overflow, and underflow.
10599 ///
10600 /// If you want to specify an output precision, consider using
10601 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10602 /// `Nearest` rounding mode, consider using
10603 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
10604 ///
10605 /// # Worst-case complexity
10606 /// $T(n, m) = O(n \log n \log\log n + m)$
10607 ///
10608 /// $M(n, m) = O(n \log n + m)$
10609 ///
10610 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10611 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10612 /// `self.significant_bits()`.
10613 ///
10614 /// # Panics
10615 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10616 /// represent the output.
10617 ///
10618 /// # Examples
10619 /// ```
10620 /// use core::f64::consts::{E, PI, SQRT_2};
10621 /// use malachite_base::rounding_modes::RoundingMode::*;
10622 /// use malachite_float::Float;
10623 /// use malachite_q::Rational;
10624 /// use std::cmp::Ordering::*;
10625 ///
10626 /// let y = Float::from(E);
10627 /// let z = Float::from(SQRT_2);
10628 /// let w = Rational::from_signeds(22, 7);
10629 ///
10630 /// let mut x = Float::from(PI);
10631 /// assert_eq!(
10632 /// x.mul_sub_mul_rational_round_assign_ref_ref_val(&y, &z, w.clone(), Floor),
10633 /// Less
10634 /// );
10635 /// assert_eq!(x.to_string(), "4.0950630266438379");
10636 ///
10637 /// let mut x = Float::from(PI);
10638 /// assert_eq!(
10639 /// x.mul_sub_mul_rational_round_assign_ref_ref_val(&y, &z, w.clone(), Ceiling),
10640 /// Greater
10641 /// );
10642 /// assert_eq!(x.to_string(), "4.0950630266438388");
10643 ///
10644 /// let mut x = Float::from(PI);
10645 /// assert_eq!(
10646 /// x.mul_sub_mul_rational_round_assign_ref_ref_val(&y, &z, w.clone(), Nearest),
10647 /// Greater
10648 /// );
10649 /// assert_eq!(x.to_string(), "4.0950630266438388");
10650 /// ```
10651 #[allow(clippy::needless_pass_by_value)]
10652 #[inline]
10653 pub fn mul_sub_mul_rational_round_assign_ref_ref_val(
10654 &mut self,
10655 y: &Self,
10656 z: &Self,
10657 w: Rational,
10658 rm: RoundingMode,
10659 ) -> Ordering {
10660 let prec = max!(
10661 self.significant_bits(),
10662 y.significant_bits(),
10663 z.significant_bits()
10664 );
10665 self.mul_sub_mul_rational_prec_round_assign_ref_ref_val(y, z, w, prec, rm)
10666 }
10667
10668 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
10669 /// [`Float`]s, with a single rounding, rounding the result with the specified rounding mode.
10670 /// The [`Float`]s on the right-hand side are all taken by reference. An [`Ordering`] is
10671 /// returned, indicating whether the rounded diff is less than, equal to, or greater than the
10672 /// exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
10673 /// assigns a `NaN` it also returns `Equal`.
10674 ///
10675 /// The precision of the output is the maximum of the precisions of the inputs. See
10676 /// [`RoundingMode`] for a description of the possible rounding modes.
10677 ///
10678 /// $$
10679 /// x \gets xy-zw+\varepsilon.
10680 /// $$
10681 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10682 /// - If $xy-zw$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
10683 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
10684 /// - If $xy-zw$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
10685 /// 2^{\lfloor\log_2 |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10686 ///
10687 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
10688 /// overflow, and underflow.
10689 ///
10690 /// If you want to specify an output precision, consider using
10691 /// [`Float::mul_sub_mul_rational_prec_round_assign`] instead. If you know you'll be using the
10692 /// `Nearest` rounding mode, consider using
10693 /// [`mul_sub_mul_assign`](malachite_base::num::arithmetic::traits::MulSubMulAssign) instead.
10694 ///
10695 /// # Worst-case complexity
10696 /// $T(n, m) = O(n \log n \log\log n + m)$
10697 ///
10698 /// $M(n, m) = O(n \log n + m)$
10699 ///
10700 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10701 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10702 /// `self.significant_bits()`.
10703 ///
10704 /// # Panics
10705 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
10706 /// represent the output.
10707 ///
10708 /// # Examples
10709 /// ```
10710 /// use core::f64::consts::{E, PI, SQRT_2};
10711 /// use malachite_base::rounding_modes::RoundingMode::*;
10712 /// use malachite_float::Float;
10713 /// use malachite_q::Rational;
10714 /// use std::cmp::Ordering::*;
10715 ///
10716 /// let y = Float::from(E);
10717 /// let z = Float::from(SQRT_2);
10718 /// let w = Rational::from_signeds(22, 7);
10719 ///
10720 /// let mut x = Float::from(PI);
10721 /// assert_eq!(
10722 /// x.mul_sub_mul_rational_round_assign_ref_ref_ref(&y, &z, &w, Floor),
10723 /// Less
10724 /// );
10725 /// assert_eq!(x.to_string(), "4.0950630266438379");
10726 ///
10727 /// let mut x = Float::from(PI);
10728 /// assert_eq!(
10729 /// x.mul_sub_mul_rational_round_assign_ref_ref_ref(&y, &z, &w, Ceiling),
10730 /// Greater
10731 /// );
10732 /// assert_eq!(x.to_string(), "4.0950630266438388");
10733 ///
10734 /// let mut x = Float::from(PI);
10735 /// assert_eq!(
10736 /// x.mul_sub_mul_rational_round_assign_ref_ref_ref(&y, &z, &w, Nearest),
10737 /// Greater
10738 /// );
10739 /// assert_eq!(x.to_string(), "4.0950630266438388");
10740 /// ```
10741 #[allow(clippy::needless_pass_by_value)]
10742 #[inline]
10743 pub fn mul_sub_mul_rational_round_assign_ref_ref_ref(
10744 &mut self,
10745 y: &Self,
10746 z: &Self,
10747 w: &Rational,
10748 rm: RoundingMode,
10749 ) -> Ordering {
10750 let prec = max!(
10751 self.significant_bits(),
10752 y.significant_bits(),
10753 z.significant_bits()
10754 );
10755 self.mul_sub_mul_rational_prec_round_assign_ref_ref_ref(y, z, w, prec, rm)
10756 }
10757}
10758
10759impl MulSubMul<Self, Self, Rational> for Float {
10760 type Output = Self;
10761 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
10762 /// single rounding, taking all four by value.
10763 ///
10764 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
10765 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
10766 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
10767 /// the `Nearest` rounding mode.
10768 ///
10769 /// $$
10770 /// f(x,y,z,w) = xy-zw+\varepsilon.
10771 /// $$
10772 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10773 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
10774 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10775 ///
10776 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
10777 ///
10778 /// Special cases:
10779 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
10780 /// f(x,y,z,\text{NaN})=\text{NaN}$
10781 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
10782 /// f(x,y,z,\text{NaN})=\text{NaN}$
10783 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
10784 /// [`Rational`] counts as an unsigned zero and a positive sign.
10785 /// - If exactly one product is infinite, the result is that product's infinity, the second
10786 /// product's sign counting as flipped.
10787 /// - If both products are infinite, the result is their common infinity if their signs differ,
10788 /// and `NaN` otherwise.
10789 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
10790 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
10791 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
10792 ///
10793 /// Overflow and underflow:
10794 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
10795 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
10796 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
10797 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
10798 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
10799 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
10800 ///
10801 /// If you want to use a rounding mode other than `Nearest`, consider using
10802 /// [`Float::mul_sub_mul_rational_round`]. If you want to specify the output precision, consider
10803 /// using [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
10804 /// [`Float::mul_sub_mul_prec_round`].
10805 ///
10806 /// # Worst-case complexity
10807 /// $T(n, m) = O(n \log n \log\log n + m)$
10808 ///
10809 /// $M(n, m) = O(n \log n + m)$
10810 ///
10811 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10812 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10813 /// `self.significant_bits()`.
10814 ///
10815 /// # Examples
10816 /// ```
10817 /// use core::f64::consts::{E, PI, SQRT_2};
10818 /// use malachite_base::num::arithmetic::traits::MulSubMul;
10819 /// use malachite_float::Float;
10820 /// use malachite_q::Rational;
10821 ///
10822 /// let x = Float::from(PI);
10823 /// let y = Float::from(E);
10824 /// let z = Float::from(SQRT_2);
10825 /// let w = Rational::from_signeds(22, 7);
10826 /// assert_eq!(x.mul_sub_mul(y, z, w).to_string(), "4.0950630266438388");
10827 /// ```
10828 #[inline]
10829 fn mul_sub_mul(self, y: Self, z: Self, w: Rational) -> Self {
10830 let prec = max!(
10831 self.significant_bits(),
10832 y.significant_bits(),
10833 z.significant_bits()
10834 );
10835 self.mul_sub_mul_rational_prec(y, z, w, prec).0
10836 }
10837}
10838
10839impl MulSubMul<Self, Self, &Rational> for Float {
10840 type Output = Self;
10841 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
10842 /// single rounding, taking the first three by value and the fourth by reference.
10843 ///
10844 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
10845 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
10846 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
10847 /// the `Nearest` rounding mode.
10848 ///
10849 /// $$
10850 /// f(x,y,z,w) = xy-zw+\varepsilon.
10851 /// $$
10852 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10853 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
10854 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10855 ///
10856 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
10857 ///
10858 /// Special cases:
10859 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
10860 /// f(x,y,z,\text{NaN})=\text{NaN}$
10861 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
10862 /// f(x,y,z,\text{NaN})=\text{NaN}$
10863 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
10864 /// [`Rational`] counts as an unsigned zero and a positive sign.
10865 /// - If exactly one product is infinite, the result is that product's infinity, the second
10866 /// product's sign counting as flipped.
10867 /// - If both products are infinite, the result is their common infinity if their signs differ,
10868 /// and `NaN` otherwise.
10869 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
10870 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
10871 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
10872 ///
10873 /// Overflow and underflow:
10874 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
10875 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
10876 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
10877 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
10878 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
10879 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
10880 ///
10881 /// If you want to use a rounding mode other than `Nearest`, consider using
10882 /// [`Float::mul_sub_mul_rational_round`]. If you want to specify the output precision, consider
10883 /// using [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
10884 /// [`Float::mul_sub_mul_prec_round`].
10885 ///
10886 /// # Worst-case complexity
10887 /// $T(n, m) = O(n \log n \log\log n + m)$
10888 ///
10889 /// $M(n, m) = O(n \log n + m)$
10890 ///
10891 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10892 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10893 /// `self.significant_bits()`.
10894 ///
10895 /// # Examples
10896 /// ```
10897 /// use core::f64::consts::{E, PI, SQRT_2};
10898 /// use malachite_base::num::arithmetic::traits::MulSubMul;
10899 /// use malachite_float::Float;
10900 /// use malachite_q::Rational;
10901 ///
10902 /// let x = Float::from(PI);
10903 /// let y = Float::from(E);
10904 /// let z = Float::from(SQRT_2);
10905 /// let w = Rational::from_signeds(22, 7);
10906 /// assert_eq!(x.mul_sub_mul(y, z, &w).to_string(), "4.0950630266438388");
10907 /// ```
10908 #[inline]
10909 fn mul_sub_mul(self, y: Self, z: Self, w: &Rational) -> Self {
10910 let prec = max!(
10911 self.significant_bits(),
10912 y.significant_bits(),
10913 z.significant_bits()
10914 );
10915 self.mul_sub_mul_rational_prec_val_val_val_ref(y, z, w, prec)
10916 .0
10917 }
10918}
10919
10920impl MulSubMul<Self, &Self, Rational> for Float {
10921 type Output = Self;
10922 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
10923 /// single rounding, taking the third by reference and the others by value.
10924 ///
10925 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
10926 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
10927 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
10928 /// the `Nearest` rounding mode.
10929 ///
10930 /// $$
10931 /// f(x,y,z,w) = xy-zw+\varepsilon.
10932 /// $$
10933 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
10934 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
10935 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
10936 ///
10937 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
10938 ///
10939 /// Special cases:
10940 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
10941 /// f(x,y,z,\text{NaN})=\text{NaN}$
10942 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
10943 /// f(x,y,z,\text{NaN})=\text{NaN}$
10944 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
10945 /// [`Rational`] counts as an unsigned zero and a positive sign.
10946 /// - If exactly one product is infinite, the result is that product's infinity, the second
10947 /// product's sign counting as flipped.
10948 /// - If both products are infinite, the result is their common infinity if their signs differ,
10949 /// and `NaN` otherwise.
10950 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
10951 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
10952 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
10953 ///
10954 /// Overflow and underflow:
10955 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
10956 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
10957 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
10958 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
10959 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
10960 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
10961 ///
10962 /// If you want to use a rounding mode other than `Nearest`, consider using
10963 /// [`Float::mul_sub_mul_rational_round`]. If you want to specify the output precision, consider
10964 /// using [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
10965 /// [`Float::mul_sub_mul_prec_round`].
10966 ///
10967 /// # Worst-case complexity
10968 /// $T(n, m) = O(n \log n \log\log n + m)$
10969 ///
10970 /// $M(n, m) = O(n \log n + m)$
10971 ///
10972 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
10973 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
10974 /// `self.significant_bits()`.
10975 ///
10976 /// # Examples
10977 /// ```
10978 /// use core::f64::consts::{E, PI, SQRT_2};
10979 /// use malachite_base::num::arithmetic::traits::MulSubMul;
10980 /// use malachite_float::Float;
10981 /// use malachite_q::Rational;
10982 ///
10983 /// let x = Float::from(PI);
10984 /// let y = Float::from(E);
10985 /// let z = Float::from(SQRT_2);
10986 /// let w = Rational::from_signeds(22, 7);
10987 /// assert_eq!(x.mul_sub_mul(y, &z, w).to_string(), "4.0950630266438388");
10988 /// ```
10989 #[inline]
10990 fn mul_sub_mul(self, y: Self, z: &Self, w: Rational) -> Self {
10991 let prec = max!(
10992 self.significant_bits(),
10993 y.significant_bits(),
10994 z.significant_bits()
10995 );
10996 self.mul_sub_mul_rational_prec_val_val_ref_val(y, z, w, prec)
10997 .0
10998 }
10999}
11000
11001impl MulSubMul<Self, &Self, &Rational> for Float {
11002 type Output = Self;
11003 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
11004 /// single rounding, taking the first two by value and the last two by reference.
11005 ///
11006 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11007 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11008 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11009 /// the `Nearest` rounding mode.
11010 ///
11011 /// $$
11012 /// f(x,y,z,w) = xy-zw+\varepsilon.
11013 /// $$
11014 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11015 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11016 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11017 ///
11018 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11019 ///
11020 /// Special cases:
11021 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11022 /// f(x,y,z,\text{NaN})=\text{NaN}$
11023 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11024 /// f(x,y,z,\text{NaN})=\text{NaN}$
11025 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
11026 /// [`Rational`] counts as an unsigned zero and a positive sign.
11027 /// - If exactly one product is infinite, the result is that product's infinity, the second
11028 /// product's sign counting as flipped.
11029 /// - If both products are infinite, the result is their common infinity if their signs differ,
11030 /// and `NaN` otherwise.
11031 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
11032 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
11033 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
11034 ///
11035 /// Overflow and underflow:
11036 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
11037 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
11038 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
11039 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
11040 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
11041 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
11042 ///
11043 /// If you want to use a rounding mode other than `Nearest`, consider using
11044 /// [`Float::mul_sub_mul_rational_round`]. If you want to specify the output precision, consider
11045 /// using [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
11046 /// [`Float::mul_sub_mul_prec_round`].
11047 ///
11048 /// # Worst-case complexity
11049 /// $T(n, m) = O(n \log n \log\log n + m)$
11050 ///
11051 /// $M(n, m) = O(n \log n + m)$
11052 ///
11053 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11054 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11055 /// `self.significant_bits()`.
11056 ///
11057 /// # Examples
11058 /// ```
11059 /// use core::f64::consts::{E, PI, SQRT_2};
11060 /// use malachite_base::num::arithmetic::traits::MulSubMul;
11061 /// use malachite_float::Float;
11062 /// use malachite_q::Rational;
11063 ///
11064 /// let x = Float::from(PI);
11065 /// let y = Float::from(E);
11066 /// let z = Float::from(SQRT_2);
11067 /// let w = Rational::from_signeds(22, 7);
11068 /// assert_eq!(x.mul_sub_mul(y, &z, &w).to_string(), "4.0950630266438388");
11069 /// ```
11070 #[inline]
11071 fn mul_sub_mul(self, y: Self, z: &Self, w: &Rational) -> Self {
11072 let prec = max!(
11073 self.significant_bits(),
11074 y.significant_bits(),
11075 z.significant_bits()
11076 );
11077 self.mul_sub_mul_rational_prec_val_val_ref_ref(y, z, w, prec)
11078 .0
11079 }
11080}
11081
11082impl MulSubMul<&Self, Self, Rational> for Float {
11083 type Output = Self;
11084 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
11085 /// single rounding, taking the second by reference and the others by value.
11086 ///
11087 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11088 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11089 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11090 /// the `Nearest` rounding mode.
11091 ///
11092 /// $$
11093 /// f(x,y,z,w) = xy-zw+\varepsilon.
11094 /// $$
11095 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11096 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11097 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11098 ///
11099 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11100 ///
11101 /// Special cases:
11102 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11103 /// f(x,y,z,\text{NaN})=\text{NaN}$
11104 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11105 /// f(x,y,z,\text{NaN})=\text{NaN}$
11106 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
11107 /// [`Rational`] counts as an unsigned zero and a positive sign.
11108 /// - If exactly one product is infinite, the result is that product's infinity, the second
11109 /// product's sign counting as flipped.
11110 /// - If both products are infinite, the result is their common infinity if their signs differ,
11111 /// and `NaN` otherwise.
11112 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
11113 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
11114 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
11115 ///
11116 /// Overflow and underflow:
11117 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
11118 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
11119 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
11120 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
11121 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
11122 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
11123 ///
11124 /// If you want to use a rounding mode other than `Nearest`, consider using
11125 /// [`Float::mul_sub_mul_rational_round`]. If you want to specify the output precision, consider
11126 /// using [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
11127 /// [`Float::mul_sub_mul_prec_round`].
11128 ///
11129 /// # Worst-case complexity
11130 /// $T(n, m) = O(n \log n \log\log n + m)$
11131 ///
11132 /// $M(n, m) = O(n \log n + m)$
11133 ///
11134 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11135 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11136 /// `self.significant_bits()`.
11137 ///
11138 /// # Examples
11139 /// ```
11140 /// use core::f64::consts::{E, PI, SQRT_2};
11141 /// use malachite_base::num::arithmetic::traits::MulSubMul;
11142 /// use malachite_float::Float;
11143 /// use malachite_q::Rational;
11144 ///
11145 /// let x = Float::from(PI);
11146 /// let y = Float::from(E);
11147 /// let z = Float::from(SQRT_2);
11148 /// let w = Rational::from_signeds(22, 7);
11149 /// assert_eq!(x.mul_sub_mul(&y, z, w).to_string(), "4.0950630266438388");
11150 /// ```
11151 #[inline]
11152 fn mul_sub_mul(self, y: &Self, z: Self, w: Rational) -> Self {
11153 let prec = max!(
11154 self.significant_bits(),
11155 y.significant_bits(),
11156 z.significant_bits()
11157 );
11158 self.mul_sub_mul_rational_prec_val_ref_val_val(y, z, w, prec)
11159 .0
11160 }
11161}
11162
11163impl MulSubMul<&Self, Self, &Rational> for Float {
11164 type Output = Self;
11165 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
11166 /// single rounding, taking the second and fourth by reference and the others by value.
11167 ///
11168 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11169 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11170 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11171 /// the `Nearest` rounding mode.
11172 ///
11173 /// $$
11174 /// f(x,y,z,w) = xy-zw+\varepsilon.
11175 /// $$
11176 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11177 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11178 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11179 ///
11180 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11181 ///
11182 /// Special cases:
11183 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11184 /// f(x,y,z,\text{NaN})=\text{NaN}$
11185 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11186 /// f(x,y,z,\text{NaN})=\text{NaN}$
11187 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
11188 /// [`Rational`] counts as an unsigned zero and a positive sign.
11189 /// - If exactly one product is infinite, the result is that product's infinity, the second
11190 /// product's sign counting as flipped.
11191 /// - If both products are infinite, the result is their common infinity if their signs differ,
11192 /// and `NaN` otherwise.
11193 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
11194 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
11195 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
11196 ///
11197 /// Overflow and underflow:
11198 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
11199 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
11200 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
11201 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
11202 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
11203 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
11204 ///
11205 /// If you want to use a rounding mode other than `Nearest`, consider using
11206 /// [`Float::mul_sub_mul_rational_round`]. If you want to specify the output precision, consider
11207 /// using [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
11208 /// [`Float::mul_sub_mul_prec_round`].
11209 ///
11210 /// # Worst-case complexity
11211 /// $T(n, m) = O(n \log n \log\log n + m)$
11212 ///
11213 /// $M(n, m) = O(n \log n + m)$
11214 ///
11215 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11216 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11217 /// `self.significant_bits()`.
11218 ///
11219 /// # Examples
11220 /// ```
11221 /// use core::f64::consts::{E, PI, SQRT_2};
11222 /// use malachite_base::num::arithmetic::traits::MulSubMul;
11223 /// use malachite_float::Float;
11224 /// use malachite_q::Rational;
11225 ///
11226 /// let x = Float::from(PI);
11227 /// let y = Float::from(E);
11228 /// let z = Float::from(SQRT_2);
11229 /// let w = Rational::from_signeds(22, 7);
11230 /// assert_eq!(x.mul_sub_mul(&y, z, &w).to_string(), "4.0950630266438388");
11231 /// ```
11232 #[inline]
11233 fn mul_sub_mul(self, y: &Self, z: Self, w: &Rational) -> Self {
11234 let prec = max!(
11235 self.significant_bits(),
11236 y.significant_bits(),
11237 z.significant_bits()
11238 );
11239 self.mul_sub_mul_rational_prec_val_ref_val_ref(y, z, w, prec)
11240 .0
11241 }
11242}
11243
11244impl MulSubMul<&Self, &Self, Rational> for Float {
11245 type Output = Self;
11246 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
11247 /// single rounding, taking the second and third by reference and the others by value.
11248 ///
11249 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11250 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11251 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11252 /// the `Nearest` rounding mode.
11253 ///
11254 /// $$
11255 /// f(x,y,z,w) = xy-zw+\varepsilon.
11256 /// $$
11257 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11258 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11259 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11260 ///
11261 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11262 ///
11263 /// Special cases:
11264 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11265 /// f(x,y,z,\text{NaN})=\text{NaN}$
11266 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11267 /// f(x,y,z,\text{NaN})=\text{NaN}$
11268 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
11269 /// [`Rational`] counts as an unsigned zero and a positive sign.
11270 /// - If exactly one product is infinite, the result is that product's infinity, the second
11271 /// product's sign counting as flipped.
11272 /// - If both products are infinite, the result is their common infinity if their signs differ,
11273 /// and `NaN` otherwise.
11274 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
11275 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
11276 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
11277 ///
11278 /// Overflow and underflow:
11279 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
11280 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
11281 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
11282 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
11283 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
11284 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
11285 ///
11286 /// If you want to use a rounding mode other than `Nearest`, consider using
11287 /// [`Float::mul_sub_mul_rational_round`]. If you want to specify the output precision, consider
11288 /// using [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
11289 /// [`Float::mul_sub_mul_prec_round`].
11290 ///
11291 /// # Worst-case complexity
11292 /// $T(n, m) = O(n \log n \log\log n + m)$
11293 ///
11294 /// $M(n, m) = O(n \log n + m)$
11295 ///
11296 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11297 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11298 /// `self.significant_bits()`.
11299 ///
11300 /// # Examples
11301 /// ```
11302 /// use core::f64::consts::{E, PI, SQRT_2};
11303 /// use malachite_base::num::arithmetic::traits::MulSubMul;
11304 /// use malachite_float::Float;
11305 /// use malachite_q::Rational;
11306 ///
11307 /// let x = Float::from(PI);
11308 /// let y = Float::from(E);
11309 /// let z = Float::from(SQRT_2);
11310 /// let w = Rational::from_signeds(22, 7);
11311 /// assert_eq!(x.mul_sub_mul(&y, &z, w).to_string(), "4.0950630266438388");
11312 /// ```
11313 #[inline]
11314 fn mul_sub_mul(self, y: &Self, z: &Self, w: Rational) -> Self {
11315 let prec = max!(
11316 self.significant_bits(),
11317 y.significant_bits(),
11318 z.significant_bits()
11319 );
11320 self.mul_sub_mul_rational_prec_val_ref_ref_val(y, z, w, prec)
11321 .0
11322 }
11323}
11324
11325impl MulSubMul<&Self, &Self, &Rational> for Float {
11326 type Output = Self;
11327 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
11328 /// single rounding, taking the first by value and the others by reference.
11329 ///
11330 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11331 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11332 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11333 /// the `Nearest` rounding mode.
11334 ///
11335 /// $$
11336 /// f(x,y,z,w) = xy-zw+\varepsilon.
11337 /// $$
11338 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11339 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11340 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11341 ///
11342 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11343 ///
11344 /// Special cases:
11345 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11346 /// f(x,y,z,\text{NaN})=\text{NaN}$
11347 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11348 /// f(x,y,z,\text{NaN})=\text{NaN}$
11349 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
11350 /// [`Rational`] counts as an unsigned zero and a positive sign.
11351 /// - If exactly one product is infinite, the result is that product's infinity, the second
11352 /// product's sign counting as flipped.
11353 /// - If both products are infinite, the result is their common infinity if their signs differ,
11354 /// and `NaN` otherwise.
11355 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
11356 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
11357 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
11358 ///
11359 /// Overflow and underflow:
11360 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
11361 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
11362 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
11363 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
11364 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
11365 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
11366 ///
11367 /// If you want to use a rounding mode other than `Nearest`, consider using
11368 /// [`Float::mul_sub_mul_rational_round`]. If you want to specify the output precision, consider
11369 /// using [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
11370 /// [`Float::mul_sub_mul_prec_round`].
11371 ///
11372 /// # Worst-case complexity
11373 /// $T(n, m) = O(n \log n \log\log n + m)$
11374 ///
11375 /// $M(n, m) = O(n \log n + m)$
11376 ///
11377 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11378 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11379 /// `self.significant_bits()`.
11380 ///
11381 /// # Examples
11382 /// ```
11383 /// use core::f64::consts::{E, PI, SQRT_2};
11384 /// use malachite_base::num::arithmetic::traits::MulSubMul;
11385 /// use malachite_float::Float;
11386 /// use malachite_q::Rational;
11387 ///
11388 /// let x = Float::from(PI);
11389 /// let y = Float::from(E);
11390 /// let z = Float::from(SQRT_2);
11391 /// let w = Rational::from_signeds(22, 7);
11392 /// assert_eq!(x.mul_sub_mul(&y, &z, &w).to_string(), "4.0950630266438388");
11393 /// ```
11394 #[inline]
11395 fn mul_sub_mul(self, y: &Self, z: &Self, w: &Rational) -> Self {
11396 let prec = max!(
11397 self.significant_bits(),
11398 y.significant_bits(),
11399 z.significant_bits()
11400 );
11401 self.mul_sub_mul_rational_prec_val_ref_ref_ref(y, z, w, prec)
11402 .0
11403 }
11404}
11405
11406impl MulSubMul<&Float, &Float, &Rational> for &Float {
11407 type Output = Float;
11408 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
11409 /// single rounding, taking all four by reference.
11410 ///
11411 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11412 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11413 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11414 /// the `Nearest` rounding mode.
11415 ///
11416 /// $$
11417 /// f(x,y,z,w) = xy-zw+\varepsilon.
11418 /// $$
11419 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11420 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11421 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11422 ///
11423 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11424 ///
11425 /// Special cases:
11426 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11427 /// f(x,y,z,\text{NaN})=\text{NaN}$
11428 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11429 /// f(x,y,z,\text{NaN})=\text{NaN}$
11430 /// - If either product multiplies an infinity by a zero, the result is `NaN`; a zero
11431 /// [`Rational`] counts as an unsigned zero and a positive sign.
11432 /// - If exactly one product is infinite, the result is that product's infinity, the second
11433 /// product's sign counting as flipped.
11434 /// - If both products are infinite, the result is their common infinity if their signs differ,
11435 /// and `NaN` otherwise.
11436 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
11437 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
11438 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
11439 ///
11440 /// Overflow and underflow:
11441 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
11442 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
11443 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
11444 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
11445 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
11446 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
11447 ///
11448 /// If you want to use a rounding mode other than `Nearest`, consider using
11449 /// [`Float::mul_sub_mul_rational_round`]. If you want to specify the output precision, consider
11450 /// using [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
11451 /// [`Float::mul_sub_mul_prec_round`].
11452 ///
11453 /// # Worst-case complexity
11454 /// $T(n, m) = O(n \log n \log\log n + m)$
11455 ///
11456 /// $M(n, m) = O(n \log n + m)$
11457 ///
11458 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11459 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11460 /// `self.significant_bits()`.
11461 ///
11462 /// # Examples
11463 /// ```
11464 /// use core::f64::consts::{E, PI, SQRT_2};
11465 /// use malachite_base::num::arithmetic::traits::MulSubMul;
11466 /// use malachite_float::Float;
11467 /// use malachite_q::Rational;
11468 ///
11469 /// let x = Float::from(PI);
11470 /// let y = Float::from(E);
11471 /// let z = Float::from(SQRT_2);
11472 /// let w = Rational::from_signeds(22, 7);
11473 /// assert_eq!(&x.mul_sub_mul(&y, &z, &w).to_string(), "4.0950630266438388");
11474 /// ```
11475 #[inline]
11476 fn mul_sub_mul(self, y: &Float, z: &Float, w: &Rational) -> Float {
11477 let prec = max!(
11478 self.significant_bits(),
11479 y.significant_bits(),
11480 z.significant_bits()
11481 );
11482 self.mul_sub_mul_rational_prec_ref_ref_ref_ref(y, z, w, prec)
11483 .0
11484 }
11485}
11486
11487impl MulSubMulAssign<Self, Self, Rational> for Float {
11488 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
11489 /// [`Float`]s, with a single rounding. The [`Float`]s on the right-hand side are all taken by
11490 /// value.
11491 ///
11492 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11493 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11494 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11495 /// the `Nearest` rounding mode.
11496 ///
11497 /// $$
11498 /// x \gets xy-zw+\varepsilon.
11499 /// $$
11500 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11501 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11502 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11503 ///
11504 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
11505 /// overflow, and underflow.
11506 ///
11507 /// If you want to use a rounding mode other than `Nearest`, consider using
11508 /// [`Float::mul_sub_mul_rational_round_assign`]. If you want to specify the output precision,
11509 /// consider using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things,
11510 /// consider using [`Float::mul_sub_mul_prec_round_assign`].
11511 ///
11512 /// # Worst-case complexity
11513 /// $T(n, m) = O(n \log n \log\log n + m)$
11514 ///
11515 /// $M(n, m) = O(n \log n + m)$
11516 ///
11517 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11518 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11519 /// `self.significant_bits()`.
11520 ///
11521 /// # Examples
11522 /// ```
11523 /// use core::f64::consts::{E, PI, SQRT_2};
11524 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
11525 /// use malachite_float::Float;
11526 /// use malachite_q::Rational;
11527 ///
11528 /// let mut x = Float::from(PI);
11529 /// let y = Float::from(E);
11530 /// let z = Float::from(SQRT_2);
11531 /// let w = Rational::from_signeds(22, 7);
11532 /// x.mul_sub_mul_assign(y, z, w);
11533 /// assert_eq!(x.to_string(), "4.0950630266438388");
11534 /// ```
11535 #[inline]
11536 fn mul_sub_mul_assign(&mut self, y: Self, z: Self, w: Rational) {
11537 let prec = max!(
11538 self.significant_bits(),
11539 y.significant_bits(),
11540 z.significant_bits()
11541 );
11542 self.mul_sub_mul_rational_prec_assign(y, z, w, prec);
11543 }
11544}
11545
11546impl MulSubMulAssign<Self, Self, &Rational> for Float {
11547 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
11548 /// [`Float`]s, with a single rounding. The last [`Float`] on the right-hand side is taken by
11549 /// reference and the others by value.
11550 ///
11551 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11552 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11553 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11554 /// the `Nearest` rounding mode.
11555 ///
11556 /// $$
11557 /// x \gets xy-zw+\varepsilon.
11558 /// $$
11559 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11560 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11561 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11562 ///
11563 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
11564 /// overflow, and underflow.
11565 ///
11566 /// If you want to use a rounding mode other than `Nearest`, consider using
11567 /// [`Float::mul_sub_mul_rational_round_assign`]. If you want to specify the output precision,
11568 /// consider using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things,
11569 /// consider using [`Float::mul_sub_mul_prec_round_assign`].
11570 ///
11571 /// # Worst-case complexity
11572 /// $T(n, m) = O(n \log n \log\log n + m)$
11573 ///
11574 /// $M(n, m) = O(n \log n + m)$
11575 ///
11576 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11577 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11578 /// `self.significant_bits()`.
11579 ///
11580 /// # Examples
11581 /// ```
11582 /// use core::f64::consts::{E, PI, SQRT_2};
11583 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
11584 /// use malachite_float::Float;
11585 /// use malachite_q::Rational;
11586 ///
11587 /// let mut x = Float::from(PI);
11588 /// let y = Float::from(E);
11589 /// let z = Float::from(SQRT_2);
11590 /// let w = Rational::from_signeds(22, 7);
11591 /// x.mul_sub_mul_assign(y, z, &w);
11592 /// assert_eq!(x.to_string(), "4.0950630266438388");
11593 /// ```
11594 #[inline]
11595 fn mul_sub_mul_assign(&mut self, y: Self, z: Self, w: &Rational) {
11596 let prec = max!(
11597 self.significant_bits(),
11598 y.significant_bits(),
11599 z.significant_bits()
11600 );
11601 self.mul_sub_mul_rational_prec_assign_val_val_ref(y, z, w, prec);
11602 }
11603}
11604
11605impl MulSubMulAssign<Self, &Self, Rational> for Float {
11606 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
11607 /// [`Float`]s, with a single rounding. The middle [`Float`] on the right-hand side is taken by
11608 /// reference and the others by value.
11609 ///
11610 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11611 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11612 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11613 /// the `Nearest` rounding mode.
11614 ///
11615 /// $$
11616 /// x \gets xy-zw+\varepsilon.
11617 /// $$
11618 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11619 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11620 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11621 ///
11622 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
11623 /// overflow, and underflow.
11624 ///
11625 /// If you want to use a rounding mode other than `Nearest`, consider using
11626 /// [`Float::mul_sub_mul_rational_round_assign`]. If you want to specify the output precision,
11627 /// consider using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things,
11628 /// consider using [`Float::mul_sub_mul_prec_round_assign`].
11629 ///
11630 /// # Worst-case complexity
11631 /// $T(n, m) = O(n \log n \log\log n + m)$
11632 ///
11633 /// $M(n, m) = O(n \log n + m)$
11634 ///
11635 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11636 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11637 /// `self.significant_bits()`.
11638 ///
11639 /// # Examples
11640 /// ```
11641 /// use core::f64::consts::{E, PI, SQRT_2};
11642 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
11643 /// use malachite_float::Float;
11644 /// use malachite_q::Rational;
11645 ///
11646 /// let mut x = Float::from(PI);
11647 /// let y = Float::from(E);
11648 /// let z = Float::from(SQRT_2);
11649 /// let w = Rational::from_signeds(22, 7);
11650 /// x.mul_sub_mul_assign(y, &z, w);
11651 /// assert_eq!(x.to_string(), "4.0950630266438388");
11652 /// ```
11653 #[inline]
11654 fn mul_sub_mul_assign(&mut self, y: Self, z: &Self, w: Rational) {
11655 let prec = max!(
11656 self.significant_bits(),
11657 y.significant_bits(),
11658 z.significant_bits()
11659 );
11660 self.mul_sub_mul_rational_prec_assign_val_ref_val(y, z, w, prec);
11661 }
11662}
11663
11664impl MulSubMulAssign<Self, &Self, &Rational> for Float {
11665 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
11666 /// [`Float`]s, with a single rounding. The first [`Float`] on the right-hand side is taken by
11667 /// value and the others by reference.
11668 ///
11669 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11670 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11671 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11672 /// the `Nearest` rounding mode.
11673 ///
11674 /// $$
11675 /// x \gets xy-zw+\varepsilon.
11676 /// $$
11677 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11678 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11679 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11680 ///
11681 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
11682 /// overflow, and underflow.
11683 ///
11684 /// If you want to use a rounding mode other than `Nearest`, consider using
11685 /// [`Float::mul_sub_mul_rational_round_assign`]. If you want to specify the output precision,
11686 /// consider using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things,
11687 /// consider using [`Float::mul_sub_mul_prec_round_assign`].
11688 ///
11689 /// # Worst-case complexity
11690 /// $T(n, m) = O(n \log n \log\log n + m)$
11691 ///
11692 /// $M(n, m) = O(n \log n + m)$
11693 ///
11694 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11695 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11696 /// `self.significant_bits()`.
11697 ///
11698 /// # Examples
11699 /// ```
11700 /// use core::f64::consts::{E, PI, SQRT_2};
11701 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
11702 /// use malachite_float::Float;
11703 /// use malachite_q::Rational;
11704 ///
11705 /// let mut x = Float::from(PI);
11706 /// let y = Float::from(E);
11707 /// let z = Float::from(SQRT_2);
11708 /// let w = Rational::from_signeds(22, 7);
11709 /// x.mul_sub_mul_assign(y, &z, &w);
11710 /// assert_eq!(x.to_string(), "4.0950630266438388");
11711 /// ```
11712 #[inline]
11713 fn mul_sub_mul_assign(&mut self, y: Self, z: &Self, w: &Rational) {
11714 let prec = max!(
11715 self.significant_bits(),
11716 y.significant_bits(),
11717 z.significant_bits()
11718 );
11719 self.mul_sub_mul_rational_prec_assign_val_ref_ref(y, z, w, prec);
11720 }
11721}
11722
11723impl MulSubMulAssign<&Self, Self, Rational> for Float {
11724 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
11725 /// [`Float`]s, with a single rounding. The first [`Float`] on the right-hand side is taken by
11726 /// reference and the others by value.
11727 ///
11728 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11729 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11730 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11731 /// the `Nearest` rounding mode.
11732 ///
11733 /// $$
11734 /// x \gets xy-zw+\varepsilon.
11735 /// $$
11736 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11737 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11738 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11739 ///
11740 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
11741 /// overflow, and underflow.
11742 ///
11743 /// If you want to use a rounding mode other than `Nearest`, consider using
11744 /// [`Float::mul_sub_mul_rational_round_assign`]. If you want to specify the output precision,
11745 /// consider using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things,
11746 /// consider using [`Float::mul_sub_mul_prec_round_assign`].
11747 ///
11748 /// # Worst-case complexity
11749 /// $T(n, m) = O(n \log n \log\log n + m)$
11750 ///
11751 /// $M(n, m) = O(n \log n + m)$
11752 ///
11753 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11754 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11755 /// `self.significant_bits()`.
11756 ///
11757 /// # Examples
11758 /// ```
11759 /// use core::f64::consts::{E, PI, SQRT_2};
11760 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
11761 /// use malachite_float::Float;
11762 /// use malachite_q::Rational;
11763 ///
11764 /// let mut x = Float::from(PI);
11765 /// let y = Float::from(E);
11766 /// let z = Float::from(SQRT_2);
11767 /// let w = Rational::from_signeds(22, 7);
11768 /// x.mul_sub_mul_assign(&y, z, w);
11769 /// assert_eq!(x.to_string(), "4.0950630266438388");
11770 /// ```
11771 #[inline]
11772 fn mul_sub_mul_assign(&mut self, y: &Self, z: Self, w: Rational) {
11773 let prec = max!(
11774 self.significant_bits(),
11775 y.significant_bits(),
11776 z.significant_bits()
11777 );
11778 self.mul_sub_mul_rational_prec_assign_ref_val_val(y, z, w, prec);
11779 }
11780}
11781
11782impl MulSubMulAssign<&Self, Self, &Rational> for Float {
11783 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
11784 /// [`Float`]s, with a single rounding. The middle [`Float`] on the right-hand side is taken by
11785 /// value and the others by reference.
11786 ///
11787 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11788 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11789 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11790 /// the `Nearest` rounding mode.
11791 ///
11792 /// $$
11793 /// x \gets xy-zw+\varepsilon.
11794 /// $$
11795 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11796 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11797 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11798 ///
11799 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
11800 /// overflow, and underflow.
11801 ///
11802 /// If you want to use a rounding mode other than `Nearest`, consider using
11803 /// [`Float::mul_sub_mul_rational_round_assign`]. If you want to specify the output precision,
11804 /// consider using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things,
11805 /// consider using [`Float::mul_sub_mul_prec_round_assign`].
11806 ///
11807 /// # Worst-case complexity
11808 /// $T(n, m) = O(n \log n \log\log n + m)$
11809 ///
11810 /// $M(n, m) = O(n \log n + m)$
11811 ///
11812 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11813 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11814 /// `self.significant_bits()`.
11815 ///
11816 /// # Examples
11817 /// ```
11818 /// use core::f64::consts::{E, PI, SQRT_2};
11819 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
11820 /// use malachite_float::Float;
11821 /// use malachite_q::Rational;
11822 ///
11823 /// let mut x = Float::from(PI);
11824 /// let y = Float::from(E);
11825 /// let z = Float::from(SQRT_2);
11826 /// let w = Rational::from_signeds(22, 7);
11827 /// x.mul_sub_mul_assign(&y, z, &w);
11828 /// assert_eq!(x.to_string(), "4.0950630266438388");
11829 /// ```
11830 #[inline]
11831 fn mul_sub_mul_assign(&mut self, y: &Self, z: Self, w: &Rational) {
11832 let prec = max!(
11833 self.significant_bits(),
11834 y.significant_bits(),
11835 z.significant_bits()
11836 );
11837 self.mul_sub_mul_rational_prec_assign_ref_val_ref(y, z, w, prec);
11838 }
11839}
11840
11841impl MulSubMulAssign<&Self, &Self, Rational> for Float {
11842 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
11843 /// [`Float`]s, with a single rounding. The last [`Float`] on the right-hand side is taken by
11844 /// value and the others by reference.
11845 ///
11846 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11847 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11848 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11849 /// the `Nearest` rounding mode.
11850 ///
11851 /// $$
11852 /// x \gets xy-zw+\varepsilon.
11853 /// $$
11854 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11855 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11856 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11857 ///
11858 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
11859 /// overflow, and underflow.
11860 ///
11861 /// If you want to use a rounding mode other than `Nearest`, consider using
11862 /// [`Float::mul_sub_mul_rational_round_assign`]. If you want to specify the output precision,
11863 /// consider using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things,
11864 /// consider using [`Float::mul_sub_mul_prec_round_assign`].
11865 ///
11866 /// # Worst-case complexity
11867 /// $T(n, m) = O(n \log n \log\log n + m)$
11868 ///
11869 /// $M(n, m) = O(n \log n + m)$
11870 ///
11871 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11872 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11873 /// `self.significant_bits()`.
11874 ///
11875 /// # Examples
11876 /// ```
11877 /// use core::f64::consts::{E, PI, SQRT_2};
11878 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
11879 /// use malachite_float::Float;
11880 /// use malachite_q::Rational;
11881 ///
11882 /// let mut x = Float::from(PI);
11883 /// let y = Float::from(E);
11884 /// let z = Float::from(SQRT_2);
11885 /// let w = Rational::from_signeds(22, 7);
11886 /// x.mul_sub_mul_assign(&y, &z, w);
11887 /// assert_eq!(x.to_string(), "4.0950630266438388");
11888 /// ```
11889 #[inline]
11890 fn mul_sub_mul_assign(&mut self, y: &Self, z: &Self, w: Rational) {
11891 let prec = max!(
11892 self.significant_bits(),
11893 y.significant_bits(),
11894 z.significant_bits()
11895 );
11896 self.mul_sub_mul_rational_prec_assign_ref_ref_val(y, z, w, prec);
11897 }
11898}
11899
11900impl MulSubMulAssign<&Self, &Self, &Rational> for Float {
11901 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
11902 /// [`Float`]s, with a single rounding. The [`Float`]s on the right-hand side are all taken by
11903 /// reference.
11904 ///
11905 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
11906 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
11907 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
11908 /// the `Nearest` rounding mode.
11909 ///
11910 /// $$
11911 /// x \gets xy-zw+\varepsilon.
11912 /// $$
11913 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11914 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11915 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11916 ///
11917 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
11918 /// overflow, and underflow.
11919 ///
11920 /// If you want to use a rounding mode other than `Nearest`, consider using
11921 /// [`Float::mul_sub_mul_rational_round_assign`]. If you want to specify the output precision,
11922 /// consider using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things,
11923 /// consider using [`Float::mul_sub_mul_prec_round_assign`].
11924 ///
11925 /// # Worst-case complexity
11926 /// $T(n, m) = O(n \log n \log\log n + m)$
11927 ///
11928 /// $M(n, m) = O(n \log n + m)$
11929 ///
11930 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
11931 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
11932 /// `self.significant_bits()`.
11933 ///
11934 /// # Examples
11935 /// ```
11936 /// use core::f64::consts::{E, PI, SQRT_2};
11937 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
11938 /// use malachite_float::Float;
11939 /// use malachite_q::Rational;
11940 ///
11941 /// let mut x = Float::from(PI);
11942 /// let y = Float::from(E);
11943 /// let z = Float::from(SQRT_2);
11944 /// let w = Rational::from_signeds(22, 7);
11945 /// x.mul_sub_mul_assign(&y, &z, &w);
11946 /// assert_eq!(x.to_string(), "4.0950630266438388");
11947 /// ```
11948 #[inline]
11949 fn mul_sub_mul_assign(&mut self, y: &Self, z: &Self, w: &Rational) {
11950 let prec = max!(
11951 self.significant_bits(),
11952 y.significant_bits(),
11953 z.significant_bits()
11954 );
11955 self.mul_sub_mul_rational_prec_assign_ref_ref_ref(y, z, w, prec);
11956 }
11957}
11958
11959impl MulSubMul<Self, Self, Self> for Float {
11960 type Output = Self;
11961 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
11962 /// single rounding, taking all four by value.
11963 ///
11964 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
11965 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
11966 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
11967 /// `Nearest` rounding mode.
11968 ///
11969 /// $$
11970 /// f(x,y,z,w) = xy-zw+\varepsilon.
11971 /// $$
11972 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
11973 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
11974 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
11975 ///
11976 /// If the output has a precision, it is the maximum of the precisions of the inputs.
11977 ///
11978 /// Special cases:
11979 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11980 /// f(x,y,z,\text{NaN})=\text{NaN}$
11981 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11982 /// f(x,y,z,\text{NaN})=\text{NaN}$
11983 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
11984 /// f(x,y,z,\text{NaN})=\text{NaN}$
11985 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
11986 /// - If exactly one product is infinite, the result is that product's infinity, the second
11987 /// product's sign counting as flipped.
11988 /// - If both products are infinite, the result is their common infinity if their signs differ,
11989 /// and `NaN` otherwise.
11990 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
11991 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
11992 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
11993 ///
11994 /// Overflow and underflow:
11995 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
11996 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
11997 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
11998 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
11999 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12000 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12001 ///
12002 /// If you want to use a rounding mode other than `Nearest`, consider using
12003 /// [`Float::mul_sub_mul_round`]. If you want to specify the output precision, consider using
12004 /// [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
12005 /// [`Float::mul_sub_mul_prec_round`].
12006 ///
12007 /// # Worst-case complexity
12008 /// $T(n, m) = O(n \log n \log\log n + m)$
12009 ///
12010 /// $M(n, m) = O(n \log n + m)$
12011 ///
12012 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12013 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12014 /// `self.significant_bits()`.
12015 ///
12016 /// # Examples
12017 /// ```
12018 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12019 /// use malachite_base::num::arithmetic::traits::MulSubMul;
12020 /// use malachite_float::Float;
12021 ///
12022 /// let x = Float::from(PI);
12023 /// let y = Float::from(E);
12024 /// let z = Float::from(SQRT_2);
12025 /// let w = Float::from(LN_2);
12026 /// assert_eq!(x.mul_sub_mul(y, z, w).to_string(), "7.5594760792050186");
12027 /// ```
12028 #[inline]
12029 fn mul_sub_mul(self, y: Self, z: Self, w: Self) -> Self {
12030 let prec = max!(
12031 self.significant_bits(),
12032 y.significant_bits(),
12033 z.significant_bits(),
12034 w.significant_bits()
12035 );
12036 self.mul_sub_mul_prec(y, z, w, prec).0
12037 }
12038}
12039
12040impl MulSubMul<Self, Self, &Self> for Float {
12041 type Output = Self;
12042 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
12043 /// single rounding, taking the first three by value and the fourth by reference.
12044 ///
12045 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
12046 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
12047 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
12048 /// `Nearest` rounding mode.
12049 ///
12050 /// $$
12051 /// f(x,y,z,w) = xy-zw+\varepsilon.
12052 /// $$
12053 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12054 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12055 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12056 ///
12057 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12058 ///
12059 /// Special cases:
12060 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12061 /// f(x,y,z,\text{NaN})=\text{NaN}$
12062 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12063 /// f(x,y,z,\text{NaN})=\text{NaN}$
12064 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12065 /// f(x,y,z,\text{NaN})=\text{NaN}$
12066 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12067 /// - If exactly one product is infinite, the result is that product's infinity, the second
12068 /// product's sign counting as flipped.
12069 /// - If both products are infinite, the result is their common infinity if their signs differ,
12070 /// and `NaN` otherwise.
12071 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
12072 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
12073 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
12074 ///
12075 /// Overflow and underflow:
12076 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12077 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12078 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12079 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12080 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12081 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12082 ///
12083 /// If you want to use a rounding mode other than `Nearest`, consider using
12084 /// [`Float::mul_sub_mul_round`]. If you want to specify the output precision, consider using
12085 /// [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
12086 /// [`Float::mul_sub_mul_prec_round`].
12087 ///
12088 /// # Worst-case complexity
12089 /// $T(n, m) = O(n \log n \log\log n + m)$
12090 ///
12091 /// $M(n, m) = O(n \log n + m)$
12092 ///
12093 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12094 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12095 /// `self.significant_bits()`.
12096 ///
12097 /// # Examples
12098 /// ```
12099 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12100 /// use malachite_base::num::arithmetic::traits::MulSubMul;
12101 /// use malachite_float::Float;
12102 ///
12103 /// let x = Float::from(PI);
12104 /// let y = Float::from(E);
12105 /// let z = Float::from(SQRT_2);
12106 /// let w = Float::from(LN_2);
12107 /// assert_eq!(x.mul_sub_mul(y, z, &w).to_string(), "7.5594760792050186");
12108 /// ```
12109 #[inline]
12110 fn mul_sub_mul(self, y: Self, z: Self, w: &Self) -> Self {
12111 let prec = max!(
12112 self.significant_bits(),
12113 y.significant_bits(),
12114 z.significant_bits(),
12115 w.significant_bits()
12116 );
12117 self.mul_sub_mul_prec_val_val_val_ref(y, z, w, prec).0
12118 }
12119}
12120
12121impl MulSubMul<Self, &Self, Self> for Float {
12122 type Output = Self;
12123 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
12124 /// single rounding, taking the third by reference and the others by value.
12125 ///
12126 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
12127 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
12128 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
12129 /// `Nearest` rounding mode.
12130 ///
12131 /// $$
12132 /// f(x,y,z,w) = xy-zw+\varepsilon.
12133 /// $$
12134 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12135 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12136 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12137 ///
12138 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12139 ///
12140 /// Special cases:
12141 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12142 /// f(x,y,z,\text{NaN})=\text{NaN}$
12143 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12144 /// f(x,y,z,\text{NaN})=\text{NaN}$
12145 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12146 /// f(x,y,z,\text{NaN})=\text{NaN}$
12147 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12148 /// - If exactly one product is infinite, the result is that product's infinity, the second
12149 /// product's sign counting as flipped.
12150 /// - If both products are infinite, the result is their common infinity if their signs differ,
12151 /// and `NaN` otherwise.
12152 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
12153 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
12154 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
12155 ///
12156 /// Overflow and underflow:
12157 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12158 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12159 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12160 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12161 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12162 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12163 ///
12164 /// If you want to use a rounding mode other than `Nearest`, consider using
12165 /// [`Float::mul_sub_mul_round`]. If you want to specify the output precision, consider using
12166 /// [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
12167 /// [`Float::mul_sub_mul_prec_round`].
12168 ///
12169 /// # Worst-case complexity
12170 /// $T(n, m) = O(n \log n \log\log n + m)$
12171 ///
12172 /// $M(n, m) = O(n \log n + m)$
12173 ///
12174 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12175 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12176 /// `self.significant_bits()`.
12177 ///
12178 /// # Examples
12179 /// ```
12180 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12181 /// use malachite_base::num::arithmetic::traits::MulSubMul;
12182 /// use malachite_float::Float;
12183 ///
12184 /// let x = Float::from(PI);
12185 /// let y = Float::from(E);
12186 /// let z = Float::from(SQRT_2);
12187 /// let w = Float::from(LN_2);
12188 /// assert_eq!(x.mul_sub_mul(y, &z, w).to_string(), "7.5594760792050186");
12189 /// ```
12190 #[inline]
12191 fn mul_sub_mul(self, y: Self, z: &Self, w: Self) -> Self {
12192 let prec = max!(
12193 self.significant_bits(),
12194 y.significant_bits(),
12195 z.significant_bits(),
12196 w.significant_bits()
12197 );
12198 self.mul_sub_mul_prec_val_val_ref_val(y, z, w, prec).0
12199 }
12200}
12201
12202impl MulSubMul<Self, &Self, &Self> for Float {
12203 type Output = Self;
12204 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
12205 /// single rounding, taking the first two by value and the last two by reference.
12206 ///
12207 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
12208 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
12209 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
12210 /// `Nearest` rounding mode.
12211 ///
12212 /// $$
12213 /// f(x,y,z,w) = xy-zw+\varepsilon.
12214 /// $$
12215 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12216 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12217 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12218 ///
12219 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12220 ///
12221 /// Special cases:
12222 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12223 /// f(x,y,z,\text{NaN})=\text{NaN}$
12224 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12225 /// f(x,y,z,\text{NaN})=\text{NaN}$
12226 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12227 /// f(x,y,z,\text{NaN})=\text{NaN}$
12228 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12229 /// - If exactly one product is infinite, the result is that product's infinity, the second
12230 /// product's sign counting as flipped.
12231 /// - If both products are infinite, the result is their common infinity if their signs differ,
12232 /// and `NaN` otherwise.
12233 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
12234 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
12235 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
12236 ///
12237 /// Overflow and underflow:
12238 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12239 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12240 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12241 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12242 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12243 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12244 ///
12245 /// If you want to use a rounding mode other than `Nearest`, consider using
12246 /// [`Float::mul_sub_mul_round`]. If you want to specify the output precision, consider using
12247 /// [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
12248 /// [`Float::mul_sub_mul_prec_round`].
12249 ///
12250 /// # Worst-case complexity
12251 /// $T(n, m) = O(n \log n \log\log n + m)$
12252 ///
12253 /// $M(n, m) = O(n \log n + m)$
12254 ///
12255 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12256 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12257 /// `self.significant_bits()`.
12258 ///
12259 /// # Examples
12260 /// ```
12261 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12262 /// use malachite_base::num::arithmetic::traits::MulSubMul;
12263 /// use malachite_float::Float;
12264 ///
12265 /// let x = Float::from(PI);
12266 /// let y = Float::from(E);
12267 /// let z = Float::from(SQRT_2);
12268 /// let w = Float::from(LN_2);
12269 /// assert_eq!(x.mul_sub_mul(y, &z, &w).to_string(), "7.5594760792050186");
12270 /// ```
12271 #[inline]
12272 fn mul_sub_mul(self, y: Self, z: &Self, w: &Self) -> Self {
12273 let prec = max!(
12274 self.significant_bits(),
12275 y.significant_bits(),
12276 z.significant_bits(),
12277 w.significant_bits()
12278 );
12279 self.mul_sub_mul_prec_val_val_ref_ref(y, z, w, prec).0
12280 }
12281}
12282
12283impl MulSubMul<&Self, Self, Self> for Float {
12284 type Output = Self;
12285 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
12286 /// single rounding, taking the second by reference and the others by value.
12287 ///
12288 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
12289 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
12290 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
12291 /// `Nearest` rounding mode.
12292 ///
12293 /// $$
12294 /// f(x,y,z,w) = xy-zw+\varepsilon.
12295 /// $$
12296 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12297 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12298 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12299 ///
12300 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12301 ///
12302 /// Special cases:
12303 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12304 /// f(x,y,z,\text{NaN})=\text{NaN}$
12305 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12306 /// f(x,y,z,\text{NaN})=\text{NaN}$
12307 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12308 /// f(x,y,z,\text{NaN})=\text{NaN}$
12309 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12310 /// - If exactly one product is infinite, the result is that product's infinity, the second
12311 /// product's sign counting as flipped.
12312 /// - If both products are infinite, the result is their common infinity if their signs differ,
12313 /// and `NaN` otherwise.
12314 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
12315 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
12316 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
12317 ///
12318 /// Overflow and underflow:
12319 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12320 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12321 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12322 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12323 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12324 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12325 ///
12326 /// If you want to use a rounding mode other than `Nearest`, consider using
12327 /// [`Float::mul_sub_mul_round`]. If you want to specify the output precision, consider using
12328 /// [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
12329 /// [`Float::mul_sub_mul_prec_round`].
12330 ///
12331 /// # Worst-case complexity
12332 /// $T(n, m) = O(n \log n \log\log n + m)$
12333 ///
12334 /// $M(n, m) = O(n \log n + m)$
12335 ///
12336 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12337 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12338 /// `self.significant_bits()`.
12339 ///
12340 /// # Examples
12341 /// ```
12342 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12343 /// use malachite_base::num::arithmetic::traits::MulSubMul;
12344 /// use malachite_float::Float;
12345 ///
12346 /// let x = Float::from(PI);
12347 /// let y = Float::from(E);
12348 /// let z = Float::from(SQRT_2);
12349 /// let w = Float::from(LN_2);
12350 /// assert_eq!(x.mul_sub_mul(&y, z, w).to_string(), "7.5594760792050186");
12351 /// ```
12352 #[inline]
12353 fn mul_sub_mul(self, y: &Self, z: Self, w: Self) -> Self {
12354 let prec = max!(
12355 self.significant_bits(),
12356 y.significant_bits(),
12357 z.significant_bits(),
12358 w.significant_bits()
12359 );
12360 self.mul_sub_mul_prec_val_ref_val_val(y, z, w, prec).0
12361 }
12362}
12363
12364impl MulSubMul<&Self, Self, &Self> for Float {
12365 type Output = Self;
12366 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
12367 /// single rounding, taking the second and fourth by reference and the others by value.
12368 ///
12369 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
12370 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
12371 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
12372 /// `Nearest` rounding mode.
12373 ///
12374 /// $$
12375 /// f(x,y,z,w) = xy-zw+\varepsilon.
12376 /// $$
12377 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12378 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12379 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12380 ///
12381 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12382 ///
12383 /// Special cases:
12384 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12385 /// f(x,y,z,\text{NaN})=\text{NaN}$
12386 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12387 /// f(x,y,z,\text{NaN})=\text{NaN}$
12388 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12389 /// f(x,y,z,\text{NaN})=\text{NaN}$
12390 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12391 /// - If exactly one product is infinite, the result is that product's infinity, the second
12392 /// product's sign counting as flipped.
12393 /// - If both products are infinite, the result is their common infinity if their signs differ,
12394 /// and `NaN` otherwise.
12395 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
12396 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
12397 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
12398 ///
12399 /// Overflow and underflow:
12400 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12401 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12402 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12403 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12404 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12405 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12406 ///
12407 /// If you want to use a rounding mode other than `Nearest`, consider using
12408 /// [`Float::mul_sub_mul_round`]. If you want to specify the output precision, consider using
12409 /// [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
12410 /// [`Float::mul_sub_mul_prec_round`].
12411 ///
12412 /// # Worst-case complexity
12413 /// $T(n, m) = O(n \log n \log\log n + m)$
12414 ///
12415 /// $M(n, m) = O(n \log n + m)$
12416 ///
12417 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12418 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12419 /// `self.significant_bits()`.
12420 ///
12421 /// # Examples
12422 /// ```
12423 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12424 /// use malachite_base::num::arithmetic::traits::MulSubMul;
12425 /// use malachite_float::Float;
12426 ///
12427 /// let x = Float::from(PI);
12428 /// let y = Float::from(E);
12429 /// let z = Float::from(SQRT_2);
12430 /// let w = Float::from(LN_2);
12431 /// assert_eq!(x.mul_sub_mul(&y, z, &w).to_string(), "7.5594760792050186");
12432 /// ```
12433 #[inline]
12434 fn mul_sub_mul(self, y: &Self, z: Self, w: &Self) -> Self {
12435 let prec = max!(
12436 self.significant_bits(),
12437 y.significant_bits(),
12438 z.significant_bits(),
12439 w.significant_bits()
12440 );
12441 self.mul_sub_mul_prec_val_ref_val_ref(y, z, w, prec).0
12442 }
12443}
12444
12445impl MulSubMul<&Self, &Self, Self> for Float {
12446 type Output = Self;
12447 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
12448 /// single rounding, taking the second and third by reference and the others by value.
12449 ///
12450 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
12451 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
12452 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
12453 /// `Nearest` rounding mode.
12454 ///
12455 /// $$
12456 /// f(x,y,z,w) = xy-zw+\varepsilon.
12457 /// $$
12458 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12459 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12460 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12461 ///
12462 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12463 ///
12464 /// Special cases:
12465 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12466 /// f(x,y,z,\text{NaN})=\text{NaN}$
12467 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12468 /// f(x,y,z,\text{NaN})=\text{NaN}$
12469 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12470 /// f(x,y,z,\text{NaN})=\text{NaN}$
12471 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12472 /// - If exactly one product is infinite, the result is that product's infinity, the second
12473 /// product's sign counting as flipped.
12474 /// - If both products are infinite, the result is their common infinity if their signs differ,
12475 /// and `NaN` otherwise.
12476 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
12477 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
12478 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
12479 ///
12480 /// Overflow and underflow:
12481 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12482 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12483 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12484 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12485 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12486 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12487 ///
12488 /// If you want to use a rounding mode other than `Nearest`, consider using
12489 /// [`Float::mul_sub_mul_round`]. If you want to specify the output precision, consider using
12490 /// [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
12491 /// [`Float::mul_sub_mul_prec_round`].
12492 ///
12493 /// # Worst-case complexity
12494 /// $T(n, m) = O(n \log n \log\log n + m)$
12495 ///
12496 /// $M(n, m) = O(n \log n + m)$
12497 ///
12498 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12499 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12500 /// `self.significant_bits()`.
12501 ///
12502 /// # Examples
12503 /// ```
12504 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12505 /// use malachite_base::num::arithmetic::traits::MulSubMul;
12506 /// use malachite_float::Float;
12507 ///
12508 /// let x = Float::from(PI);
12509 /// let y = Float::from(E);
12510 /// let z = Float::from(SQRT_2);
12511 /// let w = Float::from(LN_2);
12512 /// assert_eq!(x.mul_sub_mul(&y, &z, w).to_string(), "7.5594760792050186");
12513 /// ```
12514 #[inline]
12515 fn mul_sub_mul(self, y: &Self, z: &Self, w: Self) -> Self {
12516 let prec = max!(
12517 self.significant_bits(),
12518 y.significant_bits(),
12519 z.significant_bits(),
12520 w.significant_bits()
12521 );
12522 self.mul_sub_mul_prec_val_ref_ref_val(y, z, w, prec).0
12523 }
12524}
12525
12526impl MulSubMul<&Self, &Self, &Self> for Float {
12527 type Output = Self;
12528 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
12529 /// single rounding, taking the first by value and the others by reference.
12530 ///
12531 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
12532 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
12533 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
12534 /// `Nearest` rounding mode.
12535 ///
12536 /// $$
12537 /// f(x,y,z,w) = xy-zw+\varepsilon.
12538 /// $$
12539 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12540 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12541 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12542 ///
12543 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12544 ///
12545 /// Special cases:
12546 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12547 /// f(x,y,z,\text{NaN})=\text{NaN}$
12548 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12549 /// f(x,y,z,\text{NaN})=\text{NaN}$
12550 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12551 /// f(x,y,z,\text{NaN})=\text{NaN}$
12552 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12553 /// - If exactly one product is infinite, the result is that product's infinity, the second
12554 /// product's sign counting as flipped.
12555 /// - If both products are infinite, the result is their common infinity if their signs differ,
12556 /// and `NaN` otherwise.
12557 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
12558 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
12559 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
12560 ///
12561 /// Overflow and underflow:
12562 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12563 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12564 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12565 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12566 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12567 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12568 ///
12569 /// If you want to use a rounding mode other than `Nearest`, consider using
12570 /// [`Float::mul_sub_mul_round`]. If you want to specify the output precision, consider using
12571 /// [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
12572 /// [`Float::mul_sub_mul_prec_round`].
12573 ///
12574 /// # Worst-case complexity
12575 /// $T(n, m) = O(n \log n \log\log n + m)$
12576 ///
12577 /// $M(n, m) = O(n \log n + m)$
12578 ///
12579 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12580 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12581 /// `self.significant_bits()`.
12582 ///
12583 /// # Examples
12584 /// ```
12585 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12586 /// use malachite_base::num::arithmetic::traits::MulSubMul;
12587 /// use malachite_float::Float;
12588 ///
12589 /// let x = Float::from(PI);
12590 /// let y = Float::from(E);
12591 /// let z = Float::from(SQRT_2);
12592 /// let w = Float::from(LN_2);
12593 /// assert_eq!(x.mul_sub_mul(&y, &z, &w).to_string(), "7.5594760792050186");
12594 /// ```
12595 #[inline]
12596 fn mul_sub_mul(self, y: &Self, z: &Self, w: &Self) -> Self {
12597 let prec = max!(
12598 self.significant_bits(),
12599 y.significant_bits(),
12600 z.significant_bits(),
12601 w.significant_bits()
12602 );
12603 self.mul_sub_mul_prec_val_ref_ref_ref(y, z, w, prec).0
12604 }
12605}
12606
12607impl MulSubMul<&Float, &Float, &Float> for &Float {
12608 type Output = Float;
12609 /// Subtracts the product of one pair of [`Float`]s from the product of another pair with a
12610 /// single rounding, taking all four by reference.
12611 ///
12612 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
12613 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
12614 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
12615 /// `Nearest` rounding mode.
12616 ///
12617 /// $$
12618 /// f(x,y,z,w) = xy-zw+\varepsilon.
12619 /// $$
12620 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12621 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12622 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12623 ///
12624 /// If the output has a precision, it is the maximum of the precisions of the inputs.
12625 ///
12626 /// Special cases:
12627 /// - $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12628 /// f(x,y,z,\text{NaN})=\text{NaN}$
12629 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12630 /// f(x,y,z,\text{NaN})=\text{NaN}$
12631 /// $f(\text{NaN},y,z,w)=f(x,\text{NaN},z,w)=f(x,y,\text{NaN},w)=
12632 /// f(x,y,z,\text{NaN})=\text{NaN}$
12633 /// - If either product multiplies an infinity by a zero, the result is `NaN`.
12634 /// - If exactly one product is infinite, the result is that product's infinity, the second
12635 /// product's sign counting as flipped.
12636 /// - If both products are infinite, the result is their common infinity if their signs differ,
12637 /// and `NaN` otherwise.
12638 /// - If both products are zeros, the sign rules of [`Float`] addition apply to $xy$ and $-zw$.
12639 /// - $f(x,y,z,w)=0.0$ if $xy=zw$, the products are
12640 /// - $f(x,y,z,w)=0.0$ if $xy=zw$ and the products are finite and nonzero
12641 ///
12642 /// Overflow and underflow:
12643 /// - If $f(x,y,z,w)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
12644 /// - If $f(x,y,z,w)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
12645 /// - If $0<f(x,y,z,w)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
12646 /// - If $2^{-2^{30}-1}<f(x,y,z,w)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
12647 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,w)<0$, $-0.0$ is returned instead.
12648 /// - If $-2^{-2^{30}}<f(x,y,z,w)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
12649 ///
12650 /// If you want to use a rounding mode other than `Nearest`, consider using
12651 /// [`Float::mul_sub_mul_round`]. If you want to specify the output precision, consider using
12652 /// [`Float::mul_sub_mul_prec`]. If you want both of these things, consider using
12653 /// [`Float::mul_sub_mul_prec_round`].
12654 ///
12655 /// # Worst-case complexity
12656 /// $T(n, m) = O(n \log n \log\log n + m)$
12657 ///
12658 /// $M(n, m) = O(n \log n + m)$
12659 ///
12660 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12661 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12662 /// `self.significant_bits()`.
12663 ///
12664 /// # Examples
12665 /// ```
12666 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12667 /// use malachite_base::num::arithmetic::traits::MulSubMul;
12668 /// use malachite_float::Float;
12669 ///
12670 /// let x = Float::from(PI);
12671 /// let y = Float::from(E);
12672 /// let z = Float::from(SQRT_2);
12673 /// let w = Float::from(LN_2);
12674 /// assert_eq!(&x.mul_sub_mul(&y, &z, &w).to_string(), "7.5594760792050186");
12675 /// ```
12676 #[inline]
12677 fn mul_sub_mul(self, y: &Float, z: &Float, w: &Float) -> Float {
12678 let prec = max!(
12679 self.significant_bits(),
12680 y.significant_bits(),
12681 z.significant_bits(),
12682 w.significant_bits()
12683 );
12684 self.mul_sub_mul_prec_ref_ref_ref_ref(y, z, w, prec).0
12685 }
12686}
12687
12688impl MulSubMulAssign<Self, Self, Self> for Float {
12689 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
12690 /// [`Float`]s, with a single rounding. The [`Float`]s on the right-hand side are all taken by
12691 /// value.
12692 ///
12693 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
12694 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
12695 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
12696 /// `Nearest` rounding mode.
12697 ///
12698 /// $$
12699 /// x \gets xy-zw+\varepsilon.
12700 /// $$
12701 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12702 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12703 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12704 ///
12705 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
12706 /// overflow, and underflow.
12707 ///
12708 /// If you want to use a rounding mode other than `Nearest`, consider using
12709 /// [`Float::mul_sub_mul_round_assign`]. If you want to specify the output precision, consider
12710 /// using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things, consider using
12711 /// [`Float::mul_sub_mul_prec_round_assign`].
12712 ///
12713 /// # Worst-case complexity
12714 /// $T(n, m) = O(n \log n \log\log n + m)$
12715 ///
12716 /// $M(n, m) = O(n \log n + m)$
12717 ///
12718 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12719 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12720 /// `self.significant_bits()`.
12721 ///
12722 /// # Examples
12723 /// ```
12724 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12725 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
12726 /// use malachite_float::Float;
12727 ///
12728 /// let mut x = Float::from(PI);
12729 /// let y = Float::from(E);
12730 /// let z = Float::from(SQRT_2);
12731 /// let w = Float::from(LN_2);
12732 /// x.mul_sub_mul_assign(y, z, w);
12733 /// assert_eq!(x.to_string(), "7.5594760792050186");
12734 /// ```
12735 #[inline]
12736 fn mul_sub_mul_assign(&mut self, y: Self, z: Self, w: Self) {
12737 let prec = max!(
12738 self.significant_bits(),
12739 y.significant_bits(),
12740 z.significant_bits(),
12741 w.significant_bits()
12742 );
12743 self.mul_sub_mul_prec_assign(y, z, w, prec);
12744 }
12745}
12746
12747impl MulSubMulAssign<Self, Self, &Self> for Float {
12748 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
12749 /// [`Float`]s, with a single rounding. The last [`Float`] on the right-hand side is taken by
12750 /// reference and the others by value.
12751 ///
12752 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
12753 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
12754 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
12755 /// `Nearest` rounding mode.
12756 ///
12757 /// $$
12758 /// x \gets xy-zw+\varepsilon.
12759 /// $$
12760 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12761 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12762 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12763 ///
12764 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
12765 /// overflow, and underflow.
12766 ///
12767 /// If you want to use a rounding mode other than `Nearest`, consider using
12768 /// [`Float::mul_sub_mul_round_assign`]. If you want to specify the output precision, consider
12769 /// using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things, consider using
12770 /// [`Float::mul_sub_mul_prec_round_assign`].
12771 ///
12772 /// # Worst-case complexity
12773 /// $T(n, m) = O(n \log n \log\log n + m)$
12774 ///
12775 /// $M(n, m) = O(n \log n + m)$
12776 ///
12777 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12778 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12779 /// `self.significant_bits()`.
12780 ///
12781 /// # Examples
12782 /// ```
12783 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12784 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
12785 /// use malachite_float::Float;
12786 ///
12787 /// let mut x = Float::from(PI);
12788 /// let y = Float::from(E);
12789 /// let z = Float::from(SQRT_2);
12790 /// let w = Float::from(LN_2);
12791 /// x.mul_sub_mul_assign(y, z, &w);
12792 /// assert_eq!(x.to_string(), "7.5594760792050186");
12793 /// ```
12794 #[inline]
12795 fn mul_sub_mul_assign(&mut self, y: Self, z: Self, w: &Self) {
12796 let prec = max!(
12797 self.significant_bits(),
12798 y.significant_bits(),
12799 z.significant_bits(),
12800 w.significant_bits()
12801 );
12802 self.mul_sub_mul_prec_assign_val_val_ref(y, z, w, prec);
12803 }
12804}
12805
12806impl MulSubMulAssign<Self, &Self, Self> for Float {
12807 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
12808 /// [`Float`]s, with a single rounding. The middle [`Float`] on the right-hand side is taken by
12809 /// reference and the others by value.
12810 ///
12811 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
12812 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
12813 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
12814 /// `Nearest` rounding mode.
12815 ///
12816 /// $$
12817 /// x \gets xy-zw+\varepsilon.
12818 /// $$
12819 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12820 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12821 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12822 ///
12823 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
12824 /// overflow, and underflow.
12825 ///
12826 /// If you want to use a rounding mode other than `Nearest`, consider using
12827 /// [`Float::mul_sub_mul_round_assign`]. If you want to specify the output precision, consider
12828 /// using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things, consider using
12829 /// [`Float::mul_sub_mul_prec_round_assign`].
12830 ///
12831 /// # Worst-case complexity
12832 /// $T(n, m) = O(n \log n \log\log n + m)$
12833 ///
12834 /// $M(n, m) = O(n \log n + m)$
12835 ///
12836 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12837 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12838 /// `self.significant_bits()`.
12839 ///
12840 /// # Examples
12841 /// ```
12842 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12843 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
12844 /// use malachite_float::Float;
12845 ///
12846 /// let mut x = Float::from(PI);
12847 /// let y = Float::from(E);
12848 /// let z = Float::from(SQRT_2);
12849 /// let w = Float::from(LN_2);
12850 /// x.mul_sub_mul_assign(y, &z, w);
12851 /// assert_eq!(x.to_string(), "7.5594760792050186");
12852 /// ```
12853 #[inline]
12854 fn mul_sub_mul_assign(&mut self, y: Self, z: &Self, w: Self) {
12855 let prec = max!(
12856 self.significant_bits(),
12857 y.significant_bits(),
12858 z.significant_bits(),
12859 w.significant_bits()
12860 );
12861 self.mul_sub_mul_prec_assign_val_ref_val(y, z, w, prec);
12862 }
12863}
12864
12865impl MulSubMulAssign<Self, &Self, &Self> for Float {
12866 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
12867 /// [`Float`]s, with a single rounding. The first [`Float`] on the right-hand side is taken by
12868 /// value and the others by reference.
12869 ///
12870 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
12871 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
12872 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
12873 /// `Nearest` rounding mode.
12874 ///
12875 /// $$
12876 /// x \gets xy-zw+\varepsilon.
12877 /// $$
12878 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12879 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12880 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12881 ///
12882 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
12883 /// overflow, and underflow.
12884 ///
12885 /// If you want to use a rounding mode other than `Nearest`, consider using
12886 /// [`Float::mul_sub_mul_round_assign`]. If you want to specify the output precision, consider
12887 /// using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things, consider using
12888 /// [`Float::mul_sub_mul_prec_round_assign`].
12889 ///
12890 /// # Worst-case complexity
12891 /// $T(n, m) = O(n \log n \log\log n + m)$
12892 ///
12893 /// $M(n, m) = O(n \log n + m)$
12894 ///
12895 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12896 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12897 /// `self.significant_bits()`.
12898 ///
12899 /// # Examples
12900 /// ```
12901 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12902 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
12903 /// use malachite_float::Float;
12904 ///
12905 /// let mut x = Float::from(PI);
12906 /// let y = Float::from(E);
12907 /// let z = Float::from(SQRT_2);
12908 /// let w = Float::from(LN_2);
12909 /// x.mul_sub_mul_assign(y, &z, &w);
12910 /// assert_eq!(x.to_string(), "7.5594760792050186");
12911 /// ```
12912 #[inline]
12913 fn mul_sub_mul_assign(&mut self, y: Self, z: &Self, w: &Self) {
12914 let prec = max!(
12915 self.significant_bits(),
12916 y.significant_bits(),
12917 z.significant_bits(),
12918 w.significant_bits()
12919 );
12920 self.mul_sub_mul_prec_assign_val_ref_ref(y, z, w, prec);
12921 }
12922}
12923
12924impl MulSubMulAssign<&Self, Self, Self> for Float {
12925 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
12926 /// [`Float`]s, with a single rounding. The first [`Float`] on the right-hand side is taken by
12927 /// reference and the others by value.
12928 ///
12929 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
12930 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
12931 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
12932 /// `Nearest` rounding mode.
12933 ///
12934 /// $$
12935 /// x \gets xy-zw+\varepsilon.
12936 /// $$
12937 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12938 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12939 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12940 ///
12941 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
12942 /// overflow, and underflow.
12943 ///
12944 /// If you want to use a rounding mode other than `Nearest`, consider using
12945 /// [`Float::mul_sub_mul_round_assign`]. If you want to specify the output precision, consider
12946 /// using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things, consider using
12947 /// [`Float::mul_sub_mul_prec_round_assign`].
12948 ///
12949 /// # Worst-case complexity
12950 /// $T(n, m) = O(n \log n \log\log n + m)$
12951 ///
12952 /// $M(n, m) = O(n \log n + m)$
12953 ///
12954 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
12955 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
12956 /// `self.significant_bits()`.
12957 ///
12958 /// # Examples
12959 /// ```
12960 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
12961 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
12962 /// use malachite_float::Float;
12963 ///
12964 /// let mut x = Float::from(PI);
12965 /// let y = Float::from(E);
12966 /// let z = Float::from(SQRT_2);
12967 /// let w = Float::from(LN_2);
12968 /// x.mul_sub_mul_assign(&y, z, w);
12969 /// assert_eq!(x.to_string(), "7.5594760792050186");
12970 /// ```
12971 #[inline]
12972 fn mul_sub_mul_assign(&mut self, y: &Self, z: Self, w: Self) {
12973 let prec = max!(
12974 self.significant_bits(),
12975 y.significant_bits(),
12976 z.significant_bits(),
12977 w.significant_bits()
12978 );
12979 self.mul_sub_mul_prec_assign_ref_val_val(y, z, w, prec);
12980 }
12981}
12982
12983impl MulSubMulAssign<&Self, Self, &Self> for Float {
12984 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
12985 /// [`Float`]s, with a single rounding. The middle [`Float`] on the right-hand side is taken by
12986 /// value and the others by reference.
12987 ///
12988 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
12989 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
12990 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
12991 /// `Nearest` rounding mode.
12992 ///
12993 /// $$
12994 /// x \gets xy-zw+\varepsilon.
12995 /// $$
12996 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
12997 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
12998 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
12999 ///
13000 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
13001 /// overflow, and underflow.
13002 ///
13003 /// If you want to use a rounding mode other than `Nearest`, consider using
13004 /// [`Float::mul_sub_mul_round_assign`]. If you want to specify the output precision, consider
13005 /// using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things, consider using
13006 /// [`Float::mul_sub_mul_prec_round_assign`].
13007 ///
13008 /// # Worst-case complexity
13009 /// $T(n, m) = O(n \log n \log\log n + m)$
13010 ///
13011 /// $M(n, m) = O(n \log n + m)$
13012 ///
13013 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
13014 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
13015 /// `self.significant_bits()`.
13016 ///
13017 /// # Examples
13018 /// ```
13019 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
13020 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
13021 /// use malachite_float::Float;
13022 ///
13023 /// let mut x = Float::from(PI);
13024 /// let y = Float::from(E);
13025 /// let z = Float::from(SQRT_2);
13026 /// let w = Float::from(LN_2);
13027 /// x.mul_sub_mul_assign(&y, z, &w);
13028 /// assert_eq!(x.to_string(), "7.5594760792050186");
13029 /// ```
13030 #[inline]
13031 fn mul_sub_mul_assign(&mut self, y: &Self, z: Self, w: &Self) {
13032 let prec = max!(
13033 self.significant_bits(),
13034 y.significant_bits(),
13035 z.significant_bits(),
13036 w.significant_bits()
13037 );
13038 self.mul_sub_mul_prec_assign_ref_val_ref(y, z, w, prec);
13039 }
13040}
13041
13042impl MulSubMulAssign<&Self, &Self, Self> for Float {
13043 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
13044 /// [`Float`]s, with a single rounding. The last [`Float`] on the right-hand side is taken by
13045 /// value and the others by reference.
13046 ///
13047 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
13048 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
13049 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
13050 /// `Nearest` rounding mode.
13051 ///
13052 /// $$
13053 /// x \gets xy-zw+\varepsilon.
13054 /// $$
13055 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
13056 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
13057 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
13058 ///
13059 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
13060 /// overflow, and underflow.
13061 ///
13062 /// If you want to use a rounding mode other than `Nearest`, consider using
13063 /// [`Float::mul_sub_mul_round_assign`]. If you want to specify the output precision, consider
13064 /// using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things, consider using
13065 /// [`Float::mul_sub_mul_prec_round_assign`].
13066 ///
13067 /// # Worst-case complexity
13068 /// $T(n, m) = O(n \log n \log\log n + m)$
13069 ///
13070 /// $M(n, m) = O(n \log n + m)$
13071 ///
13072 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
13073 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
13074 /// `self.significant_bits()`.
13075 ///
13076 /// # Examples
13077 /// ```
13078 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
13079 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
13080 /// use malachite_float::Float;
13081 ///
13082 /// let mut x = Float::from(PI);
13083 /// let y = Float::from(E);
13084 /// let z = Float::from(SQRT_2);
13085 /// let w = Float::from(LN_2);
13086 /// x.mul_sub_mul_assign(&y, &z, w);
13087 /// assert_eq!(x.to_string(), "7.5594760792050186");
13088 /// ```
13089 #[inline]
13090 fn mul_sub_mul_assign(&mut self, y: &Self, z: &Self, w: Self) {
13091 let prec = max!(
13092 self.significant_bits(),
13093 y.significant_bits(),
13094 z.significant_bits(),
13095 w.significant_bits()
13096 );
13097 self.mul_sub_mul_prec_assign_ref_ref_val(y, z, w, prec);
13098 }
13099}
13100
13101impl MulSubMulAssign<&Self, &Self, &Self> for Float {
13102 /// Multiplies a [`Float`] by another [`Float`] in place and subtracts the product of two more
13103 /// [`Float`]s, with a single rounding. The [`Float`]s on the right-hand side are all taken by
13104 /// reference.
13105 ///
13106 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
13107 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
13108 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
13109 /// `Nearest` rounding mode.
13110 ///
13111 /// $$
13112 /// x \gets xy-zw+\varepsilon.
13113 /// $$
13114 /// - If $xy-zw$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
13115 /// - If $xy-zw$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
13116 /// |xy-zw|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
13117 ///
13118 /// See the [`Float::mul_sub_mul_prec_round`] documentation for information on special cases,
13119 /// overflow, and underflow.
13120 ///
13121 /// If you want to use a rounding mode other than `Nearest`, consider using
13122 /// [`Float::mul_sub_mul_round_assign`]. If you want to specify the output precision, consider
13123 /// using [`Float::mul_sub_mul_prec_assign`]. If you want both of these things, consider using
13124 /// [`Float::mul_sub_mul_prec_round_assign`].
13125 ///
13126 /// # Worst-case complexity
13127 /// $T(n, m) = O(n \log n \log\log n + m)$
13128 ///
13129 /// $M(n, m) = O(n \log n + m)$
13130 ///
13131 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
13132 /// y.significant_bits() + z.significant_bits() + w.significant_bits()`, and $m$ is
13133 /// `self.significant_bits()`.
13134 ///
13135 /// # Examples
13136 /// ```
13137 /// use core::f64::consts::{E, LN_2, PI, SQRT_2};
13138 /// use malachite_base::num::arithmetic::traits::MulSubMulAssign;
13139 /// use malachite_float::Float;
13140 ///
13141 /// let mut x = Float::from(PI);
13142 /// let y = Float::from(E);
13143 /// let z = Float::from(SQRT_2);
13144 /// let w = Float::from(LN_2);
13145 /// x.mul_sub_mul_assign(&y, &z, &w);
13146 /// assert_eq!(x.to_string(), "7.5594760792050186");
13147 /// ```
13148 #[inline]
13149 fn mul_sub_mul_assign(&mut self, y: &Self, z: &Self, w: &Self) {
13150 let prec = max!(
13151 self.significant_bits(),
13152 y.significant_bits(),
13153 z.significant_bits(),
13154 w.significant_bits()
13155 );
13156 self.mul_sub_mul_prec_assign_ref_ref_ref(y, z, w, prec);
13157 }
13158}
13159
13160/// Subtracts the product of one pair of primitive floats from the product of another pair with a
13161/// single rounding, using emulated [`Float`] arithmetic.
13162///
13163/// The products are not rounded before the subtraction, so the result is the true value of $xy-zw$
13164/// rounded once to the nearest representable value. No standard-library counterpart exists.
13165///
13166/// # Worst-case complexity
13167/// Constant time and additional memory.
13168///
13169/// # Examples
13170/// ```
13171/// use core::f64::consts::{E, LN_2, PI, SQRT_2};
13172/// use malachite_base::num::float::NiceFloat;
13173/// use malachite_float::float::arithmetic::mul_sub_mul::*;
13174///
13175/// assert_eq!(
13176/// NiceFloat(primitive_float_mul_sub_mul(PI, E, SQRT_2, LN_2)),
13177/// NiceFloat(7.559476079205019)
13178/// );
13179/// ```
13180#[allow(clippy::type_repetition_in_bounds)]
13181#[inline]
13182pub fn primitive_float_mul_sub_mul<T: PrimitiveFloat>(x: T, y: T, z: T, w: T) -> T
13183where
13184 Float: From<T> + PartialOrd<T>,
13185 for<'a> T: ExactFrom<&'a Float>,
13186{
13187 emulate_float_float_float_float_to_float_fn(Float::mul_sub_mul_prec, x, y, z, w)
13188}
13189
13190/// Subtracts the product of a primitive float and a [`Rational`] from the product of two primitive
13191/// floats, with a single rounding, using emulated [`Float`] arithmetic.
13192///
13193/// The [`Rational`] enters its product exactly, the products are not rounded before the
13194/// subtraction, and the result is the true value of $xy-zw$ rounded once to the nearest
13195/// representable value.
13196///
13197/// # Worst-case complexity
13198/// $T(n) = O(n \log n \log\log n)$
13199///
13200/// $M(n) = O(n \log n)$
13201///
13202/// where $T$ is time, $M$ is additional memory, and $n$ is `w.significant_bits()`.
13203///
13204/// # Examples
13205/// ```
13206/// use core::f64::consts::{E, PI, SQRT_2};
13207/// use malachite_base::num::float::NiceFloat;
13208/// use malachite_float::float::arithmetic::mul_sub_mul::*;
13209/// use malachite_q::Rational;
13210///
13211/// assert_eq!(
13212/// NiceFloat(primitive_float_mul_sub_mul_rational(
13213/// PI,
13214/// E,
13215/// SQRT_2,
13216/// &Rational::from_signeds(22, 7)
13217/// )),
13218/// NiceFloat(4.095063026643839)
13219/// );
13220/// ```
13221#[allow(clippy::type_repetition_in_bounds)]
13222#[inline]
13223pub fn primitive_float_mul_sub_mul_rational<T: PrimitiveFloat>(x: T, y: T, z: T, w: &Rational) -> T
13224where
13225 Float: From<T> + PartialOrd<T>,
13226 for<'a> T: ExactFrom<&'a Float>,
13227{
13228 emulate_float_float_float_to_float_fn(
13229 |x, y, z, prec| x.mul_sub_mul_rational_prec_val_val_val_ref(y, z, w, prec),
13230 x,
13231 y,
13232 z,
13233 )
13234}