malachite_float/float/arithmetic/sub_mul.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MPFR Library.
4//
5// Copyright © 2001-2025 Free Software Foundation, Inc.
6//
7// This file is part of Malachite.
8//
9// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
10// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
11// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
12
13use crate::float::arithmetic::add_mul::{
14 add_mul_helper, add_mul_rational_helper, add_mul_val_helper,
15};
16use crate::{Float, emulate_float_float_float_to_float_fn, emulate_float_float_to_float_fn};
17use core::cmp::{Ordering, max};
18use malachite_base::max;
19use malachite_base::num::arithmetic::traits::{SubMul, SubMulAssign};
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 fms.c, MPFR 4.2.2, up to a sign convention: mpfr_fms computes x * y - z by
27// negating its addend, while Malachite's sub_mul computes self - y * z by negating the product, so
28// mpfr_fms(x, y, z) = -sub_mul(z, x, y) with the rounding mode negated (an exact identity, since
29// negation is exact).
30impl Float {
31 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
32 /// specified precision and with the specified rounding mode. All three [`Float`]s are taken by
33 /// value. An [`Ordering`] is also returned, indicating whether the rounded diff is less than,
34 /// equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
35 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
36 ///
37 /// See [`RoundingMode`] for a description of the possible rounding modes.
38 ///
39 /// $$
40 /// f(x,y,z,p,m) = x-yz+\varepsilon.
41 /// $$
42 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
43 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
44 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
45 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
46 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
47 ///
48 /// If the output has a precision, it is `prec`.
49 ///
50 /// Special cases:
51 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
52 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
53 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
54 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
55 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
56 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
57 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
58 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
59 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=-0.0$
60 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=0.0$
61 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
62 /// not `Floor`
63 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$
64 /// is `Floor`
65 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
66 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
67 ///
68 /// Overflow and underflow:
69 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
70 /// returned instead.
71 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
72 /// is returned instead, where `p` is the precision of the output.
73 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
74 /// returned instead.
75 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
76 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
77 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
78 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
79 /// instead.
80 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
81 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
82 /// returned instead.
83 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
84 /// instead.
85 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
86 /// instead.
87 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
88 /// - If $-2^{-2^{30}}<f(x,y,z,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::sub_mul_prec`] instead. If
92 /// you know that your target precision is the maximum of the precisions of the inputs, consider
93 /// using [`Float::sub_mul_round`] instead. If both of these things are true, consider using
94 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
95 ///
96 /// # Worst-case complexity
97 /// $T(n, m) = O(n \log n \log\log n + m)$
98 ///
99 /// $M(n, m) = O(n \log n + m)$
100 ///
101 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
102 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
103 ///
104 /// # Panics
105 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
106 /// exactly representable with `prec` bits.
107 ///
108 /// # Examples
109 /// ```
110 /// use core::f64::consts::{E, PI, SQRT_2};
111 /// use malachite_base::rounding_modes::RoundingMode::*;
112 /// use malachite_float::Float;
113 /// use std::cmp::Ordering::*;
114 ///
115 /// let x = Float::from(PI);
116 /// let y = Float::from(E);
117 /// let z = Float::from(SQRT_2);
118 ///
119 /// let (diff, o) = x.clone().sub_mul_prec_round(y.clone(), z.clone(), 5, Floor);
120 /// assert_eq!(diff.to_string(), "-0.719");
121 /// assert_eq!(o, Less);
122 ///
123 /// let (diff, o) = x
124 /// .clone()
125 /// .sub_mul_prec_round(y.clone(), z.clone(), 5, Ceiling);
126 /// assert_eq!(diff.to_string(), "-0.688");
127 /// assert_eq!(o, Greater);
128 ///
129 /// let (diff, o) = x
130 /// .clone()
131 /// .sub_mul_prec_round(y.clone(), z.clone(), 5, Nearest);
132 /// assert_eq!(diff.to_string(), "-0.688");
133 /// assert_eq!(o, Greater);
134 ///
135 /// let (diff, o) = x
136 /// .clone()
137 /// .sub_mul_prec_round(y.clone(), z.clone(), 20, Floor);
138 /// assert_eq!(diff.to_string(), "-0.70263863");
139 /// assert_eq!(o, Less);
140 ///
141 /// let (diff, o) = x
142 /// .clone()
143 /// .sub_mul_prec_round(y.clone(), z.clone(), 20, Ceiling);
144 /// assert_eq!(diff.to_string(), "-0.70263767");
145 /// assert_eq!(o, Greater);
146 ///
147 /// let (diff, o) = x
148 /// .clone()
149 /// .sub_mul_prec_round(y.clone(), z.clone(), 20, Nearest);
150 /// assert_eq!(diff.to_string(), "-0.70263863");
151 /// assert_eq!(o, Less);
152 /// ```
153 #[allow(clippy::needless_pass_by_value)]
154 #[inline]
155 pub fn sub_mul_prec_round(
156 self,
157 y: Self,
158 z: Self,
159 prec: u64,
160 rm: RoundingMode,
161 ) -> (Self, Ordering) {
162 add_mul_val_helper(self, &y, &z, true, prec, rm)
163 }
164
165 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
166 /// specified precision and with the specified rounding mode. The first two [`Float`]s are taken
167 /// by value and the third by reference. An [`Ordering`] is also returned, indicating whether
168 /// the rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are
169 /// not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
170 /// `Equal`.
171 ///
172 /// See [`RoundingMode`] for a description of the possible rounding modes.
173 ///
174 /// $$
175 /// f(x,y,z,p,m) = x-yz+\varepsilon.
176 /// $$
177 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
178 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
179 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
180 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
181 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
182 ///
183 /// If the output has a precision, it is `prec`.
184 ///
185 /// Special cases:
186 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
187 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
188 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
189 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
190 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
191 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
192 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
193 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
194 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=-0.0$
195 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=0.0$
196 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
197 /// not `Floor`
198 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$
199 /// is `Floor`
200 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
201 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
202 ///
203 /// Overflow and underflow:
204 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
205 /// returned instead.
206 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
207 /// is returned instead, where `p` is the precision of the output.
208 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
209 /// returned instead.
210 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
211 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
212 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
213 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
214 /// instead.
215 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
216 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
217 /// returned instead.
218 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
219 /// instead.
220 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
221 /// instead.
222 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
223 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
224 /// returned instead.
225 ///
226 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_prec`] instead. If
227 /// you know that your target precision is the maximum of the precisions of the inputs, consider
228 /// using [`Float::sub_mul_round`] instead. If both of these things are true, consider using
229 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
230 ///
231 /// # Worst-case complexity
232 /// $T(n, m) = O(n \log n \log\log n + m)$
233 ///
234 /// $M(n, m) = O(n \log n + m)$
235 ///
236 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
237 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
238 ///
239 /// # Panics
240 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
241 /// exactly representable with `prec` bits.
242 ///
243 /// # Examples
244 /// ```
245 /// use core::f64::consts::{E, PI, SQRT_2};
246 /// use malachite_base::rounding_modes::RoundingMode::*;
247 /// use malachite_float::Float;
248 /// use std::cmp::Ordering::*;
249 ///
250 /// let x = Float::from(PI);
251 /// let y = Float::from(E);
252 /// let z = Float::from(SQRT_2);
253 ///
254 /// let (diff, o) = x
255 /// .clone()
256 /// .sub_mul_prec_round_val_val_ref(y.clone(), &z, 5, Floor);
257 /// assert_eq!(diff.to_string(), "-0.719");
258 /// assert_eq!(o, Less);
259 ///
260 /// let (diff, o) = x
261 /// .clone()
262 /// .sub_mul_prec_round_val_val_ref(y.clone(), &z, 5, Ceiling);
263 /// assert_eq!(diff.to_string(), "-0.688");
264 /// assert_eq!(o, Greater);
265 ///
266 /// let (diff, o) = x
267 /// .clone()
268 /// .sub_mul_prec_round_val_val_ref(y.clone(), &z, 5, Nearest);
269 /// assert_eq!(diff.to_string(), "-0.688");
270 /// assert_eq!(o, Greater);
271 ///
272 /// let (diff, o) = x
273 /// .clone()
274 /// .sub_mul_prec_round_val_val_ref(y.clone(), &z, 20, Floor);
275 /// assert_eq!(diff.to_string(), "-0.70263863");
276 /// assert_eq!(o, Less);
277 ///
278 /// let (diff, o) = x
279 /// .clone()
280 /// .sub_mul_prec_round_val_val_ref(y.clone(), &z, 20, Ceiling);
281 /// assert_eq!(diff.to_string(), "-0.70263767");
282 /// assert_eq!(o, Greater);
283 ///
284 /// let (diff, o) = x
285 /// .clone()
286 /// .sub_mul_prec_round_val_val_ref(y.clone(), &z, 20, Nearest);
287 /// assert_eq!(diff.to_string(), "-0.70263863");
288 /// assert_eq!(o, Less);
289 /// ```
290 #[allow(clippy::needless_pass_by_value)]
291 #[inline]
292 pub fn sub_mul_prec_round_val_val_ref(
293 self,
294 y: Self,
295 z: &Self,
296 prec: u64,
297 rm: RoundingMode,
298 ) -> (Self, Ordering) {
299 add_mul_val_helper(self, &y, z, true, prec, rm)
300 }
301
302 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
303 /// specified precision and with the specified rounding mode. The first and third [`Float`]s are
304 /// taken by value and the second by reference. An [`Ordering`] is also returned, indicating
305 /// whether the rounded diff is less than, equal to, or greater than the exact diff. Although
306 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
307 /// returns `Equal`.
308 ///
309 /// See [`RoundingMode`] for a description of the possible rounding modes.
310 ///
311 /// $$
312 /// f(x,y,z,p,m) = x-yz+\varepsilon.
313 /// $$
314 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
315 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
316 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
317 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
318 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
319 ///
320 /// If the output has a precision, it is `prec`.
321 ///
322 /// Special cases:
323 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
324 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
325 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
326 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
327 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
328 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
329 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
330 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
331 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=-0.0$
332 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=0.0$
333 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
334 /// not `Floor`
335 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$
336 /// is `Floor`
337 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
338 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
339 ///
340 /// Overflow and underflow:
341 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
342 /// returned instead.
343 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
344 /// is returned instead, where `p` is the precision of the output.
345 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
346 /// returned instead.
347 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
348 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
349 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
350 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
351 /// instead.
352 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
353 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
354 /// returned instead.
355 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
356 /// instead.
357 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
358 /// instead.
359 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
360 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
361 /// returned instead.
362 ///
363 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_prec`] instead. If
364 /// you know that your target precision is the maximum of the precisions of the inputs, consider
365 /// using [`Float::sub_mul_round`] instead. If both of these things are true, consider using
366 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
367 ///
368 /// # Worst-case complexity
369 /// $T(n, m) = O(n \log n \log\log n + m)$
370 ///
371 /// $M(n, m) = O(n \log n + m)$
372 ///
373 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
374 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
375 ///
376 /// # Panics
377 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
378 /// exactly representable with `prec` bits.
379 ///
380 /// # Examples
381 /// ```
382 /// use core::f64::consts::{E, PI, SQRT_2};
383 /// use malachite_base::rounding_modes::RoundingMode::*;
384 /// use malachite_float::Float;
385 /// use std::cmp::Ordering::*;
386 ///
387 /// let x = Float::from(PI);
388 /// let y = Float::from(E);
389 /// let z = Float::from(SQRT_2);
390 ///
391 /// let (diff, o) = x
392 /// .clone()
393 /// .sub_mul_prec_round_val_ref_val(&y, z.clone(), 5, Floor);
394 /// assert_eq!(diff.to_string(), "-0.719");
395 /// assert_eq!(o, Less);
396 ///
397 /// let (diff, o) = x
398 /// .clone()
399 /// .sub_mul_prec_round_val_ref_val(&y, z.clone(), 5, Ceiling);
400 /// assert_eq!(diff.to_string(), "-0.688");
401 /// assert_eq!(o, Greater);
402 ///
403 /// let (diff, o) = x
404 /// .clone()
405 /// .sub_mul_prec_round_val_ref_val(&y, z.clone(), 5, Nearest);
406 /// assert_eq!(diff.to_string(), "-0.688");
407 /// assert_eq!(o, Greater);
408 ///
409 /// let (diff, o) = x
410 /// .clone()
411 /// .sub_mul_prec_round_val_ref_val(&y, z.clone(), 20, Floor);
412 /// assert_eq!(diff.to_string(), "-0.70263863");
413 /// assert_eq!(o, Less);
414 ///
415 /// let (diff, o) = x
416 /// .clone()
417 /// .sub_mul_prec_round_val_ref_val(&y, z.clone(), 20, Ceiling);
418 /// assert_eq!(diff.to_string(), "-0.70263767");
419 /// assert_eq!(o, Greater);
420 ///
421 /// let (diff, o) = x
422 /// .clone()
423 /// .sub_mul_prec_round_val_ref_val(&y, z.clone(), 20, Nearest);
424 /// assert_eq!(diff.to_string(), "-0.70263863");
425 /// assert_eq!(o, Less);
426 /// ```
427 #[allow(clippy::needless_pass_by_value)]
428 #[inline]
429 pub fn sub_mul_prec_round_val_ref_val(
430 self,
431 y: &Self,
432 z: Self,
433 prec: u64,
434 rm: RoundingMode,
435 ) -> (Self, Ordering) {
436 add_mul_val_helper(self, y, &z, true, prec, rm)
437 }
438
439 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
440 /// specified precision and with the specified rounding mode. The first [`Float`] is taken by
441 /// value and the second and third by reference. An [`Ordering`] is also returned, indicating
442 /// whether the rounded diff is less than, equal to, or greater than the exact diff. Although
443 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
444 /// returns `Equal`.
445 ///
446 /// See [`RoundingMode`] for a description of the possible rounding modes.
447 ///
448 /// $$
449 /// f(x,y,z,p,m) = x-yz+\varepsilon.
450 /// $$
451 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
452 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
453 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
454 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
455 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
456 ///
457 /// If the output has a precision, it is `prec`.
458 ///
459 /// Special cases:
460 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
461 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
462 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
463 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
464 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
465 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
466 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
467 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
468 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=-0.0$
469 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=0.0$
470 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
471 /// not `Floor`
472 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$
473 /// is `Floor`
474 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
475 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
476 ///
477 /// Overflow and underflow:
478 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
479 /// returned instead.
480 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
481 /// is returned instead, where `p` is the precision of the output.
482 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
483 /// returned instead.
484 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
485 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
486 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
487 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
488 /// instead.
489 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
490 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
491 /// returned instead.
492 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
493 /// instead.
494 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
495 /// instead.
496 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
497 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
498 /// returned instead.
499 ///
500 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_prec`] instead. If
501 /// you know that your target precision is the maximum of the precisions of the inputs, consider
502 /// using [`Float::sub_mul_round`] instead. If both of these things are true, consider using
503 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
504 ///
505 /// # Worst-case complexity
506 /// $T(n, m) = O(n \log n \log\log n + m)$
507 ///
508 /// $M(n, m) = O(n \log n + m)$
509 ///
510 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
511 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
512 ///
513 /// # Panics
514 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
515 /// exactly representable with `prec` bits.
516 ///
517 /// # Examples
518 /// ```
519 /// use core::f64::consts::{E, PI, SQRT_2};
520 /// use malachite_base::rounding_modes::RoundingMode::*;
521 /// use malachite_float::Float;
522 /// use std::cmp::Ordering::*;
523 ///
524 /// let x = Float::from(PI);
525 /// let y = Float::from(E);
526 /// let z = Float::from(SQRT_2);
527 ///
528 /// let (diff, o) = x.clone().sub_mul_prec_round_val_ref_ref(&y, &z, 5, Floor);
529 /// assert_eq!(diff.to_string(), "-0.719");
530 /// assert_eq!(o, Less);
531 ///
532 /// let (diff, o) = x.clone().sub_mul_prec_round_val_ref_ref(&y, &z, 5, Ceiling);
533 /// assert_eq!(diff.to_string(), "-0.688");
534 /// assert_eq!(o, Greater);
535 ///
536 /// let (diff, o) = x.clone().sub_mul_prec_round_val_ref_ref(&y, &z, 5, Nearest);
537 /// assert_eq!(diff.to_string(), "-0.688");
538 /// assert_eq!(o, Greater);
539 ///
540 /// let (diff, o) = x.clone().sub_mul_prec_round_val_ref_ref(&y, &z, 20, Floor);
541 /// assert_eq!(diff.to_string(), "-0.70263863");
542 /// assert_eq!(o, Less);
543 ///
544 /// let (diff, o) = x
545 /// .clone()
546 /// .sub_mul_prec_round_val_ref_ref(&y, &z, 20, Ceiling);
547 /// assert_eq!(diff.to_string(), "-0.70263767");
548 /// assert_eq!(o, Greater);
549 ///
550 /// let (diff, o) = x
551 /// .clone()
552 /// .sub_mul_prec_round_val_ref_ref(&y, &z, 20, Nearest);
553 /// assert_eq!(diff.to_string(), "-0.70263863");
554 /// assert_eq!(o, Less);
555 /// ```
556 #[inline]
557 pub fn sub_mul_prec_round_val_ref_ref(
558 self,
559 y: &Self,
560 z: &Self,
561 prec: u64,
562 rm: RoundingMode,
563 ) -> (Self, Ordering) {
564 add_mul_val_helper(self, y, z, true, prec, rm)
565 }
566
567 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
568 /// specified precision and with the specified rounding mode. The first [`Float`] is taken by
569 /// reference and the second and third by value. An [`Ordering`] is also returned, indicating
570 /// whether the rounded diff is less than, equal to, or greater than the exact diff. Although
571 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
572 /// returns `Equal`.
573 ///
574 /// See [`RoundingMode`] for a description of the possible rounding modes.
575 ///
576 /// $$
577 /// f(x,y,z,p,m) = x-yz+\varepsilon.
578 /// $$
579 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
580 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
581 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
582 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
583 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
584 ///
585 /// If the output has a precision, it is `prec`.
586 ///
587 /// Special cases:
588 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
589 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
590 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
591 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
592 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
593 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
594 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
595 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
596 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=-0.0$
597 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=0.0$
598 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
599 /// not `Floor`
600 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$
601 /// is `Floor`
602 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
603 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
604 ///
605 /// Overflow and underflow:
606 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
607 /// returned instead.
608 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
609 /// is returned instead, where `p` is the precision of the output.
610 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
611 /// returned instead.
612 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
613 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
614 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
615 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
616 /// instead.
617 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
618 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
619 /// returned instead.
620 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
621 /// instead.
622 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
623 /// instead.
624 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
625 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
626 /// returned instead.
627 ///
628 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_prec`] instead. If
629 /// you know that your target precision is the maximum of the precisions of the inputs, consider
630 /// using [`Float::sub_mul_round`] instead. If both of these things are true, consider using
631 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
632 ///
633 /// # Worst-case complexity
634 /// $T(n, m) = O(n \log n \log\log n + m)$
635 ///
636 /// $M(n, m) = O(n \log n + m)$
637 ///
638 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
639 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
640 ///
641 /// # Panics
642 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
643 /// exactly representable with `prec` bits.
644 ///
645 /// # Examples
646 /// ```
647 /// use core::f64::consts::{E, PI, SQRT_2};
648 /// use malachite_base::rounding_modes::RoundingMode::*;
649 /// use malachite_float::Float;
650 /// use std::cmp::Ordering::*;
651 ///
652 /// let x = Float::from(PI);
653 /// let y = Float::from(E);
654 /// let z = Float::from(SQRT_2);
655 ///
656 /// let (diff, o) = x.sub_mul_prec_round_ref_val_val(y.clone(), z.clone(), 5, Floor);
657 /// assert_eq!(diff.to_string(), "-0.719");
658 /// assert_eq!(o, Less);
659 ///
660 /// let (diff, o) = x.sub_mul_prec_round_ref_val_val(y.clone(), z.clone(), 5, Ceiling);
661 /// assert_eq!(diff.to_string(), "-0.688");
662 /// assert_eq!(o, Greater);
663 ///
664 /// let (diff, o) = x.sub_mul_prec_round_ref_val_val(y.clone(), z.clone(), 5, Nearest);
665 /// assert_eq!(diff.to_string(), "-0.688");
666 /// assert_eq!(o, Greater);
667 ///
668 /// let (diff, o) = x.sub_mul_prec_round_ref_val_val(y.clone(), z.clone(), 20, Floor);
669 /// assert_eq!(diff.to_string(), "-0.70263863");
670 /// assert_eq!(o, Less);
671 ///
672 /// let (diff, o) = x.sub_mul_prec_round_ref_val_val(y.clone(), z.clone(), 20, Ceiling);
673 /// assert_eq!(diff.to_string(), "-0.70263767");
674 /// assert_eq!(o, Greater);
675 ///
676 /// let (diff, o) = x.sub_mul_prec_round_ref_val_val(y.clone(), z.clone(), 20, Nearest);
677 /// assert_eq!(diff.to_string(), "-0.70263863");
678 /// assert_eq!(o, Less);
679 /// ```
680 #[allow(clippy::needless_pass_by_value)]
681 #[inline]
682 pub fn sub_mul_prec_round_ref_val_val(
683 &self,
684 y: Self,
685 z: Self,
686 prec: u64,
687 rm: RoundingMode,
688 ) -> (Self, Ordering) {
689 add_mul_helper(self, &y, &z, true, prec, rm)
690 }
691
692 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
693 /// specified precision and with the specified rounding mode. The first and third [`Float`]s are
694 /// taken by reference and the second by value. An [`Ordering`] is also returned, indicating
695 /// whether the rounded diff is less than, equal to, or greater than the exact diff. Although
696 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
697 /// returns `Equal`.
698 ///
699 /// See [`RoundingMode`] for a description of the possible rounding modes.
700 ///
701 /// $$
702 /// f(x,y,z,p,m) = x-yz+\varepsilon.
703 /// $$
704 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
705 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
706 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
707 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
708 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
709 ///
710 /// If the output has a precision, it is `prec`.
711 ///
712 /// Special cases:
713 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
714 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
715 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
716 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
717 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
718 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
719 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
720 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
721 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=-0.0$
722 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=0.0$
723 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
724 /// not `Floor`
725 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$
726 /// is `Floor`
727 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
728 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
729 ///
730 /// Overflow and underflow:
731 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
732 /// returned instead.
733 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
734 /// is returned instead, where `p` is the precision of the output.
735 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
736 /// returned instead.
737 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
738 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
739 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
740 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
741 /// instead.
742 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
743 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
744 /// returned instead.
745 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
746 /// instead.
747 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
748 /// instead.
749 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
750 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
751 /// returned instead.
752 ///
753 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_prec`] instead. If
754 /// you know that your target precision is the maximum of the precisions of the inputs, consider
755 /// using [`Float::sub_mul_round`] instead. If both of these things are true, consider using
756 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
757 ///
758 /// # Worst-case complexity
759 /// $T(n, m) = O(n \log n \log\log n + m)$
760 ///
761 /// $M(n, m) = O(n \log n + m)$
762 ///
763 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
764 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
765 ///
766 /// # Panics
767 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
768 /// exactly representable with `prec` bits.
769 ///
770 /// # Examples
771 /// ```
772 /// use core::f64::consts::{E, PI, SQRT_2};
773 /// use malachite_base::rounding_modes::RoundingMode::*;
774 /// use malachite_float::Float;
775 /// use std::cmp::Ordering::*;
776 ///
777 /// let x = Float::from(PI);
778 /// let y = Float::from(E);
779 /// let z = Float::from(SQRT_2);
780 ///
781 /// let (diff, o) = x.sub_mul_prec_round_ref_val_ref(y.clone(), &z, 5, Floor);
782 /// assert_eq!(diff.to_string(), "-0.719");
783 /// assert_eq!(o, Less);
784 ///
785 /// let (diff, o) = x.sub_mul_prec_round_ref_val_ref(y.clone(), &z, 5, Ceiling);
786 /// assert_eq!(diff.to_string(), "-0.688");
787 /// assert_eq!(o, Greater);
788 ///
789 /// let (diff, o) = x.sub_mul_prec_round_ref_val_ref(y.clone(), &z, 5, Nearest);
790 /// assert_eq!(diff.to_string(), "-0.688");
791 /// assert_eq!(o, Greater);
792 ///
793 /// let (diff, o) = x.sub_mul_prec_round_ref_val_ref(y.clone(), &z, 20, Floor);
794 /// assert_eq!(diff.to_string(), "-0.70263863");
795 /// assert_eq!(o, Less);
796 ///
797 /// let (diff, o) = x.sub_mul_prec_round_ref_val_ref(y.clone(), &z, 20, Ceiling);
798 /// assert_eq!(diff.to_string(), "-0.70263767");
799 /// assert_eq!(o, Greater);
800 ///
801 /// let (diff, o) = x.sub_mul_prec_round_ref_val_ref(y.clone(), &z, 20, Nearest);
802 /// assert_eq!(diff.to_string(), "-0.70263863");
803 /// assert_eq!(o, Less);
804 /// ```
805 #[allow(clippy::needless_pass_by_value)]
806 #[inline]
807 pub fn sub_mul_prec_round_ref_val_ref(
808 &self,
809 y: Self,
810 z: &Self,
811 prec: u64,
812 rm: RoundingMode,
813 ) -> (Self, Ordering) {
814 add_mul_helper(self, &y, z, true, prec, rm)
815 }
816
817 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
818 /// specified precision and with the specified rounding mode. The first two [`Float`]s are taken
819 /// by reference and the third by value. An [`Ordering`] is also returned, indicating whether
820 /// the rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are
821 /// not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
822 /// `Equal`.
823 ///
824 /// See [`RoundingMode`] for a description of the possible rounding modes.
825 ///
826 /// $$
827 /// f(x,y,z,p,m) = x-yz+\varepsilon.
828 /// $$
829 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
830 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
831 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
832 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
833 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
834 ///
835 /// If the output has a precision, it is `prec`.
836 ///
837 /// Special cases:
838 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
839 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
840 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
841 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
842 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
843 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
844 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
845 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
846 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=-0.0$
847 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=0.0$
848 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
849 /// not `Floor`
850 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$
851 /// is `Floor`
852 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
853 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
854 ///
855 /// Overflow and underflow:
856 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
857 /// returned instead.
858 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
859 /// is returned instead, where `p` is the precision of the output.
860 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
861 /// returned instead.
862 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
863 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
864 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
865 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
866 /// instead.
867 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
868 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
869 /// returned instead.
870 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
871 /// instead.
872 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
873 /// instead.
874 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
875 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
876 /// returned instead.
877 ///
878 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_prec`] instead. If
879 /// you know that your target precision is the maximum of the precisions of the inputs, consider
880 /// using [`Float::sub_mul_round`] instead. If both of these things are true, consider using
881 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
882 ///
883 /// # Worst-case complexity
884 /// $T(n, m) = O(n \log n \log\log n + m)$
885 ///
886 /// $M(n, m) = O(n \log n + m)$
887 ///
888 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
889 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
890 ///
891 /// # Panics
892 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
893 /// exactly representable with `prec` bits.
894 ///
895 /// # Examples
896 /// ```
897 /// use core::f64::consts::{E, PI, SQRT_2};
898 /// use malachite_base::rounding_modes::RoundingMode::*;
899 /// use malachite_float::Float;
900 /// use std::cmp::Ordering::*;
901 ///
902 /// let x = Float::from(PI);
903 /// let y = Float::from(E);
904 /// let z = Float::from(SQRT_2);
905 ///
906 /// let (diff, o) = x.sub_mul_prec_round_ref_ref_val(&y, z.clone(), 5, Floor);
907 /// assert_eq!(diff.to_string(), "-0.719");
908 /// assert_eq!(o, Less);
909 ///
910 /// let (diff, o) = x.sub_mul_prec_round_ref_ref_val(&y, z.clone(), 5, Ceiling);
911 /// assert_eq!(diff.to_string(), "-0.688");
912 /// assert_eq!(o, Greater);
913 ///
914 /// let (diff, o) = x.sub_mul_prec_round_ref_ref_val(&y, z.clone(), 5, Nearest);
915 /// assert_eq!(diff.to_string(), "-0.688");
916 /// assert_eq!(o, Greater);
917 ///
918 /// let (diff, o) = x.sub_mul_prec_round_ref_ref_val(&y, z.clone(), 20, Floor);
919 /// assert_eq!(diff.to_string(), "-0.70263863");
920 /// assert_eq!(o, Less);
921 ///
922 /// let (diff, o) = x.sub_mul_prec_round_ref_ref_val(&y, z.clone(), 20, Ceiling);
923 /// assert_eq!(diff.to_string(), "-0.70263767");
924 /// assert_eq!(o, Greater);
925 ///
926 /// let (diff, o) = x.sub_mul_prec_round_ref_ref_val(&y, z.clone(), 20, Nearest);
927 /// assert_eq!(diff.to_string(), "-0.70263863");
928 /// assert_eq!(o, Less);
929 /// ```
930 #[allow(clippy::needless_pass_by_value)]
931 #[inline]
932 pub fn sub_mul_prec_round_ref_ref_val(
933 &self,
934 y: &Self,
935 z: Self,
936 prec: u64,
937 rm: RoundingMode,
938 ) -> (Self, Ordering) {
939 add_mul_helper(self, y, &z, true, prec, rm)
940 }
941
942 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
943 /// specified precision and with the specified rounding mode. All three [`Float`]s are taken by
944 /// reference. An [`Ordering`] is also returned, indicating whether the rounded diff is less
945 /// than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
946 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
947 ///
948 /// See [`RoundingMode`] for a description of the possible rounding modes.
949 ///
950 /// $$
951 /// f(x,y,z,p,m) = x-yz+\varepsilon.
952 /// $$
953 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
954 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
955 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
956 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
957 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
958 ///
959 /// If the output has a precision, it is `prec`.
960 ///
961 /// Special cases:
962 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=f(x,y,\text{NaN},p,m)=\text{NaN}$
963 /// - $f(x,\pm\infty,\pm0.0,p,m)=f(x,\pm0.0,\pm\infty,p,m)=\text{NaN}$
964 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
965 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
966 /// - $f(\infty,y,z,p,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
967 /// - $f(-\infty,y,z,p,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
968 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
969 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
970 /// - $f(0.0,y,z,p,m)=0.0$ if $yz=-0.0$
971 /// - $f(-0.0,y,z,p,m)=-0.0$ if $yz=0.0$
972 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
973 /// not `Floor`
974 /// - $f(0.0,y,z,p,m)=f(-0.0,y,z,p,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$
975 /// is `Floor`
976 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
977 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
978 ///
979 /// Overflow and underflow:
980 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
981 /// returned instead.
982 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
983 /// is returned instead, where `p` is the precision of the output.
984 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
985 /// returned instead.
986 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
987 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
988 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
989 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
990 /// instead.
991 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
992 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
993 /// returned instead.
994 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
995 /// instead.
996 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
997 /// instead.
998 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
999 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
1000 /// returned instead.
1001 ///
1002 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_prec`] instead. If
1003 /// you know that your target precision is the maximum of the precisions of the inputs, consider
1004 /// using [`Float::sub_mul_round`] instead. If both of these things are true, consider using
1005 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
1006 ///
1007 /// # Worst-case complexity
1008 /// $T(n, m) = O(n \log n \log\log n + m)$
1009 ///
1010 /// $M(n, m) = O(n \log n + m)$
1011 ///
1012 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1013 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1014 ///
1015 /// # Panics
1016 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
1017 /// exactly representable with `prec` bits.
1018 ///
1019 /// # Examples
1020 /// ```
1021 /// use core::f64::consts::{E, PI, SQRT_2};
1022 /// use malachite_base::rounding_modes::RoundingMode::*;
1023 /// use malachite_float::Float;
1024 /// use std::cmp::Ordering::*;
1025 ///
1026 /// let x = Float::from(PI);
1027 /// let y = Float::from(E);
1028 /// let z = Float::from(SQRT_2);
1029 ///
1030 /// let (diff, o) = x.sub_mul_prec_round_ref_ref_ref(&y, &z, 5, Floor);
1031 /// assert_eq!(diff.to_string(), "-0.719");
1032 /// assert_eq!(o, Less);
1033 ///
1034 /// let (diff, o) = x.sub_mul_prec_round_ref_ref_ref(&y, &z, 5, Ceiling);
1035 /// assert_eq!(diff.to_string(), "-0.688");
1036 /// assert_eq!(o, Greater);
1037 ///
1038 /// let (diff, o) = x.sub_mul_prec_round_ref_ref_ref(&y, &z, 5, Nearest);
1039 /// assert_eq!(diff.to_string(), "-0.688");
1040 /// assert_eq!(o, Greater);
1041 ///
1042 /// let (diff, o) = x.sub_mul_prec_round_ref_ref_ref(&y, &z, 20, Floor);
1043 /// assert_eq!(diff.to_string(), "-0.70263863");
1044 /// assert_eq!(o, Less);
1045 ///
1046 /// let (diff, o) = x.sub_mul_prec_round_ref_ref_ref(&y, &z, 20, Ceiling);
1047 /// assert_eq!(diff.to_string(), "-0.70263767");
1048 /// assert_eq!(o, Greater);
1049 ///
1050 /// let (diff, o) = x.sub_mul_prec_round_ref_ref_ref(&y, &z, 20, Nearest);
1051 /// assert_eq!(diff.to_string(), "-0.70263863");
1052 /// assert_eq!(o, Less);
1053 /// ```
1054 #[inline]
1055 pub fn sub_mul_prec_round_ref_ref_ref(
1056 &self,
1057 y: &Self,
1058 z: &Self,
1059 prec: u64,
1060 rm: RoundingMode,
1061 ) -> (Self, Ordering) {
1062 add_mul_helper(self, y, z, true, prec, rm)
1063 }
1064
1065 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, rounding the result to
1066 /// the specified precision and with the specified rounding mode. Both [`Float`]s on the
1067 /// right-hand side are taken by value. An [`Ordering`] is returned, indicating whether the
1068 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
1069 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1070 ///
1071 /// See [`RoundingMode`] for a description of the possible rounding modes.
1072 ///
1073 /// $$
1074 /// x \gets x-yz+\varepsilon.
1075 /// $$
1076 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1077 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
1078 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1079 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
1080 ///
1081 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
1082 /// overflow, and underflow.
1083 ///
1084 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_prec_assign`]
1085 /// instead. If you know that your target precision is the maximum of the precisions of the
1086 /// inputs, consider using [`Float::sub_mul_round_assign`] instead. If both of these things are
1087 /// true, consider using
1088 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
1089 /// instead.
1090 ///
1091 /// # Worst-case complexity
1092 /// $T(n, m) = O(n \log n \log\log n + m)$
1093 ///
1094 /// $M(n, m) = O(n \log n + m)$
1095 ///
1096 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1097 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1098 ///
1099 /// # Panics
1100 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
1101 /// exactly representable with `prec` bits.
1102 ///
1103 /// # Examples
1104 /// ```
1105 /// use core::f64::consts::{E, PI, SQRT_2};
1106 /// use malachite_base::rounding_modes::RoundingMode::*;
1107 /// use malachite_float::Float;
1108 /// use std::cmp::Ordering::*;
1109 ///
1110 /// let y = Float::from(E);
1111 /// let z = Float::from(SQRT_2);
1112 ///
1113 /// let mut x = Float::from(PI);
1114 /// assert_eq!(
1115 /// x.sub_mul_prec_round_assign(y.clone(), z.clone(), 5, Floor),
1116 /// Less
1117 /// );
1118 /// assert_eq!(x.to_string(), "-0.719");
1119 ///
1120 /// let mut x = Float::from(PI);
1121 /// assert_eq!(
1122 /// x.sub_mul_prec_round_assign(y.clone(), z.clone(), 5, Ceiling),
1123 /// Greater
1124 /// );
1125 /// assert_eq!(x.to_string(), "-0.688");
1126 ///
1127 /// let mut x = Float::from(PI);
1128 /// assert_eq!(
1129 /// x.sub_mul_prec_round_assign(y.clone(), z.clone(), 5, Nearest),
1130 /// Greater
1131 /// );
1132 /// assert_eq!(x.to_string(), "-0.688");
1133 /// ```
1134 #[allow(clippy::needless_pass_by_value)]
1135 #[inline]
1136 pub fn sub_mul_prec_round_assign(
1137 &mut self,
1138 y: Self,
1139 z: Self,
1140 prec: u64,
1141 rm: RoundingMode,
1142 ) -> Ordering {
1143 let (s, o) = add_mul_helper(self, &y, &z, true, prec, rm);
1144 *self = s;
1145 o
1146 }
1147
1148 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, rounding the result to
1149 /// the specified precision and with the specified rounding mode. The first [`Float`] on the
1150 /// right-hand side is taken by value and the second by reference. An [`Ordering`] is returned,
1151 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
1152 /// Although `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN`
1153 /// it also returns `Equal`.
1154 ///
1155 /// See [`RoundingMode`] for a description of the possible rounding modes.
1156 ///
1157 /// $$
1158 /// x \gets x-yz+\varepsilon.
1159 /// $$
1160 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1161 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
1162 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1163 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
1164 ///
1165 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
1166 /// overflow, and underflow.
1167 ///
1168 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_prec_assign`]
1169 /// instead. If you know that your target precision is the maximum of the precisions of the
1170 /// inputs, consider using [`Float::sub_mul_round_assign`] instead. If both of these things are
1171 /// true, consider using
1172 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
1173 /// instead.
1174 ///
1175 /// # Worst-case complexity
1176 /// $T(n, m) = O(n \log n \log\log n + m)$
1177 ///
1178 /// $M(n, m) = O(n \log n + m)$
1179 ///
1180 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1181 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1182 ///
1183 /// # Panics
1184 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
1185 /// exactly representable with `prec` bits.
1186 ///
1187 /// # Examples
1188 /// ```
1189 /// use core::f64::consts::{E, PI, SQRT_2};
1190 /// use malachite_base::rounding_modes::RoundingMode::*;
1191 /// use malachite_float::Float;
1192 /// use std::cmp::Ordering::*;
1193 ///
1194 /// let y = Float::from(E);
1195 /// let z = Float::from(SQRT_2);
1196 ///
1197 /// let mut x = Float::from(PI);
1198 /// assert_eq!(
1199 /// x.sub_mul_prec_round_assign_val_ref(y.clone(), &z, 5, Floor),
1200 /// Less
1201 /// );
1202 /// assert_eq!(x.to_string(), "-0.719");
1203 ///
1204 /// let mut x = Float::from(PI);
1205 /// assert_eq!(
1206 /// x.sub_mul_prec_round_assign_val_ref(y.clone(), &z, 5, Ceiling),
1207 /// Greater
1208 /// );
1209 /// assert_eq!(x.to_string(), "-0.688");
1210 ///
1211 /// let mut x = Float::from(PI);
1212 /// assert_eq!(
1213 /// x.sub_mul_prec_round_assign_val_ref(y.clone(), &z, 5, Nearest),
1214 /// Greater
1215 /// );
1216 /// assert_eq!(x.to_string(), "-0.688");
1217 /// ```
1218 #[allow(clippy::needless_pass_by_value)]
1219 #[inline]
1220 pub fn sub_mul_prec_round_assign_val_ref(
1221 &mut self,
1222 y: Self,
1223 z: &Self,
1224 prec: u64,
1225 rm: RoundingMode,
1226 ) -> Ordering {
1227 let (s, o) = add_mul_helper(self, &y, z, true, prec, rm);
1228 *self = s;
1229 o
1230 }
1231
1232 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, rounding the result to
1233 /// the specified precision and with the specified rounding mode. The first [`Float`] on the
1234 /// right-hand side is taken by reference and the second by value. An [`Ordering`] is returned,
1235 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
1236 /// Although `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN`
1237 /// it also returns `Equal`.
1238 ///
1239 /// See [`RoundingMode`] for a description of the possible rounding modes.
1240 ///
1241 /// $$
1242 /// x \gets x-yz+\varepsilon.
1243 /// $$
1244 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1245 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
1246 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1247 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
1248 ///
1249 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
1250 /// overflow, and underflow.
1251 ///
1252 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_prec_assign`]
1253 /// instead. If you know that your target precision is the maximum of the precisions of the
1254 /// inputs, consider using [`Float::sub_mul_round_assign`] instead. If both of these things are
1255 /// true, consider using
1256 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
1257 /// instead.
1258 ///
1259 /// # Worst-case complexity
1260 /// $T(n, m) = O(n \log n \log\log n + m)$
1261 ///
1262 /// $M(n, m) = O(n \log n + m)$
1263 ///
1264 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1265 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1266 ///
1267 /// # Panics
1268 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
1269 /// exactly representable with `prec` bits.
1270 ///
1271 /// # Examples
1272 /// ```
1273 /// use core::f64::consts::{E, PI, SQRT_2};
1274 /// use malachite_base::rounding_modes::RoundingMode::*;
1275 /// use malachite_float::Float;
1276 /// use std::cmp::Ordering::*;
1277 ///
1278 /// let y = Float::from(E);
1279 /// let z = Float::from(SQRT_2);
1280 ///
1281 /// let mut x = Float::from(PI);
1282 /// assert_eq!(
1283 /// x.sub_mul_prec_round_assign_ref_val(&y, z.clone(), 5, Floor),
1284 /// Less
1285 /// );
1286 /// assert_eq!(x.to_string(), "-0.719");
1287 ///
1288 /// let mut x = Float::from(PI);
1289 /// assert_eq!(
1290 /// x.sub_mul_prec_round_assign_ref_val(&y, z.clone(), 5, Ceiling),
1291 /// Greater
1292 /// );
1293 /// assert_eq!(x.to_string(), "-0.688");
1294 ///
1295 /// let mut x = Float::from(PI);
1296 /// assert_eq!(
1297 /// x.sub_mul_prec_round_assign_ref_val(&y, z.clone(), 5, Nearest),
1298 /// Greater
1299 /// );
1300 /// assert_eq!(x.to_string(), "-0.688");
1301 /// ```
1302 #[allow(clippy::needless_pass_by_value)]
1303 #[inline]
1304 pub fn sub_mul_prec_round_assign_ref_val(
1305 &mut self,
1306 y: &Self,
1307 z: Self,
1308 prec: u64,
1309 rm: RoundingMode,
1310 ) -> Ordering {
1311 let (s, o) = add_mul_helper(self, y, &z, true, prec, rm);
1312 *self = s;
1313 o
1314 }
1315
1316 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, rounding the result to
1317 /// the specified precision and with the specified rounding mode. Both [`Float`]s on the
1318 /// right-hand side are taken by reference. An [`Ordering`] is returned, indicating whether the
1319 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
1320 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
1321 ///
1322 /// See [`RoundingMode`] for a description of the possible rounding modes.
1323 ///
1324 /// $$
1325 /// x \gets x-yz+\varepsilon.
1326 /// $$
1327 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1328 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
1329 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
1330 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
1331 ///
1332 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
1333 /// overflow, and underflow.
1334 ///
1335 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_prec_assign`]
1336 /// instead. If you know that your target precision is the maximum of the precisions of the
1337 /// inputs, consider using [`Float::sub_mul_round_assign`] instead. If both of these things are
1338 /// true, consider using
1339 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
1340 /// instead.
1341 ///
1342 /// # Worst-case complexity
1343 /// $T(n, m) = O(n \log n \log\log n + m)$
1344 ///
1345 /// $M(n, m) = O(n \log n + m)$
1346 ///
1347 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1348 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1349 ///
1350 /// # Panics
1351 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
1352 /// exactly representable with `prec` bits.
1353 ///
1354 /// # Examples
1355 /// ```
1356 /// use core::f64::consts::{E, PI, SQRT_2};
1357 /// use malachite_base::rounding_modes::RoundingMode::*;
1358 /// use malachite_float::Float;
1359 /// use std::cmp::Ordering::*;
1360 ///
1361 /// let y = Float::from(E);
1362 /// let z = Float::from(SQRT_2);
1363 ///
1364 /// let mut x = Float::from(PI);
1365 /// assert_eq!(x.sub_mul_prec_round_assign_ref_ref(&y, &z, 5, Floor), Less);
1366 /// assert_eq!(x.to_string(), "-0.719");
1367 ///
1368 /// let mut x = Float::from(PI);
1369 /// assert_eq!(
1370 /// x.sub_mul_prec_round_assign_ref_ref(&y, &z, 5, Ceiling),
1371 /// Greater
1372 /// );
1373 /// assert_eq!(x.to_string(), "-0.688");
1374 ///
1375 /// let mut x = Float::from(PI);
1376 /// assert_eq!(
1377 /// x.sub_mul_prec_round_assign_ref_ref(&y, &z, 5, Nearest),
1378 /// Greater
1379 /// );
1380 /// assert_eq!(x.to_string(), "-0.688");
1381 /// ```
1382 #[inline]
1383 pub fn sub_mul_prec_round_assign_ref_ref(
1384 &mut self,
1385 y: &Self,
1386 z: &Self,
1387 prec: u64,
1388 rm: RoundingMode,
1389 ) -> Ordering {
1390 let (s, o) = add_mul_helper(self, y, z, true, prec, rm);
1391 *self = s;
1392 o
1393 }
1394
1395 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
1396 /// nearest value of the specified precision. All three [`Float`]s are taken by value. An
1397 /// [`Ordering`] is also returned, indicating whether the rounded diff is less than, equal to,
1398 /// or greater than the exact diff. Although `NaN`s are not comparable to any [`Float`],
1399 /// whenever this function returns a `NaN` it also returns `Equal`.
1400 ///
1401 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1402 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1403 /// the `Nearest` rounding mode.
1404 ///
1405 /// $$
1406 /// f(x,y,z,p) = x-yz+\varepsilon.
1407 /// $$
1408 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1409 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1410 /// |x-yz|\rfloor-p}$.
1411 ///
1412 /// If the output has a precision, it is `prec`.
1413 ///
1414 /// Special cases:
1415 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
1416 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
1417 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
1418 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
1419 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
1420 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
1421 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
1422 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
1423 /// - $f(0.0,y,z,p)=0.0$ if $yz=-0.0$
1424 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=0.0$
1425 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of the same sign
1426 /// - $f(x,y,z,p)=0.0$ if $x=yz$, $x$ is finite and nonzero,
1427 ///
1428 /// Overflow and underflow:
1429 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1430 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
1431 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1432 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1433 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
1434 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1435 ///
1436 /// If you want to use a rounding mode other than `Nearest`, consider using
1437 /// [`Float::sub_mul_prec_round`] instead. If you know that your target precision is the maximum
1438 /// of the precisions of the inputs, consider using
1439 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
1440 ///
1441 /// # Worst-case complexity
1442 /// $T(n, m) = O(n \log n \log\log n + m)$
1443 ///
1444 /// $M(n, m) = O(n \log n + m)$
1445 ///
1446 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1447 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1448 ///
1449 /// # Panics
1450 /// Panics if `prec` is zero.
1451 ///
1452 /// # Examples
1453 /// ```
1454 /// use core::f64::consts::{E, PI, SQRT_2};
1455 /// use malachite_float::Float;
1456 /// use std::cmp::Ordering::*;
1457 ///
1458 /// let x = Float::from(PI);
1459 /// let y = Float::from(E);
1460 /// let z = Float::from(SQRT_2);
1461 ///
1462 /// let (diff, o) = x.clone().sub_mul_prec(y.clone(), z.clone(), 5);
1463 /// assert_eq!(diff.to_string(), "-0.688");
1464 /// assert_eq!(o, Greater);
1465 ///
1466 /// let (diff, o) = x.clone().sub_mul_prec(y.clone(), z.clone(), 20);
1467 /// assert_eq!(diff.to_string(), "-0.70263863");
1468 /// assert_eq!(o, Less);
1469 /// ```
1470 #[allow(clippy::needless_pass_by_value)]
1471 #[inline]
1472 pub fn sub_mul_prec(self, y: Self, z: Self, prec: u64) -> (Self, Ordering) {
1473 self.sub_mul_prec_round(y, z, prec, Nearest)
1474 }
1475
1476 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
1477 /// nearest value of the specified precision. The first two [`Float`]s are taken by value and
1478 /// the third by reference. An [`Ordering`] is also returned, indicating whether the rounded
1479 /// diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
1480 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1481 ///
1482 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1483 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1484 /// the `Nearest` rounding mode.
1485 ///
1486 /// $$
1487 /// f(x,y,z,p) = x-yz+\varepsilon.
1488 /// $$
1489 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1490 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1491 /// |x-yz|\rfloor-p}$.
1492 ///
1493 /// If the output has a precision, it is `prec`.
1494 ///
1495 /// Special cases:
1496 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
1497 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
1498 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
1499 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
1500 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
1501 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
1502 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
1503 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
1504 /// - $f(0.0,y,z,p)=0.0$ if $yz=-0.0$
1505 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=0.0$
1506 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of the same sign
1507 /// - $f(x,y,z,p)=0.0$ if $x=yz$, $x$ is finite and nonzero,
1508 ///
1509 /// Overflow and underflow:
1510 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1511 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
1512 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1513 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1514 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
1515 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1516 ///
1517 /// If you want to use a rounding mode other than `Nearest`, consider using
1518 /// [`Float::sub_mul_prec_round`] instead. If you know that your target precision is the maximum
1519 /// of the precisions of the inputs, consider using
1520 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
1521 ///
1522 /// # Worst-case complexity
1523 /// $T(n, m) = O(n \log n \log\log n + m)$
1524 ///
1525 /// $M(n, m) = O(n \log n + m)$
1526 ///
1527 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1528 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1529 ///
1530 /// # Panics
1531 /// Panics if `prec` is zero.
1532 ///
1533 /// # Examples
1534 /// ```
1535 /// use core::f64::consts::{E, PI, SQRT_2};
1536 /// use malachite_float::Float;
1537 /// use std::cmp::Ordering::*;
1538 ///
1539 /// let x = Float::from(PI);
1540 /// let y = Float::from(E);
1541 /// let z = Float::from(SQRT_2);
1542 ///
1543 /// let (diff, o) = x.clone().sub_mul_prec_val_val_ref(y.clone(), &z, 5);
1544 /// assert_eq!(diff.to_string(), "-0.688");
1545 /// assert_eq!(o, Greater);
1546 ///
1547 /// let (diff, o) = x.clone().sub_mul_prec_val_val_ref(y.clone(), &z, 20);
1548 /// assert_eq!(diff.to_string(), "-0.70263863");
1549 /// assert_eq!(o, Less);
1550 /// ```
1551 #[allow(clippy::needless_pass_by_value)]
1552 #[inline]
1553 pub fn sub_mul_prec_val_val_ref(self, y: Self, z: &Self, prec: u64) -> (Self, Ordering) {
1554 self.sub_mul_prec_round_val_val_ref(y, z, prec, Nearest)
1555 }
1556
1557 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
1558 /// nearest value of the specified precision. The first and third [`Float`]s are taken by value
1559 /// and the second by reference. An [`Ordering`] is also returned, indicating whether the
1560 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
1561 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1562 ///
1563 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1564 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1565 /// the `Nearest` rounding mode.
1566 ///
1567 /// $$
1568 /// f(x,y,z,p) = x-yz+\varepsilon.
1569 /// $$
1570 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1571 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1572 /// |x-yz|\rfloor-p}$.
1573 ///
1574 /// If the output has a precision, it is `prec`.
1575 ///
1576 /// Special cases:
1577 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
1578 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
1579 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
1580 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
1581 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
1582 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
1583 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
1584 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
1585 /// - $f(0.0,y,z,p)=0.0$ if $yz=-0.0$
1586 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=0.0$
1587 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of the same sign
1588 /// - $f(x,y,z,p)=0.0$ if $x=yz$, $x$ is finite and nonzero,
1589 ///
1590 /// Overflow and underflow:
1591 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1592 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
1593 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1594 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1595 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
1596 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1597 ///
1598 /// If you want to use a rounding mode other than `Nearest`, consider using
1599 /// [`Float::sub_mul_prec_round`] instead. If you know that your target precision is the maximum
1600 /// of the precisions of the inputs, consider using
1601 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
1602 ///
1603 /// # Worst-case complexity
1604 /// $T(n, m) = O(n \log n \log\log n + m)$
1605 ///
1606 /// $M(n, m) = O(n \log n + m)$
1607 ///
1608 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1609 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1610 ///
1611 /// # Panics
1612 /// Panics if `prec` is zero.
1613 ///
1614 /// # Examples
1615 /// ```
1616 /// use core::f64::consts::{E, PI, SQRT_2};
1617 /// use malachite_float::Float;
1618 /// use std::cmp::Ordering::*;
1619 ///
1620 /// let x = Float::from(PI);
1621 /// let y = Float::from(E);
1622 /// let z = Float::from(SQRT_2);
1623 ///
1624 /// let (diff, o) = x.clone().sub_mul_prec_val_ref_val(&y, z.clone(), 5);
1625 /// assert_eq!(diff.to_string(), "-0.688");
1626 /// assert_eq!(o, Greater);
1627 ///
1628 /// let (diff, o) = x.clone().sub_mul_prec_val_ref_val(&y, z.clone(), 20);
1629 /// assert_eq!(diff.to_string(), "-0.70263863");
1630 /// assert_eq!(o, Less);
1631 /// ```
1632 #[allow(clippy::needless_pass_by_value)]
1633 #[inline]
1634 pub fn sub_mul_prec_val_ref_val(self, y: &Self, z: Self, prec: u64) -> (Self, Ordering) {
1635 self.sub_mul_prec_round_val_ref_val(y, z, prec, Nearest)
1636 }
1637
1638 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
1639 /// nearest value of the specified precision. The first [`Float`] is taken by value and the
1640 /// second and third by reference. An [`Ordering`] is also returned, indicating whether the
1641 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
1642 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1643 ///
1644 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1645 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1646 /// the `Nearest` rounding mode.
1647 ///
1648 /// $$
1649 /// f(x,y,z,p) = x-yz+\varepsilon.
1650 /// $$
1651 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1652 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1653 /// |x-yz|\rfloor-p}$.
1654 ///
1655 /// If the output has a precision, it is `prec`.
1656 ///
1657 /// Special cases:
1658 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
1659 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
1660 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
1661 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
1662 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
1663 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
1664 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
1665 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
1666 /// - $f(0.0,y,z,p)=0.0$ if $yz=-0.0$
1667 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=0.0$
1668 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of the same sign
1669 /// - $f(x,y,z,p)=0.0$ if $x=yz$, $x$ is finite and nonzero,
1670 ///
1671 /// Overflow and underflow:
1672 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1673 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
1674 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1675 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1676 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
1677 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1678 ///
1679 /// If you want to use a rounding mode other than `Nearest`, consider using
1680 /// [`Float::sub_mul_prec_round`] instead. If you know that your target precision is the maximum
1681 /// of the precisions of the inputs, consider using
1682 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
1683 ///
1684 /// # Worst-case complexity
1685 /// $T(n, m) = O(n \log n \log\log n + m)$
1686 ///
1687 /// $M(n, m) = O(n \log n + m)$
1688 ///
1689 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1690 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1691 ///
1692 /// # Panics
1693 /// Panics if `prec` is zero.
1694 ///
1695 /// # Examples
1696 /// ```
1697 /// use core::f64::consts::{E, PI, SQRT_2};
1698 /// use malachite_float::Float;
1699 /// use std::cmp::Ordering::*;
1700 ///
1701 /// let x = Float::from(PI);
1702 /// let y = Float::from(E);
1703 /// let z = Float::from(SQRT_2);
1704 ///
1705 /// let (diff, o) = x.clone().sub_mul_prec_val_ref_ref(&y, &z, 5);
1706 /// assert_eq!(diff.to_string(), "-0.688");
1707 /// assert_eq!(o, Greater);
1708 ///
1709 /// let (diff, o) = x.clone().sub_mul_prec_val_ref_ref(&y, &z, 20);
1710 /// assert_eq!(diff.to_string(), "-0.70263863");
1711 /// assert_eq!(o, Less);
1712 /// ```
1713 #[inline]
1714 pub fn sub_mul_prec_val_ref_ref(self, y: &Self, z: &Self, prec: u64) -> (Self, Ordering) {
1715 self.sub_mul_prec_round_val_ref_ref(y, z, prec, Nearest)
1716 }
1717
1718 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
1719 /// nearest value of the specified precision. The first [`Float`] is taken by reference and the
1720 /// second and third by value. An [`Ordering`] is also returned, indicating whether the rounded
1721 /// diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
1722 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1723 ///
1724 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1725 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1726 /// the `Nearest` rounding mode.
1727 ///
1728 /// $$
1729 /// f(x,y,z,p) = x-yz+\varepsilon.
1730 /// $$
1731 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1732 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1733 /// |x-yz|\rfloor-p}$.
1734 ///
1735 /// If the output has a precision, it is `prec`.
1736 ///
1737 /// Special cases:
1738 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
1739 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
1740 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
1741 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
1742 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
1743 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
1744 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
1745 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
1746 /// - $f(0.0,y,z,p)=0.0$ if $yz=-0.0$
1747 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=0.0$
1748 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of the same sign
1749 /// - $f(x,y,z,p)=0.0$ if $x=yz$, $x$ is finite and nonzero,
1750 ///
1751 /// Overflow and underflow:
1752 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1753 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
1754 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1755 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1756 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
1757 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1758 ///
1759 /// If you want to use a rounding mode other than `Nearest`, consider using
1760 /// [`Float::sub_mul_prec_round`] instead. If you know that your target precision is the maximum
1761 /// of the precisions of the inputs, consider using
1762 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
1763 ///
1764 /// # Worst-case complexity
1765 /// $T(n, m) = O(n \log n \log\log n + m)$
1766 ///
1767 /// $M(n, m) = O(n \log n + m)$
1768 ///
1769 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1770 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1771 ///
1772 /// # Panics
1773 /// Panics if `prec` is zero.
1774 ///
1775 /// # Examples
1776 /// ```
1777 /// use core::f64::consts::{E, PI, SQRT_2};
1778 /// use malachite_float::Float;
1779 /// use std::cmp::Ordering::*;
1780 ///
1781 /// let x = Float::from(PI);
1782 /// let y = Float::from(E);
1783 /// let z = Float::from(SQRT_2);
1784 ///
1785 /// let (diff, o) = x.sub_mul_prec_ref_val_val(y.clone(), z.clone(), 5);
1786 /// assert_eq!(diff.to_string(), "-0.688");
1787 /// assert_eq!(o, Greater);
1788 ///
1789 /// let (diff, o) = x.sub_mul_prec_ref_val_val(y.clone(), z.clone(), 20);
1790 /// assert_eq!(diff.to_string(), "-0.70263863");
1791 /// assert_eq!(o, Less);
1792 /// ```
1793 #[allow(clippy::needless_pass_by_value)]
1794 #[inline]
1795 pub fn sub_mul_prec_ref_val_val(&self, y: Self, z: Self, prec: u64) -> (Self, Ordering) {
1796 self.sub_mul_prec_round_ref_val_val(y, z, prec, Nearest)
1797 }
1798
1799 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
1800 /// nearest value of the specified precision. The first and third [`Float`]s are taken by
1801 /// reference and the second by value. An [`Ordering`] is also returned, indicating whether the
1802 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
1803 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1804 ///
1805 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1806 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1807 /// the `Nearest` rounding mode.
1808 ///
1809 /// $$
1810 /// f(x,y,z,p) = x-yz+\varepsilon.
1811 /// $$
1812 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1813 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1814 /// |x-yz|\rfloor-p}$.
1815 ///
1816 /// If the output has a precision, it is `prec`.
1817 ///
1818 /// Special cases:
1819 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
1820 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
1821 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
1822 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
1823 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
1824 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
1825 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
1826 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
1827 /// - $f(0.0,y,z,p)=0.0$ if $yz=-0.0$
1828 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=0.0$
1829 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of the same sign
1830 /// - $f(x,y,z,p)=0.0$ if $x=yz$, $x$ is finite and nonzero,
1831 ///
1832 /// Overflow and underflow:
1833 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1834 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
1835 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1836 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1837 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
1838 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1839 ///
1840 /// If you want to use a rounding mode other than `Nearest`, consider using
1841 /// [`Float::sub_mul_prec_round`] instead. If you know that your target precision is the maximum
1842 /// of the precisions of the inputs, consider using
1843 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
1844 ///
1845 /// # Worst-case complexity
1846 /// $T(n, m) = O(n \log n \log\log n + m)$
1847 ///
1848 /// $M(n, m) = O(n \log n + m)$
1849 ///
1850 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1851 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1852 ///
1853 /// # Panics
1854 /// Panics if `prec` is zero.
1855 ///
1856 /// # Examples
1857 /// ```
1858 /// use core::f64::consts::{E, PI, SQRT_2};
1859 /// use malachite_float::Float;
1860 /// use std::cmp::Ordering::*;
1861 ///
1862 /// let x = Float::from(PI);
1863 /// let y = Float::from(E);
1864 /// let z = Float::from(SQRT_2);
1865 ///
1866 /// let (diff, o) = x.sub_mul_prec_ref_val_ref(y.clone(), &z, 5);
1867 /// assert_eq!(diff.to_string(), "-0.688");
1868 /// assert_eq!(o, Greater);
1869 ///
1870 /// let (diff, o) = x.sub_mul_prec_ref_val_ref(y.clone(), &z, 20);
1871 /// assert_eq!(diff.to_string(), "-0.70263863");
1872 /// assert_eq!(o, Less);
1873 /// ```
1874 #[allow(clippy::needless_pass_by_value)]
1875 #[inline]
1876 pub fn sub_mul_prec_ref_val_ref(&self, y: Self, z: &Self, prec: u64) -> (Self, Ordering) {
1877 self.sub_mul_prec_round_ref_val_ref(y, z, prec, Nearest)
1878 }
1879
1880 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
1881 /// nearest value of the specified precision. The first two [`Float`]s are taken by reference
1882 /// and the third by value. An [`Ordering`] is also returned, indicating whether the rounded
1883 /// diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
1884 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1885 ///
1886 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1887 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1888 /// the `Nearest` rounding mode.
1889 ///
1890 /// $$
1891 /// f(x,y,z,p) = x-yz+\varepsilon.
1892 /// $$
1893 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1894 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1895 /// |x-yz|\rfloor-p}$.
1896 ///
1897 /// If the output has a precision, it is `prec`.
1898 ///
1899 /// Special cases:
1900 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
1901 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
1902 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
1903 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
1904 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
1905 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
1906 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
1907 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
1908 /// - $f(0.0,y,z,p)=0.0$ if $yz=-0.0$
1909 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=0.0$
1910 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of the same sign
1911 /// - $f(x,y,z,p)=0.0$ if $x=yz$, $x$ is finite and nonzero,
1912 ///
1913 /// Overflow and underflow:
1914 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1915 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
1916 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1917 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1918 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
1919 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
1920 ///
1921 /// If you want to use a rounding mode other than `Nearest`, consider using
1922 /// [`Float::sub_mul_prec_round`] instead. If you know that your target precision is the maximum
1923 /// of the precisions of the inputs, consider using
1924 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
1925 ///
1926 /// # Worst-case complexity
1927 /// $T(n, m) = O(n \log n \log\log n + m)$
1928 ///
1929 /// $M(n, m) = O(n \log n + m)$
1930 ///
1931 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
1932 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
1933 ///
1934 /// # Panics
1935 /// Panics if `prec` is zero.
1936 ///
1937 /// # Examples
1938 /// ```
1939 /// use core::f64::consts::{E, PI, SQRT_2};
1940 /// use malachite_float::Float;
1941 /// use std::cmp::Ordering::*;
1942 ///
1943 /// let x = Float::from(PI);
1944 /// let y = Float::from(E);
1945 /// let z = Float::from(SQRT_2);
1946 ///
1947 /// let (diff, o) = x.sub_mul_prec_ref_ref_val(&y, z.clone(), 5);
1948 /// assert_eq!(diff.to_string(), "-0.688");
1949 /// assert_eq!(o, Greater);
1950 ///
1951 /// let (diff, o) = x.sub_mul_prec_ref_ref_val(&y, z.clone(), 20);
1952 /// assert_eq!(diff.to_string(), "-0.70263863");
1953 /// assert_eq!(o, Less);
1954 /// ```
1955 #[allow(clippy::needless_pass_by_value)]
1956 #[inline]
1957 pub fn sub_mul_prec_ref_ref_val(&self, y: &Self, z: Self, prec: u64) -> (Self, Ordering) {
1958 self.sub_mul_prec_round_ref_ref_val(y, z, prec, Nearest)
1959 }
1960
1961 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result to the
1962 /// nearest value of the specified precision. All three [`Float`]s are taken by reference. An
1963 /// [`Ordering`] is also returned, indicating whether the rounded diff is less than, equal to,
1964 /// or greater than the exact diff. Although `NaN`s are not comparable to any [`Float`],
1965 /// whenever this function returns a `NaN` it also returns `Equal`.
1966 ///
1967 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
1968 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
1969 /// the `Nearest` rounding mode.
1970 ///
1971 /// $$
1972 /// f(x,y,z,p) = x-yz+\varepsilon.
1973 /// $$
1974 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1975 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
1976 /// |x-yz|\rfloor-p}$.
1977 ///
1978 /// If the output has a precision, it is `prec`.
1979 ///
1980 /// Special cases:
1981 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=f(x,y,\text{NaN},p)=\text{NaN}$
1982 /// - $f(x,\pm\infty,\pm0.0,p)=f(x,\pm0.0,\pm\infty,p)=\text{NaN}$
1983 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
1984 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
1985 /// - $f(\infty,y,z,p)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
1986 /// - $f(-\infty,y,z,p)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
1987 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
1988 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
1989 /// - $f(0.0,y,z,p)=0.0$ if $yz=-0.0$
1990 /// - $f(-0.0,y,z,p)=-0.0$ if $yz=0.0$
1991 /// - $f(0.0,y,z,p)=f(-0.0,y,z,p)=0.0$ if $x$ and $yz$ are zeros of the same sign
1992 /// - $f(x,y,z,p)=0.0$ if $x=yz$, $x$ is finite and nonzero,
1993 ///
1994 /// Overflow and underflow:
1995 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1996 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
1997 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1998 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1999 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
2000 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
2001 ///
2002 /// If you want to use a rounding mode other than `Nearest`, consider using
2003 /// [`Float::sub_mul_prec_round`] instead. If you know that your target precision is the maximum
2004 /// of the precisions of the inputs, consider using
2005 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
2006 ///
2007 /// # Worst-case complexity
2008 /// $T(n, m) = O(n \log n \log\log n + m)$
2009 ///
2010 /// $M(n, m) = O(n \log n + m)$
2011 ///
2012 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2013 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2014 ///
2015 /// # Panics
2016 /// Panics if `prec` is zero.
2017 ///
2018 /// # Examples
2019 /// ```
2020 /// use core::f64::consts::{E, PI, SQRT_2};
2021 /// use malachite_float::Float;
2022 /// use std::cmp::Ordering::*;
2023 ///
2024 /// let x = Float::from(PI);
2025 /// let y = Float::from(E);
2026 /// let z = Float::from(SQRT_2);
2027 ///
2028 /// let (diff, o) = x.sub_mul_prec_ref_ref_ref(&y, &z, 5);
2029 /// assert_eq!(diff.to_string(), "-0.688");
2030 /// assert_eq!(o, Greater);
2031 ///
2032 /// let (diff, o) = x.sub_mul_prec_ref_ref_ref(&y, &z, 20);
2033 /// assert_eq!(diff.to_string(), "-0.70263863");
2034 /// assert_eq!(o, Less);
2035 /// ```
2036 #[inline]
2037 pub fn sub_mul_prec_ref_ref_ref(&self, y: &Self, z: &Self, prec: u64) -> (Self, Ordering) {
2038 self.sub_mul_prec_round_ref_ref_ref(y, z, prec, Nearest)
2039 }
2040
2041 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, rounding the result to
2042 /// the nearest value of the specified precision. Both [`Float`]s on the right-hand side are
2043 /// taken by value. An [`Ordering`] is returned, indicating whether the rounded diff is less
2044 /// than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
2045 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
2046 ///
2047 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2048 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2049 /// the `Nearest` rounding mode.
2050 ///
2051 /// $$
2052 /// x \gets x-yz+\varepsilon.
2053 /// $$
2054 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2055 /// |x-yz|\rfloor-p}$.
2056 ///
2057 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
2058 /// overflow, and underflow.
2059 ///
2060 /// If you want to use a rounding mode other than `Nearest`, consider using
2061 /// [`Float::sub_mul_prec_round_assign`] instead. If you know that your target precision is the
2062 /// maximum of the precisions of the inputs, consider using
2063 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
2064 /// instead.
2065 ///
2066 /// # Worst-case complexity
2067 /// $T(n, m) = O(n \log n \log\log n + m)$
2068 ///
2069 /// $M(n, m) = O(n \log n + m)$
2070 ///
2071 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2072 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2073 ///
2074 /// # Panics
2075 /// Panics if `prec` is zero.
2076 ///
2077 /// # Examples
2078 /// ```
2079 /// use core::f64::consts::{E, PI, SQRT_2};
2080 /// use malachite_float::Float;
2081 /// use std::cmp::Ordering::*;
2082 ///
2083 /// let y = Float::from(E);
2084 /// let z = Float::from(SQRT_2);
2085 ///
2086 /// let mut x = Float::from(PI);
2087 /// assert_eq!(x.sub_mul_prec_assign(y.clone(), z.clone(), 5), Greater);
2088 /// assert_eq!(x.to_string(), "-0.688");
2089 ///
2090 /// let mut x = Float::from(PI);
2091 /// assert_eq!(x.sub_mul_prec_assign(y.clone(), z.clone(), 20), Less);
2092 /// assert_eq!(x.to_string(), "-0.70263863");
2093 /// ```
2094 #[allow(clippy::needless_pass_by_value)]
2095 #[inline]
2096 pub fn sub_mul_prec_assign(&mut self, y: Self, z: Self, prec: u64) -> Ordering {
2097 self.sub_mul_prec_round_assign(y, z, prec, Nearest)
2098 }
2099
2100 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, rounding the result to
2101 /// the nearest value of the specified precision. The first [`Float`] on the right-hand side is
2102 /// taken by value and the second by reference. An [`Ordering`] is returned, indicating whether
2103 /// the rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are
2104 /// not comparable to any [`Float`], whenever this function assigns a `NaN` it also returns
2105 /// `Equal`.
2106 ///
2107 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2108 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2109 /// the `Nearest` rounding mode.
2110 ///
2111 /// $$
2112 /// x \gets x-yz+\varepsilon.
2113 /// $$
2114 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2115 /// |x-yz|\rfloor-p}$.
2116 ///
2117 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
2118 /// overflow, and underflow.
2119 ///
2120 /// If you want to use a rounding mode other than `Nearest`, consider using
2121 /// [`Float::sub_mul_prec_round_assign`] instead. If you know that your target precision is the
2122 /// maximum of the precisions of the inputs, consider using
2123 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
2124 /// instead.
2125 ///
2126 /// # Worst-case complexity
2127 /// $T(n, m) = O(n \log n \log\log n + m)$
2128 ///
2129 /// $M(n, m) = O(n \log n + m)$
2130 ///
2131 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2132 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2133 ///
2134 /// # Panics
2135 /// Panics if `prec` is zero.
2136 ///
2137 /// # Examples
2138 /// ```
2139 /// use core::f64::consts::{E, PI, SQRT_2};
2140 /// use malachite_float::Float;
2141 /// use std::cmp::Ordering::*;
2142 ///
2143 /// let y = Float::from(E);
2144 /// let z = Float::from(SQRT_2);
2145 ///
2146 /// let mut x = Float::from(PI);
2147 /// assert_eq!(x.sub_mul_prec_assign_val_ref(y.clone(), &z, 5), Greater);
2148 /// assert_eq!(x.to_string(), "-0.688");
2149 ///
2150 /// let mut x = Float::from(PI);
2151 /// assert_eq!(x.sub_mul_prec_assign_val_ref(y.clone(), &z, 20), Less);
2152 /// assert_eq!(x.to_string(), "-0.70263863");
2153 /// ```
2154 #[allow(clippy::needless_pass_by_value)]
2155 #[inline]
2156 pub fn sub_mul_prec_assign_val_ref(&mut self, y: Self, z: &Self, prec: u64) -> Ordering {
2157 self.sub_mul_prec_round_assign_val_ref(y, z, prec, Nearest)
2158 }
2159
2160 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, rounding the result to
2161 /// the nearest value of the specified precision. The first [`Float`] on the right-hand side is
2162 /// taken by reference and the second by value. An [`Ordering`] is returned, indicating whether
2163 /// the rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are
2164 /// not comparable to any [`Float`], whenever this function assigns a `NaN` it also returns
2165 /// `Equal`.
2166 ///
2167 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2168 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2169 /// the `Nearest` rounding mode.
2170 ///
2171 /// $$
2172 /// x \gets x-yz+\varepsilon.
2173 /// $$
2174 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2175 /// |x-yz|\rfloor-p}$.
2176 ///
2177 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
2178 /// overflow, and underflow.
2179 ///
2180 /// If you want to use a rounding mode other than `Nearest`, consider using
2181 /// [`Float::sub_mul_prec_round_assign`] instead. If you know that your target precision is the
2182 /// maximum of the precisions of the inputs, consider using
2183 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
2184 /// instead.
2185 ///
2186 /// # Worst-case complexity
2187 /// $T(n, m) = O(n \log n \log\log n + m)$
2188 ///
2189 /// $M(n, m) = O(n \log n + m)$
2190 ///
2191 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2192 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2193 ///
2194 /// # Panics
2195 /// Panics if `prec` is zero.
2196 ///
2197 /// # Examples
2198 /// ```
2199 /// use core::f64::consts::{E, PI, SQRT_2};
2200 /// use malachite_float::Float;
2201 /// use std::cmp::Ordering::*;
2202 ///
2203 /// let y = Float::from(E);
2204 /// let z = Float::from(SQRT_2);
2205 ///
2206 /// let mut x = Float::from(PI);
2207 /// assert_eq!(x.sub_mul_prec_assign_ref_val(&y, z.clone(), 5), Greater);
2208 /// assert_eq!(x.to_string(), "-0.688");
2209 ///
2210 /// let mut x = Float::from(PI);
2211 /// assert_eq!(x.sub_mul_prec_assign_ref_val(&y, z.clone(), 20), Less);
2212 /// assert_eq!(x.to_string(), "-0.70263863");
2213 /// ```
2214 #[allow(clippy::needless_pass_by_value)]
2215 #[inline]
2216 pub fn sub_mul_prec_assign_ref_val(&mut self, y: &Self, z: Self, prec: u64) -> Ordering {
2217 self.sub_mul_prec_round_assign_ref_val(y, z, prec, Nearest)
2218 }
2219
2220 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, rounding the result to
2221 /// the nearest value of the specified precision. Both [`Float`]s on the right-hand side are
2222 /// taken by reference. An [`Ordering`] is returned, indicating whether the rounded diff is less
2223 /// than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
2224 /// [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
2225 ///
2226 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
2227 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
2228 /// the `Nearest` rounding mode.
2229 ///
2230 /// $$
2231 /// x \gets x-yz+\varepsilon.
2232 /// $$
2233 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
2234 /// |x-yz|\rfloor-p}$.
2235 ///
2236 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
2237 /// overflow, and underflow.
2238 ///
2239 /// If you want to use a rounding mode other than `Nearest`, consider using
2240 /// [`Float::sub_mul_prec_round_assign`] instead. If you know that your target precision is the
2241 /// maximum of the precisions of the inputs, consider using
2242 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
2243 /// instead.
2244 ///
2245 /// # Worst-case complexity
2246 /// $T(n, m) = O(n \log n \log\log n + m)$
2247 ///
2248 /// $M(n, m) = O(n \log n + m)$
2249 ///
2250 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2251 /// z.significant_bits()`, and $m$ is `max(self.significant_bits(), prec)`.
2252 ///
2253 /// # Panics
2254 /// Panics if `prec` is zero.
2255 ///
2256 /// # Examples
2257 /// ```
2258 /// use core::f64::consts::{E, PI, SQRT_2};
2259 /// use malachite_float::Float;
2260 /// use std::cmp::Ordering::*;
2261 ///
2262 /// let y = Float::from(E);
2263 /// let z = Float::from(SQRT_2);
2264 ///
2265 /// let mut x = Float::from(PI);
2266 /// assert_eq!(x.sub_mul_prec_assign_ref_ref(&y, &z, 5), Greater);
2267 /// assert_eq!(x.to_string(), "-0.688");
2268 ///
2269 /// let mut x = Float::from(PI);
2270 /// assert_eq!(x.sub_mul_prec_assign_ref_ref(&y, &z, 20), Less);
2271 /// assert_eq!(x.to_string(), "-0.70263863");
2272 /// ```
2273 #[inline]
2274 pub fn sub_mul_prec_assign_ref_ref(&mut self, y: &Self, z: &Self, prec: u64) -> Ordering {
2275 self.sub_mul_prec_round_assign_ref_ref(y, z, prec, Nearest)
2276 }
2277
2278 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result with the
2279 /// specified rounding mode. All three [`Float`]s are taken by value. An [`Ordering`] is also
2280 /// returned, indicating whether the rounded diff is less than, equal to, or greater than the
2281 /// exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
2282 /// returns a `NaN` it also returns `Equal`.
2283 ///
2284 /// The precision of the output is the maximum of the precisions of the inputs. See
2285 /// [`RoundingMode`] for a description of the possible rounding modes.
2286 ///
2287 /// $$
2288 /// f(x,y,z,m) = x-yz+\varepsilon.
2289 /// $$
2290 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2291 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2292 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
2293 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
2294 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
2295 ///
2296 /// If the output has a precision, it is the maximum of the precisions of the inputs.
2297 ///
2298 /// Special cases:
2299 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
2300 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
2301 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
2302 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
2303 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2304 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2305 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
2306 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
2307 /// - $f(0.0,y,z,m)=0.0$ if $yz=-0.0$
2308 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=0.0$
2309 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is not
2310 /// `Floor`
2311 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
2312 /// `Floor`
2313 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
2314 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
2315 ///
2316 /// Overflow and underflow:
2317 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
2318 /// returned instead.
2319 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
2320 /// is returned instead, where `p` is the precision of the output.
2321 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
2322 /// returned instead.
2323 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
2324 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
2325 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
2326 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
2327 /// instead.
2328 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
2329 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
2330 /// instead.
2331 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
2332 /// instead.
2333 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
2334 /// instead.
2335 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
2336 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
2337 /// returned instead.
2338 ///
2339 /// If you want to specify an output precision, consider using [`Float::sub_mul_prec_round`]
2340 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
2341 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
2342 ///
2343 /// # Worst-case complexity
2344 /// $T(n, m) = O(n \log n \log\log n + m)$
2345 ///
2346 /// $M(n, m) = O(n \log n + m)$
2347 ///
2348 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2349 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
2350 ///
2351 /// # Panics
2352 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
2353 /// represent the output.
2354 ///
2355 /// # Examples
2356 /// ```
2357 /// use core::f64::consts::{E, PI, SQRT_2};
2358 /// use malachite_base::rounding_modes::RoundingMode::*;
2359 /// use malachite_float::Float;
2360 /// use std::cmp::Ordering::*;
2361 ///
2362 /// let x = Float::from(PI);
2363 /// let y = Float::from(E);
2364 /// let z = Float::from(SQRT_2);
2365 ///
2366 /// let (diff, o) = x.clone().sub_mul_round(y.clone(), z.clone(), Floor);
2367 /// assert_eq!(diff.to_string(), "-0.70263837456932388");
2368 /// assert_eq!(o, Less);
2369 ///
2370 /// let (diff, o) = x.clone().sub_mul_round(y.clone(), z.clone(), Ceiling);
2371 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
2372 /// assert_eq!(o, Greater);
2373 ///
2374 /// let (diff, o) = x.clone().sub_mul_round(y.clone(), z.clone(), Nearest);
2375 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
2376 /// assert_eq!(o, Greater);
2377 /// ```
2378 #[allow(clippy::needless_pass_by_value)]
2379 #[inline]
2380 pub fn sub_mul_round(self, y: Self, z: Self, rm: RoundingMode) -> (Self, Ordering) {
2381 let prec = max!(
2382 self.significant_bits(),
2383 y.significant_bits(),
2384 z.significant_bits()
2385 );
2386 self.sub_mul_prec_round(y, z, prec, rm)
2387 }
2388
2389 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result with the
2390 /// specified rounding mode. The first two [`Float`]s are taken by value and the third by
2391 /// reference. An [`Ordering`] is also returned, indicating whether the rounded diff is less
2392 /// than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
2393 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2394 ///
2395 /// The precision of the output is the maximum of the precisions of the inputs. See
2396 /// [`RoundingMode`] for a description of the possible rounding modes.
2397 ///
2398 /// $$
2399 /// f(x,y,z,m) = x-yz+\varepsilon.
2400 /// $$
2401 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2402 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2403 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
2404 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
2405 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
2406 ///
2407 /// If the output has a precision, it is the maximum of the precisions of the inputs.
2408 ///
2409 /// Special cases:
2410 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
2411 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
2412 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
2413 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
2414 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2415 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2416 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
2417 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
2418 /// - $f(0.0,y,z,m)=0.0$ if $yz=-0.0$
2419 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=0.0$
2420 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is not
2421 /// `Floor`
2422 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
2423 /// `Floor`
2424 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
2425 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
2426 ///
2427 /// Overflow and underflow:
2428 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
2429 /// returned instead.
2430 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
2431 /// is returned instead, where `p` is the precision of the output.
2432 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
2433 /// returned instead.
2434 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
2435 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
2436 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
2437 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
2438 /// instead.
2439 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
2440 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
2441 /// instead.
2442 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
2443 /// instead.
2444 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
2445 /// instead.
2446 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
2447 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
2448 /// returned instead.
2449 ///
2450 /// If you want to specify an output precision, consider using [`Float::sub_mul_prec_round`]
2451 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
2452 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
2453 ///
2454 /// # Worst-case complexity
2455 /// $T(n, m) = O(n \log n \log\log n + m)$
2456 ///
2457 /// $M(n, m) = O(n \log n + m)$
2458 ///
2459 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2460 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
2461 ///
2462 /// # Panics
2463 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
2464 /// represent the output.
2465 ///
2466 /// # Examples
2467 /// ```
2468 /// use core::f64::consts::{E, PI, SQRT_2};
2469 /// use malachite_base::rounding_modes::RoundingMode::*;
2470 /// use malachite_float::Float;
2471 /// use std::cmp::Ordering::*;
2472 ///
2473 /// let x = Float::from(PI);
2474 /// let y = Float::from(E);
2475 /// let z = Float::from(SQRT_2);
2476 ///
2477 /// let (diff, o) = x.clone().sub_mul_round_val_val_ref(y.clone(), &z, Floor);
2478 /// assert_eq!(diff.to_string(), "-0.70263837456932388");
2479 /// assert_eq!(o, Less);
2480 ///
2481 /// let (diff, o) = x.clone().sub_mul_round_val_val_ref(y.clone(), &z, Ceiling);
2482 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
2483 /// assert_eq!(o, Greater);
2484 ///
2485 /// let (diff, o) = x.clone().sub_mul_round_val_val_ref(y.clone(), &z, Nearest);
2486 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
2487 /// assert_eq!(o, Greater);
2488 /// ```
2489 #[allow(clippy::needless_pass_by_value)]
2490 #[inline]
2491 pub fn sub_mul_round_val_val_ref(
2492 self,
2493 y: Self,
2494 z: &Self,
2495 rm: RoundingMode,
2496 ) -> (Self, Ordering) {
2497 let prec = max!(
2498 self.significant_bits(),
2499 y.significant_bits(),
2500 z.significant_bits()
2501 );
2502 self.sub_mul_prec_round_val_val_ref(y, z, prec, rm)
2503 }
2504
2505 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result with the
2506 /// specified rounding mode. The first and third [`Float`]s are taken by value and the second by
2507 /// reference. An [`Ordering`] is also returned, indicating whether the rounded diff is less
2508 /// than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
2509 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2510 ///
2511 /// The precision of the output is the maximum of the precisions of the inputs. See
2512 /// [`RoundingMode`] for a description of the possible rounding modes.
2513 ///
2514 /// $$
2515 /// f(x,y,z,m) = x-yz+\varepsilon.
2516 /// $$
2517 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2518 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2519 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
2520 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
2521 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
2522 ///
2523 /// If the output has a precision, it is the maximum of the precisions of the inputs.
2524 ///
2525 /// Special cases:
2526 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
2527 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
2528 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
2529 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
2530 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2531 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2532 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
2533 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
2534 /// - $f(0.0,y,z,m)=0.0$ if $yz=-0.0$
2535 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=0.0$
2536 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is not
2537 /// `Floor`
2538 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
2539 /// `Floor`
2540 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
2541 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
2542 ///
2543 /// Overflow and underflow:
2544 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
2545 /// returned instead.
2546 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
2547 /// is returned instead, where `p` is the precision of the output.
2548 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
2549 /// returned instead.
2550 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
2551 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
2552 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
2553 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
2554 /// instead.
2555 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
2556 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
2557 /// instead.
2558 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
2559 /// instead.
2560 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
2561 /// instead.
2562 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
2563 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
2564 /// returned instead.
2565 ///
2566 /// If you want to specify an output precision, consider using [`Float::sub_mul_prec_round`]
2567 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
2568 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
2569 ///
2570 /// # Worst-case complexity
2571 /// $T(n, m) = O(n \log n \log\log n + m)$
2572 ///
2573 /// $M(n, m) = O(n \log n + m)$
2574 ///
2575 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2576 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
2577 ///
2578 /// # Panics
2579 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
2580 /// represent the output.
2581 ///
2582 /// # Examples
2583 /// ```
2584 /// use core::f64::consts::{E, PI, SQRT_2};
2585 /// use malachite_base::rounding_modes::RoundingMode::*;
2586 /// use malachite_float::Float;
2587 /// use std::cmp::Ordering::*;
2588 ///
2589 /// let x = Float::from(PI);
2590 /// let y = Float::from(E);
2591 /// let z = Float::from(SQRT_2);
2592 ///
2593 /// let (diff, o) = x.clone().sub_mul_round_val_ref_val(&y, z.clone(), Floor);
2594 /// assert_eq!(diff.to_string(), "-0.70263837456932388");
2595 /// assert_eq!(o, Less);
2596 ///
2597 /// let (diff, o) = x.clone().sub_mul_round_val_ref_val(&y, z.clone(), Ceiling);
2598 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
2599 /// assert_eq!(o, Greater);
2600 ///
2601 /// let (diff, o) = x.clone().sub_mul_round_val_ref_val(&y, z.clone(), Nearest);
2602 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
2603 /// assert_eq!(o, Greater);
2604 /// ```
2605 #[allow(clippy::needless_pass_by_value)]
2606 #[inline]
2607 pub fn sub_mul_round_val_ref_val(
2608 self,
2609 y: &Self,
2610 z: Self,
2611 rm: RoundingMode,
2612 ) -> (Self, Ordering) {
2613 let prec = max!(
2614 self.significant_bits(),
2615 y.significant_bits(),
2616 z.significant_bits()
2617 );
2618 self.sub_mul_prec_round_val_ref_val(y, z, prec, rm)
2619 }
2620
2621 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result with the
2622 /// specified rounding mode. The first [`Float`] is taken by value and the second and third by
2623 /// reference. An [`Ordering`] is also returned, indicating whether the rounded diff is less
2624 /// than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
2625 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2626 ///
2627 /// The precision of the output is the maximum of the precisions of the inputs. See
2628 /// [`RoundingMode`] for a description of the possible rounding modes.
2629 ///
2630 /// $$
2631 /// f(x,y,z,m) = x-yz+\varepsilon.
2632 /// $$
2633 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2634 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2635 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
2636 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
2637 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
2638 ///
2639 /// If the output has a precision, it is the maximum of the precisions of the inputs.
2640 ///
2641 /// Special cases:
2642 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
2643 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
2644 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
2645 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
2646 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2647 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2648 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
2649 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
2650 /// - $f(0.0,y,z,m)=0.0$ if $yz=-0.0$
2651 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=0.0$
2652 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is not
2653 /// `Floor`
2654 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
2655 /// `Floor`
2656 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
2657 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
2658 ///
2659 /// Overflow and underflow:
2660 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
2661 /// returned instead.
2662 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
2663 /// is returned instead, where `p` is the precision of the output.
2664 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
2665 /// returned instead.
2666 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
2667 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
2668 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
2669 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
2670 /// instead.
2671 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
2672 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
2673 /// instead.
2674 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
2675 /// instead.
2676 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
2677 /// instead.
2678 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
2679 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
2680 /// returned instead.
2681 ///
2682 /// If you want to specify an output precision, consider using [`Float::sub_mul_prec_round`]
2683 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
2684 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
2685 ///
2686 /// # Worst-case complexity
2687 /// $T(n, m) = O(n \log n \log\log n + m)$
2688 ///
2689 /// $M(n, m) = O(n \log n + m)$
2690 ///
2691 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2692 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
2693 ///
2694 /// # Panics
2695 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
2696 /// represent the output.
2697 ///
2698 /// # Examples
2699 /// ```
2700 /// use core::f64::consts::{E, PI, SQRT_2};
2701 /// use malachite_base::rounding_modes::RoundingMode::*;
2702 /// use malachite_float::Float;
2703 /// use std::cmp::Ordering::*;
2704 ///
2705 /// let x = Float::from(PI);
2706 /// let y = Float::from(E);
2707 /// let z = Float::from(SQRT_2);
2708 ///
2709 /// let (diff, o) = x.clone().sub_mul_round_val_ref_ref(&y, &z, Floor);
2710 /// assert_eq!(diff.to_string(), "-0.70263837456932388");
2711 /// assert_eq!(o, Less);
2712 ///
2713 /// let (diff, o) = x.clone().sub_mul_round_val_ref_ref(&y, &z, Ceiling);
2714 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
2715 /// assert_eq!(o, Greater);
2716 ///
2717 /// let (diff, o) = x.clone().sub_mul_round_val_ref_ref(&y, &z, Nearest);
2718 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
2719 /// assert_eq!(o, Greater);
2720 /// ```
2721 #[inline]
2722 pub fn sub_mul_round_val_ref_ref(
2723 self,
2724 y: &Self,
2725 z: &Self,
2726 rm: RoundingMode,
2727 ) -> (Self, Ordering) {
2728 let prec = max!(
2729 self.significant_bits(),
2730 y.significant_bits(),
2731 z.significant_bits()
2732 );
2733 self.sub_mul_prec_round_val_ref_ref(y, z, prec, rm)
2734 }
2735
2736 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result with the
2737 /// specified rounding mode. The first [`Float`] is taken by reference and the second and third
2738 /// by value. An [`Ordering`] is also returned, indicating whether the rounded diff is less
2739 /// than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
2740 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2741 ///
2742 /// The precision of the output is the maximum of the precisions of the inputs. See
2743 /// [`RoundingMode`] for a description of the possible rounding modes.
2744 ///
2745 /// $$
2746 /// f(x,y,z,m) = x-yz+\varepsilon.
2747 /// $$
2748 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2749 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2750 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
2751 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
2752 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
2753 ///
2754 /// If the output has a precision, it is the maximum of the precisions of the inputs.
2755 ///
2756 /// Special cases:
2757 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
2758 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
2759 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
2760 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
2761 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2762 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2763 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
2764 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
2765 /// - $f(0.0,y,z,m)=0.0$ if $yz=-0.0$
2766 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=0.0$
2767 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is not
2768 /// `Floor`
2769 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
2770 /// `Floor`
2771 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
2772 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
2773 ///
2774 /// Overflow and underflow:
2775 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
2776 /// returned instead.
2777 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
2778 /// is returned instead, where `p` is the precision of the output.
2779 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
2780 /// returned instead.
2781 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
2782 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
2783 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
2784 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
2785 /// instead.
2786 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
2787 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
2788 /// instead.
2789 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
2790 /// instead.
2791 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
2792 /// instead.
2793 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
2794 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
2795 /// returned instead.
2796 ///
2797 /// If you want to specify an output precision, consider using [`Float::sub_mul_prec_round`]
2798 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
2799 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
2800 ///
2801 /// # Worst-case complexity
2802 /// $T(n, m) = O(n \log n \log\log n + m)$
2803 ///
2804 /// $M(n, m) = O(n \log n + m)$
2805 ///
2806 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2807 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
2808 ///
2809 /// # Panics
2810 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
2811 /// represent the output.
2812 ///
2813 /// # Examples
2814 /// ```
2815 /// use core::f64::consts::{E, PI, SQRT_2};
2816 /// use malachite_base::rounding_modes::RoundingMode::*;
2817 /// use malachite_float::Float;
2818 /// use std::cmp::Ordering::*;
2819 ///
2820 /// let x = Float::from(PI);
2821 /// let y = Float::from(E);
2822 /// let z = Float::from(SQRT_2);
2823 ///
2824 /// let (diff, o) = x.sub_mul_round_ref_val_val(y.clone(), z.clone(), Floor);
2825 /// assert_eq!(diff.to_string(), "-0.70263837456932388");
2826 /// assert_eq!(o, Less);
2827 ///
2828 /// let (diff, o) = x.sub_mul_round_ref_val_val(y.clone(), z.clone(), Ceiling);
2829 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
2830 /// assert_eq!(o, Greater);
2831 ///
2832 /// let (diff, o) = x.sub_mul_round_ref_val_val(y.clone(), z.clone(), Nearest);
2833 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
2834 /// assert_eq!(o, Greater);
2835 /// ```
2836 #[allow(clippy::needless_pass_by_value)]
2837 #[inline]
2838 pub fn sub_mul_round_ref_val_val(
2839 &self,
2840 y: Self,
2841 z: Self,
2842 rm: RoundingMode,
2843 ) -> (Self, Ordering) {
2844 let prec = max!(
2845 self.significant_bits(),
2846 y.significant_bits(),
2847 z.significant_bits()
2848 );
2849 self.sub_mul_prec_round_ref_val_val(y, z, prec, rm)
2850 }
2851
2852 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result with the
2853 /// specified rounding mode. The first and third [`Float`]s are taken by reference and the
2854 /// second by value. An [`Ordering`] is also returned, indicating whether the rounded diff is
2855 /// less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to
2856 /// any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2857 ///
2858 /// The precision of the output is the maximum of the precisions of the inputs. See
2859 /// [`RoundingMode`] for a description of the possible rounding modes.
2860 ///
2861 /// $$
2862 /// f(x,y,z,m) = x-yz+\varepsilon.
2863 /// $$
2864 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2865 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2866 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
2867 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
2868 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
2869 ///
2870 /// If the output has a precision, it is the maximum of the precisions of the inputs.
2871 ///
2872 /// Special cases:
2873 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
2874 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
2875 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
2876 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
2877 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2878 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2879 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
2880 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
2881 /// - $f(0.0,y,z,m)=0.0$ if $yz=-0.0$
2882 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=0.0$
2883 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is not
2884 /// `Floor`
2885 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
2886 /// `Floor`
2887 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
2888 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
2889 ///
2890 /// Overflow and underflow:
2891 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
2892 /// returned instead.
2893 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
2894 /// is returned instead, where `p` is the precision of the output.
2895 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
2896 /// returned instead.
2897 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
2898 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
2899 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
2900 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
2901 /// instead.
2902 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
2903 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
2904 /// instead.
2905 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
2906 /// instead.
2907 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
2908 /// instead.
2909 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
2910 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
2911 /// returned instead.
2912 ///
2913 /// If you want to specify an output precision, consider using [`Float::sub_mul_prec_round`]
2914 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
2915 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
2916 ///
2917 /// # Worst-case complexity
2918 /// $T(n, m) = O(n \log n \log\log n + m)$
2919 ///
2920 /// $M(n, m) = O(n \log n + m)$
2921 ///
2922 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
2923 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
2924 ///
2925 /// # Panics
2926 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
2927 /// represent the output.
2928 ///
2929 /// # Examples
2930 /// ```
2931 /// use core::f64::consts::{E, PI, SQRT_2};
2932 /// use malachite_base::rounding_modes::RoundingMode::*;
2933 /// use malachite_float::Float;
2934 /// use std::cmp::Ordering::*;
2935 ///
2936 /// let x = Float::from(PI);
2937 /// let y = Float::from(E);
2938 /// let z = Float::from(SQRT_2);
2939 ///
2940 /// let (diff, o) = x.sub_mul_round_ref_val_ref(y.clone(), &z, Floor);
2941 /// assert_eq!(diff.to_string(), "-0.70263837456932388");
2942 /// assert_eq!(o, Less);
2943 ///
2944 /// let (diff, o) = x.sub_mul_round_ref_val_ref(y.clone(), &z, Ceiling);
2945 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
2946 /// assert_eq!(o, Greater);
2947 ///
2948 /// let (diff, o) = x.sub_mul_round_ref_val_ref(y.clone(), &z, Nearest);
2949 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
2950 /// assert_eq!(o, Greater);
2951 /// ```
2952 #[allow(clippy::needless_pass_by_value)]
2953 #[inline]
2954 pub fn sub_mul_round_ref_val_ref(
2955 &self,
2956 y: Self,
2957 z: &Self,
2958 rm: RoundingMode,
2959 ) -> (Self, Ordering) {
2960 let prec = max!(
2961 self.significant_bits(),
2962 y.significant_bits(),
2963 z.significant_bits()
2964 );
2965 self.sub_mul_prec_round_ref_val_ref(y, z, prec, rm)
2966 }
2967
2968 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result with the
2969 /// specified rounding mode. The first two [`Float`]s are taken by reference and the third by
2970 /// value. An [`Ordering`] is also returned, indicating whether the rounded diff is less than,
2971 /// equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
2972 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2973 ///
2974 /// The precision of the output is the maximum of the precisions of the inputs. See
2975 /// [`RoundingMode`] for a description of the possible rounding modes.
2976 ///
2977 /// $$
2978 /// f(x,y,z,m) = x-yz+\varepsilon.
2979 /// $$
2980 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2981 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2982 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
2983 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
2984 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
2985 ///
2986 /// If the output has a precision, it is the maximum of the precisions of the inputs.
2987 ///
2988 /// Special cases:
2989 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
2990 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
2991 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
2992 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
2993 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
2994 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
2995 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
2996 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
2997 /// - $f(0.0,y,z,m)=0.0$ if $yz=-0.0$
2998 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=0.0$
2999 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is not
3000 /// `Floor`
3001 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
3002 /// `Floor`
3003 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
3004 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
3005 ///
3006 /// Overflow and underflow:
3007 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3008 /// returned instead.
3009 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
3010 /// is returned instead, where `p` is the precision of the output.
3011 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3012 /// returned instead.
3013 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3014 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3015 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3016 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3017 /// instead.
3018 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3019 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
3020 /// instead.
3021 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3022 /// instead.
3023 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3024 /// instead.
3025 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3026 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3027 /// returned instead.
3028 ///
3029 /// If you want to specify an output precision, consider using [`Float::sub_mul_prec_round`]
3030 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3031 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
3032 ///
3033 /// # Worst-case complexity
3034 /// $T(n, m) = O(n \log n \log\log n + m)$
3035 ///
3036 /// $M(n, m) = O(n \log n + m)$
3037 ///
3038 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3039 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3040 ///
3041 /// # Panics
3042 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3043 /// represent the output.
3044 ///
3045 /// # Examples
3046 /// ```
3047 /// use core::f64::consts::{E, PI, SQRT_2};
3048 /// use malachite_base::rounding_modes::RoundingMode::*;
3049 /// use malachite_float::Float;
3050 /// use std::cmp::Ordering::*;
3051 ///
3052 /// let x = Float::from(PI);
3053 /// let y = Float::from(E);
3054 /// let z = Float::from(SQRT_2);
3055 ///
3056 /// let (diff, o) = x.sub_mul_round_ref_ref_val(&y, z.clone(), Floor);
3057 /// assert_eq!(diff.to_string(), "-0.70263837456932388");
3058 /// assert_eq!(o, Less);
3059 ///
3060 /// let (diff, o) = x.sub_mul_round_ref_ref_val(&y, z.clone(), Ceiling);
3061 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
3062 /// assert_eq!(o, Greater);
3063 ///
3064 /// let (diff, o) = x.sub_mul_round_ref_ref_val(&y, z.clone(), Nearest);
3065 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
3066 /// assert_eq!(o, Greater);
3067 /// ```
3068 #[allow(clippy::needless_pass_by_value)]
3069 #[inline]
3070 pub fn sub_mul_round_ref_ref_val(
3071 &self,
3072 y: &Self,
3073 z: Self,
3074 rm: RoundingMode,
3075 ) -> (Self, Ordering) {
3076 let prec = max!(
3077 self.significant_bits(),
3078 y.significant_bits(),
3079 z.significant_bits()
3080 );
3081 self.sub_mul_prec_round_ref_ref_val(y, z, prec, rm)
3082 }
3083
3084 /// Subtracts the product of two other [`Float`]s from a [`Float`], rounding the result with the
3085 /// specified rounding mode. All three [`Float`]s are taken by reference. An [`Ordering`] is
3086 /// also returned, indicating whether the rounded diff is less than, equal to, or greater than
3087 /// the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
3088 /// returns a `NaN` it also returns `Equal`.
3089 ///
3090 /// The precision of the output is the maximum of the precisions of the inputs. See
3091 /// [`RoundingMode`] for a description of the possible rounding modes.
3092 ///
3093 /// $$
3094 /// f(x,y,z,m) = x-yz+\varepsilon.
3095 /// $$
3096 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3097 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3098 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3099 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3100 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3101 ///
3102 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3103 ///
3104 /// Special cases:
3105 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=f(x,y,\text{NaN},m)=\text{NaN}$
3106 /// - $f(x,\pm\infty,\pm0.0,m)=f(x,\pm0.0,\pm\infty,m)=\text{NaN}$
3107 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
3108 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
3109 /// - $f(\infty,y,z,m)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
3110 /// - $f(-\infty,y,z,m)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
3111 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
3112 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
3113 /// - $f(0.0,y,z,m)=0.0$ if $yz=-0.0$
3114 /// - $f(-0.0,y,z,m)=-0.0$ if $yz=0.0$
3115 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is not
3116 /// `Floor`
3117 /// - $f(0.0,y,z,m)=f(-0.0,y,z,m)=-0.0$ if $x$ and $yz$ are zeros of the same sign and $m$ is
3118 /// `Floor`
3119 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
3120 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
3121 ///
3122 /// Overflow and underflow:
3123 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
3124 /// returned instead.
3125 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
3126 /// is returned instead, where `p` is the precision of the output.
3127 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
3128 /// returned instead.
3129 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
3130 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
3131 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
3132 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
3133 /// instead.
3134 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
3135 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
3136 /// instead.
3137 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
3138 /// instead.
3139 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
3140 /// instead.
3141 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
3142 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
3143 /// returned instead.
3144 ///
3145 /// If you want to specify an output precision, consider using [`Float::sub_mul_prec_round`]
3146 /// instead. If you know you'll be using the `Nearest` rounding mode, consider using
3147 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
3148 ///
3149 /// # Worst-case complexity
3150 /// $T(n, m) = O(n \log n \log\log n + m)$
3151 ///
3152 /// $M(n, m) = O(n \log n + m)$
3153 ///
3154 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3155 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3156 ///
3157 /// # Panics
3158 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3159 /// represent the output.
3160 ///
3161 /// # Examples
3162 /// ```
3163 /// use core::f64::consts::{E, PI, SQRT_2};
3164 /// use malachite_base::rounding_modes::RoundingMode::*;
3165 /// use malachite_float::Float;
3166 /// use std::cmp::Ordering::*;
3167 ///
3168 /// let x = Float::from(PI);
3169 /// let y = Float::from(E);
3170 /// let z = Float::from(SQRT_2);
3171 ///
3172 /// let (diff, o) = x.sub_mul_round_ref_ref_ref(&y, &z, Floor);
3173 /// assert_eq!(diff.to_string(), "-0.70263837456932388");
3174 /// assert_eq!(o, Less);
3175 ///
3176 /// let (diff, o) = x.sub_mul_round_ref_ref_ref(&y, &z, Ceiling);
3177 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
3178 /// assert_eq!(o, Greater);
3179 ///
3180 /// let (diff, o) = x.sub_mul_round_ref_ref_ref(&y, &z, Nearest);
3181 /// assert_eq!(diff.to_string(), "-0.70263837456932376");
3182 /// assert_eq!(o, Greater);
3183 /// ```
3184 #[inline]
3185 pub fn sub_mul_round_ref_ref_ref(
3186 &self,
3187 y: &Self,
3188 z: &Self,
3189 rm: RoundingMode,
3190 ) -> (Self, Ordering) {
3191 let prec = max!(
3192 self.significant_bits(),
3193 y.significant_bits(),
3194 z.significant_bits()
3195 );
3196 self.sub_mul_prec_round_ref_ref_ref(y, z, prec, rm)
3197 }
3198
3199 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, rounding the result with
3200 /// the specified rounding mode. Both [`Float`]s on the right-hand side are taken by value. An
3201 /// [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
3202 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
3203 /// this function assigns a `NaN` it also returns `Equal`.
3204 ///
3205 /// The precision of the output is the maximum of the precisions of the inputs. See
3206 /// [`RoundingMode`] for a description of the possible rounding modes.
3207 ///
3208 /// $$
3209 /// x \gets x-yz+\varepsilon.
3210 /// $$
3211 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3212 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3213 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3214 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3215 ///
3216 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
3217 /// overflow, and underflow.
3218 ///
3219 /// If you want to specify an output precision, consider using
3220 /// [`Float::sub_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
3221 /// rounding mode, consider using
3222 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
3223 /// instead.
3224 ///
3225 /// # Worst-case complexity
3226 /// $T(n, m) = O(n \log n \log\log n + m)$
3227 ///
3228 /// $M(n, m) = O(n \log n + m)$
3229 ///
3230 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3231 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3232 ///
3233 /// # Panics
3234 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3235 /// represent the output.
3236 ///
3237 /// # Examples
3238 /// ```
3239 /// use core::f64::consts::{E, PI, SQRT_2};
3240 /// use malachite_base::rounding_modes::RoundingMode::*;
3241 /// use malachite_float::Float;
3242 /// use std::cmp::Ordering::*;
3243 ///
3244 /// let y = Float::from(E);
3245 /// let z = Float::from(SQRT_2);
3246 ///
3247 /// let mut x = Float::from(PI);
3248 /// assert_eq!(x.sub_mul_round_assign(y.clone(), z.clone(), Floor), Less);
3249 /// assert_eq!(x.to_string(), "-0.70263837456932388");
3250 ///
3251 /// let mut x = Float::from(PI);
3252 /// assert_eq!(
3253 /// x.sub_mul_round_assign(y.clone(), z.clone(), Ceiling),
3254 /// Greater
3255 /// );
3256 /// assert_eq!(x.to_string(), "-0.70263837456932376");
3257 ///
3258 /// let mut x = Float::from(PI);
3259 /// assert_eq!(
3260 /// x.sub_mul_round_assign(y.clone(), z.clone(), Nearest),
3261 /// Greater
3262 /// );
3263 /// assert_eq!(x.to_string(), "-0.70263837456932376");
3264 /// ```
3265 #[allow(clippy::needless_pass_by_value)]
3266 #[inline]
3267 pub fn sub_mul_round_assign(&mut self, y: Self, z: Self, rm: RoundingMode) -> Ordering {
3268 let prec = max!(
3269 self.significant_bits(),
3270 y.significant_bits(),
3271 z.significant_bits()
3272 );
3273 self.sub_mul_prec_round_assign(y, z, prec, rm)
3274 }
3275
3276 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, rounding the result with
3277 /// the specified rounding mode. The first [`Float`] on the right-hand side is taken by value
3278 /// and the second by reference. An [`Ordering`] is returned, indicating whether the rounded
3279 /// diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
3280 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
3281 ///
3282 /// The precision of the output is the maximum of the precisions of the inputs. See
3283 /// [`RoundingMode`] for a description of the possible rounding modes.
3284 ///
3285 /// $$
3286 /// x \gets x-yz+\varepsilon.
3287 /// $$
3288 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3289 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3290 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3291 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3292 ///
3293 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
3294 /// overflow, and underflow.
3295 ///
3296 /// If you want to specify an output precision, consider using
3297 /// [`Float::sub_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
3298 /// rounding mode, consider using
3299 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
3300 /// instead.
3301 ///
3302 /// # Worst-case complexity
3303 /// $T(n, m) = O(n \log n \log\log n + m)$
3304 ///
3305 /// $M(n, m) = O(n \log n + m)$
3306 ///
3307 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3308 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3309 ///
3310 /// # Panics
3311 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3312 /// represent the output.
3313 ///
3314 /// # Examples
3315 /// ```
3316 /// use core::f64::consts::{E, PI, SQRT_2};
3317 /// use malachite_base::rounding_modes::RoundingMode::*;
3318 /// use malachite_float::Float;
3319 /// use std::cmp::Ordering::*;
3320 ///
3321 /// let y = Float::from(E);
3322 /// let z = Float::from(SQRT_2);
3323 ///
3324 /// let mut x = Float::from(PI);
3325 /// assert_eq!(x.sub_mul_round_assign_val_ref(y.clone(), &z, Floor), Less);
3326 /// assert_eq!(x.to_string(), "-0.70263837456932388");
3327 ///
3328 /// let mut x = Float::from(PI);
3329 /// assert_eq!(
3330 /// x.sub_mul_round_assign_val_ref(y.clone(), &z, Ceiling),
3331 /// Greater
3332 /// );
3333 /// assert_eq!(x.to_string(), "-0.70263837456932376");
3334 ///
3335 /// let mut x = Float::from(PI);
3336 /// assert_eq!(
3337 /// x.sub_mul_round_assign_val_ref(y.clone(), &z, Nearest),
3338 /// Greater
3339 /// );
3340 /// assert_eq!(x.to_string(), "-0.70263837456932376");
3341 /// ```
3342 #[allow(clippy::needless_pass_by_value)]
3343 #[inline]
3344 pub fn sub_mul_round_assign_val_ref(
3345 &mut self,
3346 y: Self,
3347 z: &Self,
3348 rm: RoundingMode,
3349 ) -> Ordering {
3350 let prec = max!(
3351 self.significant_bits(),
3352 y.significant_bits(),
3353 z.significant_bits()
3354 );
3355 self.sub_mul_prec_round_assign_val_ref(y, z, prec, rm)
3356 }
3357
3358 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, rounding the result with
3359 /// the specified rounding mode. The first [`Float`] on the right-hand side is taken by
3360 /// reference and the second by value. An [`Ordering`] is returned, indicating whether the
3361 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
3362 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
3363 ///
3364 /// The precision of the output is the maximum of the precisions of the inputs. See
3365 /// [`RoundingMode`] for a description of the possible rounding modes.
3366 ///
3367 /// $$
3368 /// x \gets x-yz+\varepsilon.
3369 /// $$
3370 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3371 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3372 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3373 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3374 ///
3375 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
3376 /// overflow, and underflow.
3377 ///
3378 /// If you want to specify an output precision, consider using
3379 /// [`Float::sub_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
3380 /// rounding mode, consider using
3381 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
3382 /// instead.
3383 ///
3384 /// # Worst-case complexity
3385 /// $T(n, m) = O(n \log n \log\log n + m)$
3386 ///
3387 /// $M(n, m) = O(n \log n + m)$
3388 ///
3389 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3390 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3391 ///
3392 /// # Panics
3393 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3394 /// represent the output.
3395 ///
3396 /// # Examples
3397 /// ```
3398 /// use core::f64::consts::{E, PI, SQRT_2};
3399 /// use malachite_base::rounding_modes::RoundingMode::*;
3400 /// use malachite_float::Float;
3401 /// use std::cmp::Ordering::*;
3402 ///
3403 /// let y = Float::from(E);
3404 /// let z = Float::from(SQRT_2);
3405 ///
3406 /// let mut x = Float::from(PI);
3407 /// assert_eq!(x.sub_mul_round_assign_ref_val(&y, z.clone(), Floor), Less);
3408 /// assert_eq!(x.to_string(), "-0.70263837456932388");
3409 ///
3410 /// let mut x = Float::from(PI);
3411 /// assert_eq!(
3412 /// x.sub_mul_round_assign_ref_val(&y, z.clone(), Ceiling),
3413 /// Greater
3414 /// );
3415 /// assert_eq!(x.to_string(), "-0.70263837456932376");
3416 ///
3417 /// let mut x = Float::from(PI);
3418 /// assert_eq!(
3419 /// x.sub_mul_round_assign_ref_val(&y, z.clone(), Nearest),
3420 /// Greater
3421 /// );
3422 /// assert_eq!(x.to_string(), "-0.70263837456932376");
3423 /// ```
3424 #[allow(clippy::needless_pass_by_value)]
3425 #[inline]
3426 pub fn sub_mul_round_assign_ref_val(
3427 &mut self,
3428 y: &Self,
3429 z: Self,
3430 rm: RoundingMode,
3431 ) -> Ordering {
3432 let prec = max!(
3433 self.significant_bits(),
3434 y.significant_bits(),
3435 z.significant_bits()
3436 );
3437 self.sub_mul_prec_round_assign_ref_val(y, z, prec, rm)
3438 }
3439
3440 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, rounding the result with
3441 /// the specified rounding mode. Both [`Float`]s on the right-hand side are taken by reference.
3442 /// An [`Ordering`] is returned, indicating whether the rounded diff is less than, equal to, or
3443 /// greater than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever
3444 /// this function assigns a `NaN` it also returns `Equal`.
3445 ///
3446 /// The precision of the output is the maximum of the precisions of the inputs. See
3447 /// [`RoundingMode`] for a description of the possible rounding modes.
3448 ///
3449 /// $$
3450 /// x \gets x-yz+\varepsilon.
3451 /// $$
3452 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3453 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
3454 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
3455 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3456 ///
3457 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
3458 /// overflow, and underflow.
3459 ///
3460 /// If you want to specify an output precision, consider using
3461 /// [`Float::sub_mul_prec_round_assign`] instead. If you know you'll be using the `Nearest`
3462 /// rounding mode, consider using
3463 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
3464 /// instead.
3465 ///
3466 /// # Worst-case complexity
3467 /// $T(n, m) = O(n \log n \log\log n + m)$
3468 ///
3469 /// $M(n, m) = O(n \log n + m)$
3470 ///
3471 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3472 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3473 ///
3474 /// # Panics
3475 /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
3476 /// represent the output.
3477 ///
3478 /// # Examples
3479 /// ```
3480 /// use core::f64::consts::{E, PI, SQRT_2};
3481 /// use malachite_base::rounding_modes::RoundingMode::*;
3482 /// use malachite_float::Float;
3483 /// use std::cmp::Ordering::*;
3484 ///
3485 /// let y = Float::from(E);
3486 /// let z = Float::from(SQRT_2);
3487 ///
3488 /// let mut x = Float::from(PI);
3489 /// assert_eq!(x.sub_mul_round_assign_ref_ref(&y, &z, Floor), Less);
3490 /// assert_eq!(x.to_string(), "-0.70263837456932388");
3491 ///
3492 /// let mut x = Float::from(PI);
3493 /// assert_eq!(x.sub_mul_round_assign_ref_ref(&y, &z, Ceiling), Greater);
3494 /// assert_eq!(x.to_string(), "-0.70263837456932376");
3495 ///
3496 /// let mut x = Float::from(PI);
3497 /// assert_eq!(x.sub_mul_round_assign_ref_ref(&y, &z, Nearest), Greater);
3498 /// assert_eq!(x.to_string(), "-0.70263837456932376");
3499 /// ```
3500 #[inline]
3501 pub fn sub_mul_round_assign_ref_ref(
3502 &mut self,
3503 y: &Self,
3504 z: &Self,
3505 rm: RoundingMode,
3506 ) -> Ordering {
3507 let prec = max!(
3508 self.significant_bits(),
3509 y.significant_bits(),
3510 z.significant_bits()
3511 );
3512 self.sub_mul_prec_round_assign_ref_ref(y, z, prec, rm)
3513 }
3514}
3515
3516impl SubMul<Self, Self> for Float {
3517 type Output = Self;
3518 /// Subtracts the product of two other [`Float`]s from a [`Float`], taking all three by value.
3519 ///
3520 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
3521 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
3522 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
3523 /// `Nearest` rounding mode.
3524 ///
3525 /// $$
3526 /// f(x,y,z) = x-yz+\varepsilon.
3527 /// $$
3528 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3529 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3530 ///
3531 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3532 ///
3533 /// Special cases:
3534 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
3535 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
3536 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
3537 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
3538 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
3539 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
3540 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
3541 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
3542 /// - $f(0.0,y,z)=0.0$ if $yz=-0.0$
3543 /// - $f(-0.0,y,z)=-0.0$ if $yz=0.0$
3544 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of the same sign
3545 /// - $f(x,y,z)=0.0$ if $x=yz$, $x$ is finite and nonzero,
3546 ///
3547 /// Overflow and underflow:
3548 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
3549 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
3550 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
3551 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
3552 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
3553 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
3554 ///
3555 /// If you want to use a rounding mode other than `Nearest`, consider using
3556 /// [`Float::sub_mul_round`]. If you want to specify the output precision, consider using
3557 /// [`Float::sub_mul_prec`]. If you want both of these things, consider using
3558 /// [`Float::sub_mul_prec_round`].
3559 ///
3560 /// # Worst-case complexity
3561 /// $T(n, m) = O(n \log n \log\log n + m)$
3562 ///
3563 /// $M(n, m) = O(n \log n + m)$
3564 ///
3565 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3566 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3567 ///
3568 /// # Examples
3569 /// ```
3570 /// use core::f64::consts::{E, PI, SQRT_2};
3571 /// use malachite_base::num::arithmetic::traits::SubMul;
3572 /// use malachite_float::Float;
3573 ///
3574 /// let x = Float::from(PI);
3575 /// let y = Float::from(E);
3576 /// let z = Float::from(SQRT_2);
3577 /// assert_eq!(x.sub_mul(y, z).to_string(), "-0.70263837456932376");
3578 /// ```
3579 #[inline]
3580 fn sub_mul(self, y: Self, z: Self) -> Self {
3581 let prec = max!(
3582 self.significant_bits(),
3583 y.significant_bits(),
3584 z.significant_bits()
3585 );
3586 self.sub_mul_prec(y, z, prec).0
3587 }
3588}
3589
3590impl SubMul<Self, &Self> for Float {
3591 type Output = Self;
3592 /// Subtracts the product of two other [`Float`]s from a [`Float`], taking the first two by
3593 /// value and the third by reference.
3594 ///
3595 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
3596 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
3597 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
3598 /// `Nearest` rounding mode.
3599 ///
3600 /// $$
3601 /// f(x,y,z) = x-yz+\varepsilon.
3602 /// $$
3603 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3604 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3605 ///
3606 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3607 ///
3608 /// Special cases:
3609 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
3610 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
3611 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
3612 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
3613 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
3614 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
3615 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
3616 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
3617 /// - $f(0.0,y,z)=0.0$ if $yz=-0.0$
3618 /// - $f(-0.0,y,z)=-0.0$ if $yz=0.0$
3619 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of the same sign
3620 /// - $f(x,y,z)=0.0$ if $x=yz$, $x$ is finite and nonzero,
3621 ///
3622 /// Overflow and underflow:
3623 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
3624 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
3625 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
3626 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
3627 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
3628 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
3629 ///
3630 /// If you want to use a rounding mode other than `Nearest`, consider using
3631 /// [`Float::sub_mul_round`]. If you want to specify the output precision, consider using
3632 /// [`Float::sub_mul_prec`]. If you want both of these things, consider using
3633 /// [`Float::sub_mul_prec_round`].
3634 ///
3635 /// # Worst-case complexity
3636 /// $T(n, m) = O(n \log n \log\log n + m)$
3637 ///
3638 /// $M(n, m) = O(n \log n + m)$
3639 ///
3640 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3641 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3642 ///
3643 /// # Examples
3644 /// ```
3645 /// use core::f64::consts::{E, PI, SQRT_2};
3646 /// use malachite_base::num::arithmetic::traits::SubMul;
3647 /// use malachite_float::Float;
3648 ///
3649 /// let x = Float::from(PI);
3650 /// let y = Float::from(E);
3651 /// let z = Float::from(SQRT_2);
3652 /// assert_eq!(x.sub_mul(y, &z).to_string(), "-0.70263837456932376");
3653 /// ```
3654 #[inline]
3655 fn sub_mul(self, y: Self, z: &Self) -> Self {
3656 let prec = max!(
3657 self.significant_bits(),
3658 y.significant_bits(),
3659 z.significant_bits()
3660 );
3661 self.sub_mul_prec_val_val_ref(y, z, prec).0
3662 }
3663}
3664
3665impl SubMul<&Self, Self> for Float {
3666 type Output = Self;
3667 /// Subtracts the product of two other [`Float`]s from a [`Float`], taking the first and third
3668 /// by value and the second by reference.
3669 ///
3670 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
3671 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
3672 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
3673 /// `Nearest` rounding mode.
3674 ///
3675 /// $$
3676 /// f(x,y,z) = x-yz+\varepsilon.
3677 /// $$
3678 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3679 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3680 ///
3681 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3682 ///
3683 /// Special cases:
3684 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
3685 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
3686 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
3687 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
3688 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
3689 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
3690 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
3691 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
3692 /// - $f(0.0,y,z)=0.0$ if $yz=-0.0$
3693 /// - $f(-0.0,y,z)=-0.0$ if $yz=0.0$
3694 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of the same sign
3695 /// - $f(x,y,z)=0.0$ if $x=yz$, $x$ is finite and nonzero,
3696 ///
3697 /// Overflow and underflow:
3698 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
3699 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
3700 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
3701 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
3702 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
3703 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
3704 ///
3705 /// If you want to use a rounding mode other than `Nearest`, consider using
3706 /// [`Float::sub_mul_round`]. If you want to specify the output precision, consider using
3707 /// [`Float::sub_mul_prec`]. If you want both of these things, consider using
3708 /// [`Float::sub_mul_prec_round`].
3709 ///
3710 /// # Worst-case complexity
3711 /// $T(n, m) = O(n \log n \log\log n + m)$
3712 ///
3713 /// $M(n, m) = O(n \log n + m)$
3714 ///
3715 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3716 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3717 ///
3718 /// # Examples
3719 /// ```
3720 /// use core::f64::consts::{E, PI, SQRT_2};
3721 /// use malachite_base::num::arithmetic::traits::SubMul;
3722 /// use malachite_float::Float;
3723 ///
3724 /// let x = Float::from(PI);
3725 /// let y = Float::from(E);
3726 /// let z = Float::from(SQRT_2);
3727 /// assert_eq!(x.sub_mul(&y, z).to_string(), "-0.70263837456932376");
3728 /// ```
3729 #[inline]
3730 fn sub_mul(self, y: &Self, z: Self) -> Self {
3731 let prec = max!(
3732 self.significant_bits(),
3733 y.significant_bits(),
3734 z.significant_bits()
3735 );
3736 self.sub_mul_prec_val_ref_val(y, z, prec).0
3737 }
3738}
3739
3740impl SubMul<&Self, &Self> for Float {
3741 type Output = Self;
3742 /// Subtracts the product of two other [`Float`]s from a [`Float`], taking the first by value
3743 /// and the second and third by reference.
3744 ///
3745 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
3746 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
3747 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
3748 /// `Nearest` rounding mode.
3749 ///
3750 /// $$
3751 /// f(x,y,z) = x-yz+\varepsilon.
3752 /// $$
3753 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3754 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3755 ///
3756 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3757 ///
3758 /// Special cases:
3759 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
3760 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
3761 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
3762 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
3763 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
3764 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
3765 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
3766 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
3767 /// - $f(0.0,y,z)=0.0$ if $yz=-0.0$
3768 /// - $f(-0.0,y,z)=-0.0$ if $yz=0.0$
3769 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of the same sign
3770 /// - $f(x,y,z)=0.0$ if $x=yz$, $x$ is finite and nonzero,
3771 ///
3772 /// Overflow and underflow:
3773 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
3774 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
3775 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
3776 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
3777 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
3778 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
3779 ///
3780 /// If you want to use a rounding mode other than `Nearest`, consider using
3781 /// [`Float::sub_mul_round`]. If you want to specify the output precision, consider using
3782 /// [`Float::sub_mul_prec`]. If you want both of these things, consider using
3783 /// [`Float::sub_mul_prec_round`].
3784 ///
3785 /// # Worst-case complexity
3786 /// $T(n, m) = O(n \log n \log\log n + m)$
3787 ///
3788 /// $M(n, m) = O(n \log n + m)$
3789 ///
3790 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3791 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3792 ///
3793 /// # Examples
3794 /// ```
3795 /// use core::f64::consts::{E, PI, SQRT_2};
3796 /// use malachite_base::num::arithmetic::traits::SubMul;
3797 /// use malachite_float::Float;
3798 ///
3799 /// let x = Float::from(PI);
3800 /// let y = Float::from(E);
3801 /// let z = Float::from(SQRT_2);
3802 /// assert_eq!(x.sub_mul(&y, &z).to_string(), "-0.70263837456932376");
3803 /// ```
3804 #[inline]
3805 fn sub_mul(self, y: &Self, z: &Self) -> Self {
3806 let prec = max!(
3807 self.significant_bits(),
3808 y.significant_bits(),
3809 z.significant_bits()
3810 );
3811 self.sub_mul_prec_val_ref_ref(y, z, prec).0
3812 }
3813}
3814
3815impl SubMul<Float, Float> for &Float {
3816 type Output = Float;
3817 /// Subtracts the product of two other [`Float`]s from a [`Float`], taking the first by
3818 /// reference and the second and third by value.
3819 ///
3820 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
3821 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
3822 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
3823 /// `Nearest` rounding mode.
3824 ///
3825 /// $$
3826 /// f(x,y,z) = x-yz+\varepsilon.
3827 /// $$
3828 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3829 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3830 ///
3831 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3832 ///
3833 /// Special cases:
3834 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
3835 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
3836 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
3837 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
3838 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
3839 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
3840 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
3841 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
3842 /// - $f(0.0,y,z)=0.0$ if $yz=-0.0$
3843 /// - $f(-0.0,y,z)=-0.0$ if $yz=0.0$
3844 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of the same sign
3845 /// - $f(x,y,z)=0.0$ if $x=yz$, $x$ is finite and nonzero,
3846 ///
3847 /// Overflow and underflow:
3848 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
3849 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
3850 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
3851 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
3852 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
3853 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
3854 ///
3855 /// If you want to use a rounding mode other than `Nearest`, consider using
3856 /// [`Float::sub_mul_round`]. If you want to specify the output precision, consider using
3857 /// [`Float::sub_mul_prec`]. If you want both of these things, consider using
3858 /// [`Float::sub_mul_prec_round`].
3859 ///
3860 /// # Worst-case complexity
3861 /// $T(n, m) = O(n \log n \log\log n + m)$
3862 ///
3863 /// $M(n, m) = O(n \log n + m)$
3864 ///
3865 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3866 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3867 ///
3868 /// # Examples
3869 /// ```
3870 /// use core::f64::consts::{E, PI, SQRT_2};
3871 /// use malachite_base::num::arithmetic::traits::SubMul;
3872 /// use malachite_float::Float;
3873 ///
3874 /// let x = Float::from(PI);
3875 /// let y = Float::from(E);
3876 /// let z = Float::from(SQRT_2);
3877 /// assert_eq!(&x.sub_mul(y, z).to_string(), "-0.70263837456932376");
3878 /// ```
3879 #[inline]
3880 fn sub_mul(self, y: Float, z: Float) -> Float {
3881 let prec = max!(
3882 self.significant_bits(),
3883 y.significant_bits(),
3884 z.significant_bits()
3885 );
3886 self.sub_mul_prec_ref_val_val(y, z, prec).0
3887 }
3888}
3889
3890impl SubMul<Float, &Float> for &Float {
3891 type Output = Float;
3892 /// Subtracts the product of two other [`Float`]s from a [`Float`], taking the first and third
3893 /// by reference and the second by value.
3894 ///
3895 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
3896 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
3897 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
3898 /// `Nearest` rounding mode.
3899 ///
3900 /// $$
3901 /// f(x,y,z) = x-yz+\varepsilon.
3902 /// $$
3903 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3904 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3905 ///
3906 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3907 ///
3908 /// Special cases:
3909 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
3910 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
3911 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
3912 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
3913 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
3914 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
3915 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
3916 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
3917 /// - $f(0.0,y,z)=0.0$ if $yz=-0.0$
3918 /// - $f(-0.0,y,z)=-0.0$ if $yz=0.0$
3919 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of the same sign
3920 /// - $f(x,y,z)=0.0$ if $x=yz$, $x$ is finite and nonzero,
3921 ///
3922 /// Overflow and underflow:
3923 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
3924 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
3925 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
3926 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
3927 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
3928 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
3929 ///
3930 /// If you want to use a rounding mode other than `Nearest`, consider using
3931 /// [`Float::sub_mul_round`]. If you want to specify the output precision, consider using
3932 /// [`Float::sub_mul_prec`]. If you want both of these things, consider using
3933 /// [`Float::sub_mul_prec_round`].
3934 ///
3935 /// # Worst-case complexity
3936 /// $T(n, m) = O(n \log n \log\log n + m)$
3937 ///
3938 /// $M(n, m) = O(n \log n + m)$
3939 ///
3940 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
3941 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
3942 ///
3943 /// # Examples
3944 /// ```
3945 /// use core::f64::consts::{E, PI, SQRT_2};
3946 /// use malachite_base::num::arithmetic::traits::SubMul;
3947 /// use malachite_float::Float;
3948 ///
3949 /// let x = Float::from(PI);
3950 /// let y = Float::from(E);
3951 /// let z = Float::from(SQRT_2);
3952 /// assert_eq!(&x.sub_mul(y, &z).to_string(), "-0.70263837456932376");
3953 /// ```
3954 #[inline]
3955 fn sub_mul(self, y: Float, z: &Float) -> Float {
3956 let prec = max!(
3957 self.significant_bits(),
3958 y.significant_bits(),
3959 z.significant_bits()
3960 );
3961 self.sub_mul_prec_ref_val_ref(y, z, prec).0
3962 }
3963}
3964
3965impl SubMul<&Float, Float> for &Float {
3966 type Output = Float;
3967 /// Subtracts the product of two other [`Float`]s from a [`Float`], taking the first two by
3968 /// reference and the third by value.
3969 ///
3970 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
3971 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
3972 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
3973 /// `Nearest` rounding mode.
3974 ///
3975 /// $$
3976 /// f(x,y,z) = x-yz+\varepsilon.
3977 /// $$
3978 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
3979 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
3980 ///
3981 /// If the output has a precision, it is the maximum of the precisions of the inputs.
3982 ///
3983 /// Special cases:
3984 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
3985 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
3986 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
3987 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
3988 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
3989 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
3990 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
3991 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
3992 /// - $f(0.0,y,z)=0.0$ if $yz=-0.0$
3993 /// - $f(-0.0,y,z)=-0.0$ if $yz=0.0$
3994 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of the same sign
3995 /// - $f(x,y,z)=0.0$ if $x=yz$, $x$ is finite and nonzero,
3996 ///
3997 /// Overflow and underflow:
3998 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
3999 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
4000 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
4001 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
4002 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
4003 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
4004 ///
4005 /// If you want to use a rounding mode other than `Nearest`, consider using
4006 /// [`Float::sub_mul_round`]. If you want to specify the output precision, consider using
4007 /// [`Float::sub_mul_prec`]. If you want both of these things, consider using
4008 /// [`Float::sub_mul_prec_round`].
4009 ///
4010 /// # Worst-case complexity
4011 /// $T(n, m) = O(n \log n \log\log n + m)$
4012 ///
4013 /// $M(n, m) = O(n \log n + m)$
4014 ///
4015 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4016 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4017 ///
4018 /// # Examples
4019 /// ```
4020 /// use core::f64::consts::{E, PI, SQRT_2};
4021 /// use malachite_base::num::arithmetic::traits::SubMul;
4022 /// use malachite_float::Float;
4023 ///
4024 /// let x = Float::from(PI);
4025 /// let y = Float::from(E);
4026 /// let z = Float::from(SQRT_2);
4027 /// assert_eq!(&x.sub_mul(&y, z).to_string(), "-0.70263837456932376");
4028 /// ```
4029 #[inline]
4030 fn sub_mul(self, y: &Float, z: Float) -> Float {
4031 let prec = max!(
4032 self.significant_bits(),
4033 y.significant_bits(),
4034 z.significant_bits()
4035 );
4036 self.sub_mul_prec_ref_ref_val(y, z, prec).0
4037 }
4038}
4039
4040impl SubMul<&Float, &Float> for &Float {
4041 type Output = Float;
4042 /// Subtracts the product of two other [`Float`]s from a [`Float`], taking all three by
4043 /// reference.
4044 ///
4045 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
4046 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
4047 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
4048 /// `Nearest` rounding mode.
4049 ///
4050 /// $$
4051 /// f(x,y,z) = x-yz+\varepsilon.
4052 /// $$
4053 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4054 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4055 ///
4056 /// If the output has a precision, it is the maximum of the precisions of the inputs.
4057 ///
4058 /// Special cases:
4059 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=f(x,y,\text{NaN})=\text{NaN}$
4060 /// - $f(x,\pm\infty,\pm0.0)=f(x,\pm0.0,\pm\infty)=\text{NaN}$
4061 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
4062 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
4063 /// - $f(\infty,y,z)=\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq\infty$
4064 /// - $f(-\infty,y,z)=-\infty$ if neither $y$ nor $z$ is `NaN` and $yz\neq-\infty$
4065 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
4066 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
4067 /// - $f(0.0,y,z)=0.0$ if $yz=-0.0$
4068 /// - $f(-0.0,y,z)=-0.0$ if $yz=0.0$
4069 /// - $f(0.0,y,z)=f(-0.0,y,z)=0.0$ if $x$ and $yz$ are zeros of the same sign
4070 /// - $f(x,y,z)=0.0$ if $x=yz$, $x$ is finite and nonzero,
4071 ///
4072 /// Overflow and underflow:
4073 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
4074 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
4075 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
4076 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
4077 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
4078 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
4079 ///
4080 /// If you want to use a rounding mode other than `Nearest`, consider using
4081 /// [`Float::sub_mul_round`]. If you want to specify the output precision, consider using
4082 /// [`Float::sub_mul_prec`]. If you want both of these things, consider using
4083 /// [`Float::sub_mul_prec_round`].
4084 ///
4085 /// # Worst-case complexity
4086 /// $T(n, m) = O(n \log n \log\log n + m)$
4087 ///
4088 /// $M(n, m) = O(n \log n + m)$
4089 ///
4090 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4091 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4092 ///
4093 /// # Examples
4094 /// ```
4095 /// use core::f64::consts::{E, PI, SQRT_2};
4096 /// use malachite_base::num::arithmetic::traits::SubMul;
4097 /// use malachite_float::Float;
4098 ///
4099 /// let x = Float::from(PI);
4100 /// let y = Float::from(E);
4101 /// let z = Float::from(SQRT_2);
4102 /// assert_eq!(&x.sub_mul(&y, &z).to_string(), "-0.70263837456932376");
4103 /// ```
4104 #[inline]
4105 fn sub_mul(self, y: &Float, z: &Float) -> Float {
4106 let prec = max!(
4107 self.significant_bits(),
4108 y.significant_bits(),
4109 z.significant_bits()
4110 );
4111 self.sub_mul_prec_ref_ref_ref(y, z, prec).0
4112 }
4113}
4114
4115impl SubMulAssign<Self, Self> for Float {
4116 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, both [`Float`]s on the
4117 /// right-hand side being taken by value.
4118 ///
4119 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
4120 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
4121 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
4122 /// `Nearest` rounding mode.
4123 ///
4124 /// $$
4125 /// x \gets x-yz+\varepsilon.
4126 /// $$
4127 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4128 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4129 ///
4130 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
4131 /// overflow, and underflow.
4132 ///
4133 /// If you want to use a rounding mode other than `Nearest`, consider using
4134 /// [`Float::sub_mul_round_assign`]. If you want to specify the output precision, consider using
4135 /// [`Float::sub_mul_prec_assign`]. If you want both of these things, consider using
4136 /// [`Float::sub_mul_prec_round_assign`].
4137 ///
4138 /// # Worst-case complexity
4139 /// $T(n, m) = O(n \log n \log\log n + m)$
4140 ///
4141 /// $M(n, m) = O(n \log n + m)$
4142 ///
4143 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4144 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4145 ///
4146 /// # Examples
4147 /// ```
4148 /// use core::f64::consts::{E, PI, SQRT_2};
4149 /// use malachite_base::num::arithmetic::traits::SubMulAssign;
4150 /// use malachite_float::Float;
4151 ///
4152 /// let mut x = Float::from(PI);
4153 /// let y = Float::from(E);
4154 /// let z = Float::from(SQRT_2);
4155 /// x.sub_mul_assign(y, z);
4156 /// assert_eq!(x.to_string(), "-0.70263837456932376");
4157 /// ```
4158 #[inline]
4159 fn sub_mul_assign(&mut self, y: Self, z: Self) {
4160 let prec = max!(
4161 self.significant_bits(),
4162 y.significant_bits(),
4163 z.significant_bits()
4164 );
4165 self.sub_mul_prec_assign(y, z, prec);
4166 }
4167}
4168
4169impl SubMulAssign<Self, &Self> for Float {
4170 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, the first [`Float`] on
4171 /// the right-hand side being taken by value and the second by reference.
4172 ///
4173 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
4174 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
4175 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
4176 /// `Nearest` rounding mode.
4177 ///
4178 /// $$
4179 /// x \gets x-yz+\varepsilon.
4180 /// $$
4181 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4182 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4183 ///
4184 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
4185 /// overflow, and underflow.
4186 ///
4187 /// If you want to use a rounding mode other than `Nearest`, consider using
4188 /// [`Float::sub_mul_round_assign`]. If you want to specify the output precision, consider using
4189 /// [`Float::sub_mul_prec_assign`]. If you want both of these things, consider using
4190 /// [`Float::sub_mul_prec_round_assign`].
4191 ///
4192 /// # Worst-case complexity
4193 /// $T(n, m) = O(n \log n \log\log n + m)$
4194 ///
4195 /// $M(n, m) = O(n \log n + m)$
4196 ///
4197 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4198 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4199 ///
4200 /// # Examples
4201 /// ```
4202 /// use core::f64::consts::{E, PI, SQRT_2};
4203 /// use malachite_base::num::arithmetic::traits::SubMulAssign;
4204 /// use malachite_float::Float;
4205 ///
4206 /// let mut x = Float::from(PI);
4207 /// let y = Float::from(E);
4208 /// let z = Float::from(SQRT_2);
4209 /// x.sub_mul_assign(y, &z);
4210 /// assert_eq!(x.to_string(), "-0.70263837456932376");
4211 /// ```
4212 #[inline]
4213 fn sub_mul_assign(&mut self, y: Self, z: &Self) {
4214 let prec = max!(
4215 self.significant_bits(),
4216 y.significant_bits(),
4217 z.significant_bits()
4218 );
4219 self.sub_mul_prec_assign_val_ref(y, z, prec);
4220 }
4221}
4222
4223impl SubMulAssign<&Self, Self> for Float {
4224 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, the first [`Float`] on
4225 /// the right-hand side being taken by reference and the second by value.
4226 ///
4227 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
4228 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
4229 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
4230 /// `Nearest` rounding mode.
4231 ///
4232 /// $$
4233 /// x \gets x-yz+\varepsilon.
4234 /// $$
4235 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4236 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4237 ///
4238 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
4239 /// overflow, and underflow.
4240 ///
4241 /// If you want to use a rounding mode other than `Nearest`, consider using
4242 /// [`Float::sub_mul_round_assign`]. If you want to specify the output precision, consider using
4243 /// [`Float::sub_mul_prec_assign`]. If you want both of these things, consider using
4244 /// [`Float::sub_mul_prec_round_assign`].
4245 ///
4246 /// # Worst-case complexity
4247 /// $T(n, m) = O(n \log n \log\log n + m)$
4248 ///
4249 /// $M(n, m) = O(n \log n + m)$
4250 ///
4251 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4252 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4253 ///
4254 /// # Examples
4255 /// ```
4256 /// use core::f64::consts::{E, PI, SQRT_2};
4257 /// use malachite_base::num::arithmetic::traits::SubMulAssign;
4258 /// use malachite_float::Float;
4259 ///
4260 /// let mut x = Float::from(PI);
4261 /// let y = Float::from(E);
4262 /// let z = Float::from(SQRT_2);
4263 /// x.sub_mul_assign(&y, z);
4264 /// assert_eq!(x.to_string(), "-0.70263837456932376");
4265 /// ```
4266 #[inline]
4267 fn sub_mul_assign(&mut self, y: &Self, z: Self) {
4268 let prec = max!(
4269 self.significant_bits(),
4270 y.significant_bits(),
4271 z.significant_bits()
4272 );
4273 self.sub_mul_prec_assign_ref_val(y, z, prec);
4274 }
4275}
4276
4277impl SubMulAssign<&Self, &Self> for Float {
4278 /// Subtracts the product of two [`Float`]s from a [`Float`] in place, both [`Float`]s on the
4279 /// right-hand side being taken by reference.
4280 ///
4281 /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
4282 /// diff is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
4283 /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
4284 /// `Nearest` rounding mode.
4285 ///
4286 /// $$
4287 /// x \gets x-yz+\varepsilon.
4288 /// $$
4289 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
4290 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
4291 ///
4292 /// See the [`Float::sub_mul_prec_round`] documentation for information on special cases,
4293 /// overflow, and underflow.
4294 ///
4295 /// If you want to use a rounding mode other than `Nearest`, consider using
4296 /// [`Float::sub_mul_round_assign`]. If you want to specify the output precision, consider using
4297 /// [`Float::sub_mul_prec_assign`]. If you want both of these things, consider using
4298 /// [`Float::sub_mul_prec_round_assign`].
4299 ///
4300 /// # Worst-case complexity
4301 /// $T(n, m) = O(n \log n \log\log n + m)$
4302 ///
4303 /// $M(n, m) = O(n \log n + m)$
4304 ///
4305 /// where $T$ is time, $M$ is additional memory, $n$ is `y.significant_bits() +
4306 /// z.significant_bits()`, and $m$ is `self.significant_bits()`.
4307 ///
4308 /// # Examples
4309 /// ```
4310 /// use core::f64::consts::{E, PI, SQRT_2};
4311 /// use malachite_base::num::arithmetic::traits::SubMulAssign;
4312 /// use malachite_float::Float;
4313 ///
4314 /// let mut x = Float::from(PI);
4315 /// let y = Float::from(E);
4316 /// let z = Float::from(SQRT_2);
4317 /// x.sub_mul_assign(&y, &z);
4318 /// assert_eq!(x.to_string(), "-0.70263837456932376");
4319 /// ```
4320 #[inline]
4321 fn sub_mul_assign(&mut self, y: &Self, z: &Self) {
4322 let prec = max!(
4323 self.significant_bits(),
4324 y.significant_bits(),
4325 z.significant_bits()
4326 );
4327 self.sub_mul_prec_assign_ref_ref(y, z, prec);
4328 }
4329}
4330
4331impl Float {
4332 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
4333 /// result to the specified precision and with the specified rounding mode. The [`Float`]s and
4334 /// the [`Rational`] are all taken by value. An [`Ordering`] is also returned, indicating
4335 /// whether the rounded diff is less than, equal to, or greater than the exact diff. Although
4336 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
4337 /// returns `Equal`.
4338 ///
4339 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
4340 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
4341 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
4342 ///
4343 /// See [`RoundingMode`] for a description of the possible rounding modes.
4344 ///
4345 /// $$
4346 /// f(x,y,z,p,m) = x-yz+\varepsilon.
4347 /// $$
4348 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4349 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4350 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
4351 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4352 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
4353 ///
4354 /// If the output has a precision, it is `prec`.
4355 ///
4356 /// Special cases:
4357 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
4358 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
4359 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
4360 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
4361 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
4362 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
4363 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
4364 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
4365 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
4366 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
4367 /// zero [`Rational`] counting as positive.
4368 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
4369 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
4370 ///
4371 /// Overflow and underflow:
4372 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4373 /// returned instead.
4374 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
4375 /// is returned instead, where `p` is the precision of the output.
4376 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4377 /// returned instead.
4378 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4379 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4380 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4381 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4382 /// instead.
4383 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4384 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4385 /// returned instead.
4386 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4387 /// instead.
4388 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4389 /// instead.
4390 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4391 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4392 /// returned instead.
4393 ///
4394 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_rational_prec`]
4395 /// instead. If you know that your target precision is the maximum of the precisions of the
4396 /// inputs, consider using [`Float::sub_mul_rational_round`] instead. If both of these things
4397 /// are true, consider using
4398 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
4399 ///
4400 /// # Worst-case complexity
4401 /// $T(n, m) = O(n \log n \log\log n + m)$
4402 ///
4403 /// $M(n, m) = O(n \log n + m)$
4404 ///
4405 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4406 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
4407 /// prec)`.
4408 ///
4409 /// # Panics
4410 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
4411 /// exactly representable with `prec` bits.
4412 ///
4413 /// # Examples
4414 /// ```
4415 /// use core::f64::consts::{E, PI};
4416 /// use malachite_base::rounding_modes::RoundingMode::*;
4417 /// use malachite_float::Float;
4418 /// use malachite_q::Rational;
4419 /// use std::cmp::Ordering::*;
4420 ///
4421 /// let x = Float::from(PI);
4422 /// let y = Float::from(E);
4423 /// let z = Rational::from_signeds(22, 7);
4424 ///
4425 /// let (diff, o) = x
4426 /// .clone()
4427 /// .sub_mul_rational_prec_round(y.clone(), z.clone(), 5, Floor);
4428 /// assert_eq!(diff.to_string(), "-5.50");
4429 /// assert_eq!(o, Less);
4430 ///
4431 /// let (diff, o) = x
4432 /// .clone()
4433 /// .sub_mul_rational_prec_round(y.clone(), z.clone(), 5, Ceiling);
4434 /// assert_eq!(diff.to_string(), "-5.25");
4435 /// assert_eq!(o, Greater);
4436 ///
4437 /// let (diff, o) = x
4438 /// .clone()
4439 /// .sub_mul_rational_prec_round(y.clone(), z.clone(), 5, Nearest);
4440 /// assert_eq!(diff.to_string(), "-5.50");
4441 /// assert_eq!(o, Less);
4442 ///
4443 /// let (diff, o) = x
4444 /// .clone()
4445 /// .sub_mul_rational_prec_round(y.clone(), z.clone(), 20, Floor);
4446 /// assert_eq!(diff.to_string(), "-5.4015808");
4447 /// assert_eq!(o, Less);
4448 ///
4449 /// let (diff, o) = x
4450 /// .clone()
4451 /// .sub_mul_rational_prec_round(y.clone(), z.clone(), 20, Ceiling);
4452 /// assert_eq!(diff.to_string(), "-5.4015732");
4453 /// assert_eq!(o, Greater);
4454 ///
4455 /// let (diff, o) = x
4456 /// .clone()
4457 /// .sub_mul_rational_prec_round(y.clone(), z.clone(), 20, Nearest);
4458 /// assert_eq!(diff.to_string(), "-5.4015808");
4459 /// assert_eq!(o, Less);
4460 /// ```
4461 #[allow(clippy::needless_pass_by_value)]
4462 #[inline]
4463 pub fn sub_mul_rational_prec_round(
4464 self,
4465 y: Self,
4466 z: Rational,
4467 prec: u64,
4468 rm: RoundingMode,
4469 ) -> (Self, Ordering) {
4470 add_mul_rational_helper(&self, &y, &z, true, prec, rm)
4471 }
4472
4473 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
4474 /// result to the specified precision and with the specified rounding mode. The [`Float`]s are
4475 /// taken by value and the [`Rational`] by reference. An [`Ordering`] is also returned,
4476 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
4477 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
4478 /// it also returns `Equal`.
4479 ///
4480 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
4481 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
4482 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
4483 ///
4484 /// See [`RoundingMode`] for a description of the possible rounding modes.
4485 ///
4486 /// $$
4487 /// f(x,y,z,p,m) = x-yz+\varepsilon.
4488 /// $$
4489 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4490 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4491 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
4492 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4493 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
4494 ///
4495 /// If the output has a precision, it is `prec`.
4496 ///
4497 /// Special cases:
4498 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
4499 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
4500 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
4501 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
4502 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
4503 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
4504 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
4505 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
4506 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
4507 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
4508 /// zero [`Rational`] counting as positive.
4509 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
4510 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
4511 ///
4512 /// Overflow and underflow:
4513 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4514 /// returned instead.
4515 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
4516 /// is returned instead, where `p` is the precision of the output.
4517 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4518 /// returned instead.
4519 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4520 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4521 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4522 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4523 /// instead.
4524 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4525 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4526 /// returned instead.
4527 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4528 /// instead.
4529 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4530 /// instead.
4531 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4532 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4533 /// returned instead.
4534 ///
4535 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_rational_prec`]
4536 /// instead. If you know that your target precision is the maximum of the precisions of the
4537 /// inputs, consider using [`Float::sub_mul_rational_round`] instead. If both of these things
4538 /// are true, consider using
4539 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
4540 ///
4541 /// # Worst-case complexity
4542 /// $T(n, m) = O(n \log n \log\log n + m)$
4543 ///
4544 /// $M(n, m) = O(n \log n + m)$
4545 ///
4546 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4547 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
4548 /// prec)`.
4549 ///
4550 /// # Panics
4551 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
4552 /// exactly representable with `prec` bits.
4553 ///
4554 /// # Examples
4555 /// ```
4556 /// use core::f64::consts::{E, PI};
4557 /// use malachite_base::rounding_modes::RoundingMode::*;
4558 /// use malachite_float::Float;
4559 /// use malachite_q::Rational;
4560 /// use std::cmp::Ordering::*;
4561 ///
4562 /// let x = Float::from(PI);
4563 /// let y = Float::from(E);
4564 /// let z = Rational::from_signeds(22, 7);
4565 ///
4566 /// let (diff, o) = x
4567 /// .clone()
4568 /// .sub_mul_rational_prec_round_val_val_ref(y.clone(), &z, 5, Floor);
4569 /// assert_eq!(diff.to_string(), "-5.50");
4570 /// assert_eq!(o, Less);
4571 ///
4572 /// let (diff, o) =
4573 /// x.clone()
4574 /// .sub_mul_rational_prec_round_val_val_ref(y.clone(), &z, 5, Ceiling);
4575 /// assert_eq!(diff.to_string(), "-5.25");
4576 /// assert_eq!(o, Greater);
4577 ///
4578 /// let (diff, o) =
4579 /// x.clone()
4580 /// .sub_mul_rational_prec_round_val_val_ref(y.clone(), &z, 5, Nearest);
4581 /// assert_eq!(diff.to_string(), "-5.50");
4582 /// assert_eq!(o, Less);
4583 ///
4584 /// let (diff, o) = x
4585 /// .clone()
4586 /// .sub_mul_rational_prec_round_val_val_ref(y.clone(), &z, 20, Floor);
4587 /// assert_eq!(diff.to_string(), "-5.4015808");
4588 /// assert_eq!(o, Less);
4589 ///
4590 /// let (diff, o) =
4591 /// x.clone()
4592 /// .sub_mul_rational_prec_round_val_val_ref(y.clone(), &z, 20, Ceiling);
4593 /// assert_eq!(diff.to_string(), "-5.4015732");
4594 /// assert_eq!(o, Greater);
4595 ///
4596 /// let (diff, o) =
4597 /// x.clone()
4598 /// .sub_mul_rational_prec_round_val_val_ref(y.clone(), &z, 20, Nearest);
4599 /// assert_eq!(diff.to_string(), "-5.4015808");
4600 /// assert_eq!(o, Less);
4601 /// ```
4602 #[allow(clippy::needless_pass_by_value)]
4603 #[inline]
4604 pub fn sub_mul_rational_prec_round_val_val_ref(
4605 self,
4606 y: Self,
4607 z: &Rational,
4608 prec: u64,
4609 rm: RoundingMode,
4610 ) -> (Self, Ordering) {
4611 add_mul_rational_helper(&self, &y, z, true, prec, rm)
4612 }
4613
4614 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
4615 /// result to the specified precision and with the specified rounding mode. The first [`Float`]
4616 /// and the [`Rational`] are taken by value and the second [`Float`] by reference. An
4617 /// [`Ordering`] is also returned, indicating whether the rounded diff is less than, equal to,
4618 /// or greater than the exact diff. Although `NaN`s are not comparable to any [`Float`],
4619 /// whenever this function returns a `NaN` it also returns `Equal`.
4620 ///
4621 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
4622 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
4623 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
4624 ///
4625 /// See [`RoundingMode`] for a description of the possible rounding modes.
4626 ///
4627 /// $$
4628 /// f(x,y,z,p,m) = x-yz+\varepsilon.
4629 /// $$
4630 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4631 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4632 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
4633 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4634 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
4635 ///
4636 /// If the output has a precision, it is `prec`.
4637 ///
4638 /// Special cases:
4639 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
4640 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
4641 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
4642 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
4643 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
4644 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
4645 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
4646 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
4647 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
4648 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
4649 /// zero [`Rational`] counting as positive.
4650 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
4651 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
4652 ///
4653 /// Overflow and underflow:
4654 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4655 /// returned instead.
4656 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
4657 /// is returned instead, where `p` is the precision of the output.
4658 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4659 /// returned instead.
4660 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4661 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4662 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4663 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4664 /// instead.
4665 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4666 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4667 /// returned instead.
4668 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4669 /// instead.
4670 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4671 /// instead.
4672 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4673 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4674 /// returned instead.
4675 ///
4676 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_rational_prec`]
4677 /// instead. If you know that your target precision is the maximum of the precisions of the
4678 /// inputs, consider using [`Float::sub_mul_rational_round`] instead. If both of these things
4679 /// are true, consider using
4680 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
4681 ///
4682 /// # Worst-case complexity
4683 /// $T(n, m) = O(n \log n \log\log n + m)$
4684 ///
4685 /// $M(n, m) = O(n \log n + m)$
4686 ///
4687 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4688 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
4689 /// prec)`.
4690 ///
4691 /// # Panics
4692 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
4693 /// exactly representable with `prec` bits.
4694 ///
4695 /// # Examples
4696 /// ```
4697 /// use core::f64::consts::{E, PI};
4698 /// use malachite_base::rounding_modes::RoundingMode::*;
4699 /// use malachite_float::Float;
4700 /// use malachite_q::Rational;
4701 /// use std::cmp::Ordering::*;
4702 ///
4703 /// let x = Float::from(PI);
4704 /// let y = Float::from(E);
4705 /// let z = Rational::from_signeds(22, 7);
4706 ///
4707 /// let (diff, o) = x
4708 /// .clone()
4709 /// .sub_mul_rational_prec_round_val_ref_val(&y, z.clone(), 5, Floor);
4710 /// assert_eq!(diff.to_string(), "-5.50");
4711 /// assert_eq!(o, Less);
4712 ///
4713 /// let (diff, o) =
4714 /// x.clone()
4715 /// .sub_mul_rational_prec_round_val_ref_val(&y, z.clone(), 5, Ceiling);
4716 /// assert_eq!(diff.to_string(), "-5.25");
4717 /// assert_eq!(o, Greater);
4718 ///
4719 /// let (diff, o) =
4720 /// x.clone()
4721 /// .sub_mul_rational_prec_round_val_ref_val(&y, z.clone(), 5, Nearest);
4722 /// assert_eq!(diff.to_string(), "-5.50");
4723 /// assert_eq!(o, Less);
4724 ///
4725 /// let (diff, o) = x
4726 /// .clone()
4727 /// .sub_mul_rational_prec_round_val_ref_val(&y, z.clone(), 20, Floor);
4728 /// assert_eq!(diff.to_string(), "-5.4015808");
4729 /// assert_eq!(o, Less);
4730 ///
4731 /// let (diff, o) =
4732 /// x.clone()
4733 /// .sub_mul_rational_prec_round_val_ref_val(&y, z.clone(), 20, Ceiling);
4734 /// assert_eq!(diff.to_string(), "-5.4015732");
4735 /// assert_eq!(o, Greater);
4736 ///
4737 /// let (diff, o) =
4738 /// x.clone()
4739 /// .sub_mul_rational_prec_round_val_ref_val(&y, z.clone(), 20, Nearest);
4740 /// assert_eq!(diff.to_string(), "-5.4015808");
4741 /// assert_eq!(o, Less);
4742 /// ```
4743 #[allow(clippy::needless_pass_by_value)]
4744 #[inline]
4745 pub fn sub_mul_rational_prec_round_val_ref_val(
4746 self,
4747 y: &Self,
4748 z: Rational,
4749 prec: u64,
4750 rm: RoundingMode,
4751 ) -> (Self, Ordering) {
4752 add_mul_rational_helper(&self, y, &z, true, prec, rm)
4753 }
4754
4755 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
4756 /// result to the specified precision and with the specified rounding mode. The first [`Float`]
4757 /// is taken by value and the second [`Float`] and the [`Rational`] by reference. An
4758 /// [`Ordering`] is also returned, indicating whether the rounded diff is less than, equal to,
4759 /// or greater than the exact diff. Although `NaN`s are not comparable to any [`Float`],
4760 /// whenever this function returns a `NaN` it also returns `Equal`.
4761 ///
4762 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
4763 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
4764 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
4765 ///
4766 /// See [`RoundingMode`] for a description of the possible rounding modes.
4767 ///
4768 /// $$
4769 /// f(x,y,z,p,m) = x-yz+\varepsilon.
4770 /// $$
4771 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4772 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4773 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
4774 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4775 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
4776 ///
4777 /// If the output has a precision, it is `prec`.
4778 ///
4779 /// Special cases:
4780 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
4781 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
4782 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
4783 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
4784 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
4785 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
4786 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
4787 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
4788 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
4789 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
4790 /// zero [`Rational`] counting as positive.
4791 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
4792 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
4793 ///
4794 /// Overflow and underflow:
4795 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4796 /// returned instead.
4797 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
4798 /// is returned instead, where `p` is the precision of the output.
4799 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4800 /// returned instead.
4801 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4802 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4803 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4804 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4805 /// instead.
4806 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4807 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4808 /// returned instead.
4809 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4810 /// instead.
4811 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4812 /// instead.
4813 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4814 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4815 /// returned instead.
4816 ///
4817 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_rational_prec`]
4818 /// instead. If you know that your target precision is the maximum of the precisions of the
4819 /// inputs, consider using [`Float::sub_mul_rational_round`] instead. If both of these things
4820 /// are true, consider using
4821 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
4822 ///
4823 /// # Worst-case complexity
4824 /// $T(n, m) = O(n \log n \log\log n + m)$
4825 ///
4826 /// $M(n, m) = O(n \log n + m)$
4827 ///
4828 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4829 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
4830 /// prec)`.
4831 ///
4832 /// # Panics
4833 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
4834 /// exactly representable with `prec` bits.
4835 ///
4836 /// # Examples
4837 /// ```
4838 /// use core::f64::consts::{E, PI};
4839 /// use malachite_base::rounding_modes::RoundingMode::*;
4840 /// use malachite_float::Float;
4841 /// use malachite_q::Rational;
4842 /// use std::cmp::Ordering::*;
4843 ///
4844 /// let x = Float::from(PI);
4845 /// let y = Float::from(E);
4846 /// let z = Rational::from_signeds(22, 7);
4847 ///
4848 /// let (diff, o) = x
4849 /// .clone()
4850 /// .sub_mul_rational_prec_round_val_ref_ref(&y, &z, 5, Floor);
4851 /// assert_eq!(diff.to_string(), "-5.50");
4852 /// assert_eq!(o, Less);
4853 ///
4854 /// let (diff, o) = x
4855 /// .clone()
4856 /// .sub_mul_rational_prec_round_val_ref_ref(&y, &z, 5, Ceiling);
4857 /// assert_eq!(diff.to_string(), "-5.25");
4858 /// assert_eq!(o, Greater);
4859 ///
4860 /// let (diff, o) = x
4861 /// .clone()
4862 /// .sub_mul_rational_prec_round_val_ref_ref(&y, &z, 5, Nearest);
4863 /// assert_eq!(diff.to_string(), "-5.50");
4864 /// assert_eq!(o, Less);
4865 ///
4866 /// let (diff, o) = x
4867 /// .clone()
4868 /// .sub_mul_rational_prec_round_val_ref_ref(&y, &z, 20, Floor);
4869 /// assert_eq!(diff.to_string(), "-5.4015808");
4870 /// assert_eq!(o, Less);
4871 ///
4872 /// let (diff, o) = x
4873 /// .clone()
4874 /// .sub_mul_rational_prec_round_val_ref_ref(&y, &z, 20, Ceiling);
4875 /// assert_eq!(diff.to_string(), "-5.4015732");
4876 /// assert_eq!(o, Greater);
4877 ///
4878 /// let (diff, o) = x
4879 /// .clone()
4880 /// .sub_mul_rational_prec_round_val_ref_ref(&y, &z, 20, Nearest);
4881 /// assert_eq!(diff.to_string(), "-5.4015808");
4882 /// assert_eq!(o, Less);
4883 /// ```
4884 #[allow(clippy::needless_pass_by_value)]
4885 #[inline]
4886 pub fn sub_mul_rational_prec_round_val_ref_ref(
4887 self,
4888 y: &Self,
4889 z: &Rational,
4890 prec: u64,
4891 rm: RoundingMode,
4892 ) -> (Self, Ordering) {
4893 add_mul_rational_helper(&self, y, z, true, prec, rm)
4894 }
4895
4896 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
4897 /// result to the specified precision and with the specified rounding mode. The first [`Float`]
4898 /// is taken by reference and the second [`Float`] and the [`Rational`] by value. An
4899 /// [`Ordering`] is also returned, indicating whether the rounded diff is less than, equal to,
4900 /// or greater than the exact diff. Although `NaN`s are not comparable to any [`Float`],
4901 /// whenever this function returns a `NaN` it also returns `Equal`.
4902 ///
4903 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
4904 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
4905 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
4906 ///
4907 /// See [`RoundingMode`] for a description of the possible rounding modes.
4908 ///
4909 /// $$
4910 /// f(x,y,z,p,m) = x-yz+\varepsilon.
4911 /// $$
4912 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4913 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
4914 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
4915 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
4916 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
4917 ///
4918 /// If the output has a precision, it is `prec`.
4919 ///
4920 /// Special cases:
4921 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
4922 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
4923 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
4924 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
4925 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
4926 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
4927 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
4928 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
4929 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
4930 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
4931 /// zero [`Rational`] counting as positive.
4932 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
4933 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
4934 ///
4935 /// Overflow and underflow:
4936 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
4937 /// returned instead.
4938 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
4939 /// is returned instead, where `p` is the precision of the output.
4940 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
4941 /// returned instead.
4942 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
4943 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
4944 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
4945 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
4946 /// instead.
4947 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
4948 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
4949 /// returned instead.
4950 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
4951 /// instead.
4952 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
4953 /// instead.
4954 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
4955 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
4956 /// returned instead.
4957 ///
4958 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_rational_prec`]
4959 /// instead. If you know that your target precision is the maximum of the precisions of the
4960 /// inputs, consider using [`Float::sub_mul_rational_round`] instead. If both of these things
4961 /// are true, consider using
4962 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
4963 ///
4964 /// # Worst-case complexity
4965 /// $T(n, m) = O(n \log n \log\log n + m)$
4966 ///
4967 /// $M(n, m) = O(n \log n + m)$
4968 ///
4969 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
4970 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
4971 /// prec)`.
4972 ///
4973 /// # Panics
4974 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
4975 /// exactly representable with `prec` bits.
4976 ///
4977 /// # Examples
4978 /// ```
4979 /// use core::f64::consts::{E, PI};
4980 /// use malachite_base::rounding_modes::RoundingMode::*;
4981 /// use malachite_float::Float;
4982 /// use malachite_q::Rational;
4983 /// use std::cmp::Ordering::*;
4984 ///
4985 /// let x = Float::from(PI);
4986 /// let y = Float::from(E);
4987 /// let z = Rational::from_signeds(22, 7);
4988 ///
4989 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_val_val(y.clone(), z.clone(), 5, Floor);
4990 /// assert_eq!(diff.to_string(), "-5.50");
4991 /// assert_eq!(o, Less);
4992 ///
4993 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_val_val(y.clone(), z.clone(), 5, Ceiling);
4994 /// assert_eq!(diff.to_string(), "-5.25");
4995 /// assert_eq!(o, Greater);
4996 ///
4997 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_val_val(y.clone(), z.clone(), 5, Nearest);
4998 /// assert_eq!(diff.to_string(), "-5.50");
4999 /// assert_eq!(o, Less);
5000 ///
5001 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_val_val(y.clone(), z.clone(), 20, Floor);
5002 /// assert_eq!(diff.to_string(), "-5.4015808");
5003 /// assert_eq!(o, Less);
5004 ///
5005 /// let (diff, o) =
5006 /// x.sub_mul_rational_prec_round_ref_val_val(y.clone(), z.clone(), 20, Ceiling);
5007 /// assert_eq!(diff.to_string(), "-5.4015732");
5008 /// assert_eq!(o, Greater);
5009 ///
5010 /// let (diff, o) =
5011 /// x.sub_mul_rational_prec_round_ref_val_val(y.clone(), z.clone(), 20, Nearest);
5012 /// assert_eq!(diff.to_string(), "-5.4015808");
5013 /// assert_eq!(o, Less);
5014 /// ```
5015 #[allow(clippy::needless_pass_by_value)]
5016 #[inline]
5017 pub fn sub_mul_rational_prec_round_ref_val_val(
5018 &self,
5019 y: Self,
5020 z: Rational,
5021 prec: u64,
5022 rm: RoundingMode,
5023 ) -> (Self, Ordering) {
5024 add_mul_rational_helper(self, &y, &z, true, prec, rm)
5025 }
5026
5027 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
5028 /// result to the specified precision and with the specified rounding mode. The second [`Float`]
5029 /// is taken by value and the first [`Float`] and the [`Rational`] by reference. An [`Ordering`]
5030 /// is also returned, indicating whether the rounded diff is less than, equal to, or greater
5031 /// than the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this
5032 /// function returns a `NaN` it also returns `Equal`.
5033 ///
5034 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5035 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
5036 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5037 ///
5038 /// See [`RoundingMode`] for a description of the possible rounding modes.
5039 ///
5040 /// $$
5041 /// f(x,y,z,p,m) = x-yz+\varepsilon.
5042 /// $$
5043 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5044 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5045 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
5046 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5047 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
5048 ///
5049 /// If the output has a precision, it is `prec`.
5050 ///
5051 /// Special cases:
5052 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
5053 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
5054 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
5055 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
5056 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
5057 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
5058 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
5059 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
5060 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
5061 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
5062 /// zero [`Rational`] counting as positive.
5063 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
5064 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
5065 ///
5066 /// Overflow and underflow:
5067 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5068 /// returned instead.
5069 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
5070 /// is returned instead, where `p` is the precision of the output.
5071 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5072 /// returned instead.
5073 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5074 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5075 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
5076 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5077 /// instead.
5078 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5079 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5080 /// returned instead.
5081 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5082 /// instead.
5083 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5084 /// instead.
5085 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
5086 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5087 /// returned instead.
5088 ///
5089 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_rational_prec`]
5090 /// instead. If you know that your target precision is the maximum of the precisions of the
5091 /// inputs, consider using [`Float::sub_mul_rational_round`] instead. If both of these things
5092 /// are true, consider using
5093 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
5094 ///
5095 /// # Worst-case complexity
5096 /// $T(n, m) = O(n \log n \log\log n + m)$
5097 ///
5098 /// $M(n, m) = O(n \log n + m)$
5099 ///
5100 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5101 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5102 /// prec)`.
5103 ///
5104 /// # Panics
5105 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
5106 /// exactly representable with `prec` bits.
5107 ///
5108 /// # Examples
5109 /// ```
5110 /// use core::f64::consts::{E, PI};
5111 /// use malachite_base::rounding_modes::RoundingMode::*;
5112 /// use malachite_float::Float;
5113 /// use malachite_q::Rational;
5114 /// use std::cmp::Ordering::*;
5115 ///
5116 /// let x = Float::from(PI);
5117 /// let y = Float::from(E);
5118 /// let z = Rational::from_signeds(22, 7);
5119 ///
5120 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_val_ref(y.clone(), &z, 5, Floor);
5121 /// assert_eq!(diff.to_string(), "-5.50");
5122 /// assert_eq!(o, Less);
5123 ///
5124 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_val_ref(y.clone(), &z, 5, Ceiling);
5125 /// assert_eq!(diff.to_string(), "-5.25");
5126 /// assert_eq!(o, Greater);
5127 ///
5128 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_val_ref(y.clone(), &z, 5, Nearest);
5129 /// assert_eq!(diff.to_string(), "-5.50");
5130 /// assert_eq!(o, Less);
5131 ///
5132 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_val_ref(y.clone(), &z, 20, Floor);
5133 /// assert_eq!(diff.to_string(), "-5.4015808");
5134 /// assert_eq!(o, Less);
5135 ///
5136 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_val_ref(y.clone(), &z, 20, Ceiling);
5137 /// assert_eq!(diff.to_string(), "-5.4015732");
5138 /// assert_eq!(o, Greater);
5139 ///
5140 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_val_ref(y.clone(), &z, 20, Nearest);
5141 /// assert_eq!(diff.to_string(), "-5.4015808");
5142 /// assert_eq!(o, Less);
5143 /// ```
5144 #[allow(clippy::needless_pass_by_value)]
5145 #[inline]
5146 pub fn sub_mul_rational_prec_round_ref_val_ref(
5147 &self,
5148 y: Self,
5149 z: &Rational,
5150 prec: u64,
5151 rm: RoundingMode,
5152 ) -> (Self, Ordering) {
5153 add_mul_rational_helper(self, &y, z, true, prec, rm)
5154 }
5155
5156 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
5157 /// result to the specified precision and with the specified rounding mode. The [`Float`]s are
5158 /// taken by reference and the [`Rational`] by value. An [`Ordering`] is also returned,
5159 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
5160 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
5161 /// it also returns `Equal`.
5162 ///
5163 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5164 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
5165 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5166 ///
5167 /// See [`RoundingMode`] for a description of the possible rounding modes.
5168 ///
5169 /// $$
5170 /// f(x,y,z,p,m) = x-yz+\varepsilon.
5171 /// $$
5172 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5173 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5174 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
5175 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5176 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
5177 ///
5178 /// If the output has a precision, it is `prec`.
5179 ///
5180 /// Special cases:
5181 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
5182 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
5183 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
5184 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
5185 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
5186 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
5187 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
5188 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
5189 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
5190 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
5191 /// zero [`Rational`] counting as positive.
5192 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
5193 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
5194 ///
5195 /// Overflow and underflow:
5196 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5197 /// returned instead.
5198 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
5199 /// is returned instead, where `p` is the precision of the output.
5200 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5201 /// returned instead.
5202 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5203 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5204 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
5205 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5206 /// instead.
5207 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5208 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5209 /// returned instead.
5210 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5211 /// instead.
5212 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5213 /// instead.
5214 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
5215 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5216 /// returned instead.
5217 ///
5218 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_rational_prec`]
5219 /// instead. If you know that your target precision is the maximum of the precisions of the
5220 /// inputs, consider using [`Float::sub_mul_rational_round`] instead. If both of these things
5221 /// are true, consider using
5222 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
5223 ///
5224 /// # Worst-case complexity
5225 /// $T(n, m) = O(n \log n \log\log n + m)$
5226 ///
5227 /// $M(n, m) = O(n \log n + m)$
5228 ///
5229 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5230 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5231 /// prec)`.
5232 ///
5233 /// # Panics
5234 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
5235 /// exactly representable with `prec` bits.
5236 ///
5237 /// # Examples
5238 /// ```
5239 /// use core::f64::consts::{E, PI};
5240 /// use malachite_base::rounding_modes::RoundingMode::*;
5241 /// use malachite_float::Float;
5242 /// use malachite_q::Rational;
5243 /// use std::cmp::Ordering::*;
5244 ///
5245 /// let x = Float::from(PI);
5246 /// let y = Float::from(E);
5247 /// let z = Rational::from_signeds(22, 7);
5248 ///
5249 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_ref_val(&y, z.clone(), 5, Floor);
5250 /// assert_eq!(diff.to_string(), "-5.50");
5251 /// assert_eq!(o, Less);
5252 ///
5253 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_ref_val(&y, z.clone(), 5, Ceiling);
5254 /// assert_eq!(diff.to_string(), "-5.25");
5255 /// assert_eq!(o, Greater);
5256 ///
5257 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_ref_val(&y, z.clone(), 5, Nearest);
5258 /// assert_eq!(diff.to_string(), "-5.50");
5259 /// assert_eq!(o, Less);
5260 ///
5261 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_ref_val(&y, z.clone(), 20, Floor);
5262 /// assert_eq!(diff.to_string(), "-5.4015808");
5263 /// assert_eq!(o, Less);
5264 ///
5265 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_ref_val(&y, z.clone(), 20, Ceiling);
5266 /// assert_eq!(diff.to_string(), "-5.4015732");
5267 /// assert_eq!(o, Greater);
5268 ///
5269 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_ref_val(&y, z.clone(), 20, Nearest);
5270 /// assert_eq!(diff.to_string(), "-5.4015808");
5271 /// assert_eq!(o, Less);
5272 /// ```
5273 #[allow(clippy::needless_pass_by_value)]
5274 #[inline]
5275 pub fn sub_mul_rational_prec_round_ref_ref_val(
5276 &self,
5277 y: &Self,
5278 z: Rational,
5279 prec: u64,
5280 rm: RoundingMode,
5281 ) -> (Self, Ordering) {
5282 add_mul_rational_helper(self, y, &z, true, prec, rm)
5283 }
5284
5285 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
5286 /// result to the specified precision and with the specified rounding mode. The [`Float`]s and
5287 /// the [`Rational`] are all taken by reference. An [`Ordering`] is also returned, indicating
5288 /// whether the rounded diff is less than, equal to, or greater than the exact diff. Although
5289 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
5290 /// returns `Equal`.
5291 ///
5292 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5293 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
5294 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5295 ///
5296 /// See [`RoundingMode`] for a description of the possible rounding modes.
5297 ///
5298 /// $$
5299 /// f(x,y,z,p,m) = x-yz+\varepsilon.
5300 /// $$
5301 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5302 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5303 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
5304 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5305 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
5306 ///
5307 /// If the output has a precision, it is `prec`.
5308 ///
5309 /// Special cases:
5310 /// - $f(\text{NaN},y,z,p,m)=f(x,\text{NaN},z,p,m)=\text{NaN}$
5311 /// - $f(x,\pm\infty,0,p,m)=\text{NaN}$
5312 /// - $f(\infty,y,z,p,m)=\text{NaN}$ if $yz=\infty$
5313 /// - $f(-\infty,y,z,p,m)=\text{NaN}$ if $yz=-\infty$
5314 /// - $f(\infty,y,z,p,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
5315 /// - $f(-\infty,y,z,p,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
5316 /// - $f(x,y,z,p,m)=-\infty$ if $x$ is finite and $yz=\infty$
5317 /// - $f(x,y,z,p,m)=\infty$ if $x$ is finite and $yz=-\infty$
5318 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
5319 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
5320 /// zero [`Rational`] counting as positive.
5321 /// - $f(x,y,z,p,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
5322 /// - $f(x,y,z,p,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
5323 ///
5324 /// Overflow and underflow:
5325 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
5326 /// returned instead.
5327 /// - If $f(x,y,z,p,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
5328 /// is returned instead, where `p` is the precision of the output.
5329 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
5330 /// returned instead.
5331 /// - If $f(x,y,z,p,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
5332 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
5333 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
5334 /// - If $0<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
5335 /// instead.
5336 /// - If $0<f(x,y,z,p,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
5337 /// - If $2^{-2^{30}-1}<f(x,y,z,p,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is
5338 /// returned instead.
5339 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
5340 /// instead.
5341 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
5342 /// instead.
5343 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
5344 /// - If $-2^{-2^{30}}<f(x,y,z,p,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
5345 /// returned instead.
5346 ///
5347 /// If you know you'll be using `Nearest`, consider using [`Float::sub_mul_rational_prec`]
5348 /// instead. If you know that your target precision is the maximum of the precisions of the
5349 /// inputs, consider using [`Float::sub_mul_rational_round`] instead. If both of these things
5350 /// are true, consider using
5351 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
5352 ///
5353 /// # Worst-case complexity
5354 /// $T(n, m) = O(n \log n \log\log n + m)$
5355 ///
5356 /// $M(n, m) = O(n \log n + m)$
5357 ///
5358 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5359 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5360 /// prec)`.
5361 ///
5362 /// # Panics
5363 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
5364 /// exactly representable with `prec` bits.
5365 ///
5366 /// # Examples
5367 /// ```
5368 /// use core::f64::consts::{E, PI};
5369 /// use malachite_base::rounding_modes::RoundingMode::*;
5370 /// use malachite_float::Float;
5371 /// use malachite_q::Rational;
5372 /// use std::cmp::Ordering::*;
5373 ///
5374 /// let x = Float::from(PI);
5375 /// let y = Float::from(E);
5376 /// let z = Rational::from_signeds(22, 7);
5377 ///
5378 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_ref_ref(&y, &z, 5, Floor);
5379 /// assert_eq!(diff.to_string(), "-5.50");
5380 /// assert_eq!(o, Less);
5381 ///
5382 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_ref_ref(&y, &z, 5, Ceiling);
5383 /// assert_eq!(diff.to_string(), "-5.25");
5384 /// assert_eq!(o, Greater);
5385 ///
5386 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_ref_ref(&y, &z, 5, Nearest);
5387 /// assert_eq!(diff.to_string(), "-5.50");
5388 /// assert_eq!(o, Less);
5389 ///
5390 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_ref_ref(&y, &z, 20, Floor);
5391 /// assert_eq!(diff.to_string(), "-5.4015808");
5392 /// assert_eq!(o, Less);
5393 ///
5394 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_ref_ref(&y, &z, 20, Ceiling);
5395 /// assert_eq!(diff.to_string(), "-5.4015732");
5396 /// assert_eq!(o, Greater);
5397 ///
5398 /// let (diff, o) = x.sub_mul_rational_prec_round_ref_ref_ref(&y, &z, 20, Nearest);
5399 /// assert_eq!(diff.to_string(), "-5.4015808");
5400 /// assert_eq!(o, Less);
5401 /// ```
5402 #[inline]
5403 pub fn sub_mul_rational_prec_round_ref_ref_ref(
5404 &self,
5405 y: &Self,
5406 z: &Rational,
5407 prec: u64,
5408 rm: RoundingMode,
5409 ) -> (Self, Ordering) {
5410 add_mul_rational_helper(self, y, z, true, prec, rm)
5411 }
5412
5413 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place, rounding
5414 /// the result to the specified precision and with the specified rounding mode. The [`Float`]
5415 /// and the [`Rational`] on the right-hand side are both taken by value. An [`Ordering`] is
5416 /// returned, indicating whether the rounded diff is less than, equal to, or greater than the
5417 /// exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
5418 /// assigns a `NaN` it also returns `Equal`.
5419 ///
5420 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5421 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
5422 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5423 ///
5424 /// See [`RoundingMode`] for a description of the possible rounding modes.
5425 ///
5426 /// $$
5427 /// x \gets x-yz+\varepsilon.
5428 /// $$
5429 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5430 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5431 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
5432 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5433 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
5434 ///
5435 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
5436 /// cases, overflow, and underflow.
5437 ///
5438 /// If you know you'll be using `Nearest`, consider using
5439 /// [`Float::sub_mul_rational_prec_assign`] instead. If you know that your target precision is
5440 /// the maximum of the precisions of the inputs, consider using
5441 /// [`Float::sub_mul_rational_round_assign`] instead. If both of these things are true, consider
5442 /// using
5443 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
5444 /// instead.
5445 ///
5446 /// # Worst-case complexity
5447 /// $T(n, m) = O(n \log n \log\log n + m)$
5448 ///
5449 /// $M(n, m) = O(n \log n + m)$
5450 ///
5451 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5452 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5453 /// prec)`.
5454 ///
5455 /// # Panics
5456 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
5457 /// exactly representable with `prec` bits.
5458 ///
5459 /// # Examples
5460 /// ```
5461 /// use core::f64::consts::{E, PI};
5462 /// use malachite_base::rounding_modes::RoundingMode::*;
5463 /// use malachite_float::Float;
5464 /// use malachite_q::Rational;
5465 /// use std::cmp::Ordering::*;
5466 ///
5467 /// let y = Float::from(E);
5468 /// let z = Rational::from_signeds(22, 7);
5469 ///
5470 /// let mut x = Float::from(PI);
5471 /// assert_eq!(
5472 /// x.sub_mul_rational_prec_round_assign(y.clone(), z.clone(), 5, Floor),
5473 /// Less
5474 /// );
5475 /// assert_eq!(x.to_string(), "-5.50");
5476 ///
5477 /// let mut x = Float::from(PI);
5478 /// assert_eq!(
5479 /// x.sub_mul_rational_prec_round_assign(y.clone(), z.clone(), 5, Ceiling),
5480 /// Greater
5481 /// );
5482 /// assert_eq!(x.to_string(), "-5.25");
5483 ///
5484 /// let mut x = Float::from(PI);
5485 /// assert_eq!(
5486 /// x.sub_mul_rational_prec_round_assign(y.clone(), z.clone(), 5, Nearest),
5487 /// Less
5488 /// );
5489 /// assert_eq!(x.to_string(), "-5.50");
5490 /// ```
5491 #[allow(clippy::needless_pass_by_value)]
5492 #[inline]
5493 pub fn sub_mul_rational_prec_round_assign(
5494 &mut self,
5495 y: Self,
5496 z: Rational,
5497 prec: u64,
5498 rm: RoundingMode,
5499 ) -> Ordering {
5500 let (s, o) = add_mul_rational_helper(self, &y, &z, true, prec, rm);
5501 *self = s;
5502 o
5503 }
5504
5505 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place, rounding
5506 /// the result to the specified precision and with the specified rounding mode. The [`Float`] on
5507 /// the right-hand side is taken by value and the [`Rational`] by reference. An [`Ordering`] is
5508 /// returned, indicating whether the rounded diff is less than, equal to, or greater than the
5509 /// exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
5510 /// assigns a `NaN` it also returns `Equal`.
5511 ///
5512 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5513 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
5514 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5515 ///
5516 /// See [`RoundingMode`] for a description of the possible rounding modes.
5517 ///
5518 /// $$
5519 /// x \gets x-yz+\varepsilon.
5520 /// $$
5521 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5522 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5523 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
5524 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5525 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
5526 ///
5527 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
5528 /// cases, overflow, and underflow.
5529 ///
5530 /// If you know you'll be using `Nearest`, consider using
5531 /// [`Float::sub_mul_rational_prec_assign`] instead. If you know that your target precision is
5532 /// the maximum of the precisions of the inputs, consider using
5533 /// [`Float::sub_mul_rational_round_assign`] instead. If both of these things are true, consider
5534 /// using
5535 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
5536 /// instead.
5537 ///
5538 /// # Worst-case complexity
5539 /// $T(n, m) = O(n \log n \log\log n + m)$
5540 ///
5541 /// $M(n, m) = O(n \log n + m)$
5542 ///
5543 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5544 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5545 /// prec)`.
5546 ///
5547 /// # Panics
5548 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
5549 /// exactly representable with `prec` bits.
5550 ///
5551 /// # Examples
5552 /// ```
5553 /// use core::f64::consts::{E, PI};
5554 /// use malachite_base::rounding_modes::RoundingMode::*;
5555 /// use malachite_float::Float;
5556 /// use malachite_q::Rational;
5557 /// use std::cmp::Ordering::*;
5558 ///
5559 /// let y = Float::from(E);
5560 /// let z = Rational::from_signeds(22, 7);
5561 ///
5562 /// let mut x = Float::from(PI);
5563 /// assert_eq!(
5564 /// x.sub_mul_rational_prec_round_assign_val_ref(y.clone(), &z, 5, Floor),
5565 /// Less
5566 /// );
5567 /// assert_eq!(x.to_string(), "-5.50");
5568 ///
5569 /// let mut x = Float::from(PI);
5570 /// assert_eq!(
5571 /// x.sub_mul_rational_prec_round_assign_val_ref(y.clone(), &z, 5, Ceiling),
5572 /// Greater
5573 /// );
5574 /// assert_eq!(x.to_string(), "-5.25");
5575 ///
5576 /// let mut x = Float::from(PI);
5577 /// assert_eq!(
5578 /// x.sub_mul_rational_prec_round_assign_val_ref(y.clone(), &z, 5, Nearest),
5579 /// Less
5580 /// );
5581 /// assert_eq!(x.to_string(), "-5.50");
5582 /// ```
5583 #[allow(clippy::needless_pass_by_value)]
5584 #[inline]
5585 pub fn sub_mul_rational_prec_round_assign_val_ref(
5586 &mut self,
5587 y: Self,
5588 z: &Rational,
5589 prec: u64,
5590 rm: RoundingMode,
5591 ) -> Ordering {
5592 let (s, o) = add_mul_rational_helper(self, &y, z, true, prec, rm);
5593 *self = s;
5594 o
5595 }
5596
5597 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place, rounding
5598 /// the result to the specified precision and with the specified rounding mode. The [`Float`] on
5599 /// the right-hand side is taken by reference and the [`Rational`] by value. An [`Ordering`] is
5600 /// returned, indicating whether the rounded diff is less than, equal to, or greater than the
5601 /// exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
5602 /// assigns a `NaN` it also returns `Equal`.
5603 ///
5604 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5605 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
5606 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5607 ///
5608 /// See [`RoundingMode`] for a description of the possible rounding modes.
5609 ///
5610 /// $$
5611 /// x \gets x-yz+\varepsilon.
5612 /// $$
5613 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5614 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5615 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
5616 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5617 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
5618 ///
5619 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
5620 /// cases, overflow, and underflow.
5621 ///
5622 /// If you know you'll be using `Nearest`, consider using
5623 /// [`Float::sub_mul_rational_prec_assign`] instead. If you know that your target precision is
5624 /// the maximum of the precisions of the inputs, consider using
5625 /// [`Float::sub_mul_rational_round_assign`] instead. If both of these things are true, consider
5626 /// using
5627 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
5628 /// instead.
5629 ///
5630 /// # Worst-case complexity
5631 /// $T(n, m) = O(n \log n \log\log n + m)$
5632 ///
5633 /// $M(n, m) = O(n \log n + m)$
5634 ///
5635 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5636 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5637 /// prec)`.
5638 ///
5639 /// # Panics
5640 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
5641 /// exactly representable with `prec` bits.
5642 ///
5643 /// # Examples
5644 /// ```
5645 /// use core::f64::consts::{E, PI};
5646 /// use malachite_base::rounding_modes::RoundingMode::*;
5647 /// use malachite_float::Float;
5648 /// use malachite_q::Rational;
5649 /// use std::cmp::Ordering::*;
5650 ///
5651 /// let y = Float::from(E);
5652 /// let z = Rational::from_signeds(22, 7);
5653 ///
5654 /// let mut x = Float::from(PI);
5655 /// assert_eq!(
5656 /// x.sub_mul_rational_prec_round_assign_ref_val(&y, z.clone(), 5, Floor),
5657 /// Less
5658 /// );
5659 /// assert_eq!(x.to_string(), "-5.50");
5660 ///
5661 /// let mut x = Float::from(PI);
5662 /// assert_eq!(
5663 /// x.sub_mul_rational_prec_round_assign_ref_val(&y, z.clone(), 5, Ceiling),
5664 /// Greater
5665 /// );
5666 /// assert_eq!(x.to_string(), "-5.25");
5667 ///
5668 /// let mut x = Float::from(PI);
5669 /// assert_eq!(
5670 /// x.sub_mul_rational_prec_round_assign_ref_val(&y, z.clone(), 5, Nearest),
5671 /// Less
5672 /// );
5673 /// assert_eq!(x.to_string(), "-5.50");
5674 /// ```
5675 #[allow(clippy::needless_pass_by_value)]
5676 #[inline]
5677 pub fn sub_mul_rational_prec_round_assign_ref_val(
5678 &mut self,
5679 y: &Self,
5680 z: Rational,
5681 prec: u64,
5682 rm: RoundingMode,
5683 ) -> Ordering {
5684 let (s, o) = add_mul_rational_helper(self, y, &z, true, prec, rm);
5685 *self = s;
5686 o
5687 }
5688
5689 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place, rounding
5690 /// the result to the specified precision and with the specified rounding mode. The [`Float`]
5691 /// and the [`Rational`] on the right-hand side are both taken by reference. An [`Ordering`] is
5692 /// returned, indicating whether the rounded diff is less than, equal to, or greater than the
5693 /// exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
5694 /// assigns a `NaN` it also returns `Equal`.
5695 ///
5696 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5697 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
5698 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5699 ///
5700 /// See [`RoundingMode`] for a description of the possible rounding modes.
5701 ///
5702 /// $$
5703 /// x \gets x-yz+\varepsilon.
5704 /// $$
5705 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5706 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
5707 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$.
5708 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
5709 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$.
5710 ///
5711 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
5712 /// cases, overflow, and underflow.
5713 ///
5714 /// If you know you'll be using `Nearest`, consider using
5715 /// [`Float::sub_mul_rational_prec_assign`] instead. If you know that your target precision is
5716 /// the maximum of the precisions of the inputs, consider using
5717 /// [`Float::sub_mul_rational_round_assign`] instead. If both of these things are true, consider
5718 /// using
5719 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
5720 /// instead.
5721 ///
5722 /// # Worst-case complexity
5723 /// $T(n, m) = O(n \log n \log\log n + m)$
5724 ///
5725 /// $M(n, m) = O(n \log n + m)$
5726 ///
5727 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5728 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5729 /// prec)`.
5730 ///
5731 /// # Panics
5732 /// Panics if `prec` is zero, or if `rm` is `Exact` and the fused multiply-subtract is not
5733 /// exactly representable with `prec` bits.
5734 ///
5735 /// # Examples
5736 /// ```
5737 /// use core::f64::consts::{E, PI};
5738 /// use malachite_base::rounding_modes::RoundingMode::*;
5739 /// use malachite_float::Float;
5740 /// use malachite_q::Rational;
5741 /// use std::cmp::Ordering::*;
5742 ///
5743 /// let y = Float::from(E);
5744 /// let z = Rational::from_signeds(22, 7);
5745 ///
5746 /// let mut x = Float::from(PI);
5747 /// assert_eq!(
5748 /// x.sub_mul_rational_prec_round_assign_ref_ref(&y, &z, 5, Floor),
5749 /// Less
5750 /// );
5751 /// assert_eq!(x.to_string(), "-5.50");
5752 ///
5753 /// let mut x = Float::from(PI);
5754 /// assert_eq!(
5755 /// x.sub_mul_rational_prec_round_assign_ref_ref(&y, &z, 5, Ceiling),
5756 /// Greater
5757 /// );
5758 /// assert_eq!(x.to_string(), "-5.25");
5759 ///
5760 /// let mut x = Float::from(PI);
5761 /// assert_eq!(
5762 /// x.sub_mul_rational_prec_round_assign_ref_ref(&y, &z, 5, Nearest),
5763 /// Less
5764 /// );
5765 /// assert_eq!(x.to_string(), "-5.50");
5766 /// ```
5767 #[inline]
5768 pub fn sub_mul_rational_prec_round_assign_ref_ref(
5769 &mut self,
5770 y: &Self,
5771 z: &Rational,
5772 prec: u64,
5773 rm: RoundingMode,
5774 ) -> Ordering {
5775 let (s, o) = add_mul_rational_helper(self, y, z, true, prec, rm);
5776 *self = s;
5777 o
5778 }
5779
5780 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
5781 /// result to the nearest value of the specified precision. The [`Float`]s and the [`Rational`]
5782 /// are all taken by value. An [`Ordering`] is also returned, indicating whether the rounded
5783 /// diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
5784 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
5785 ///
5786 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5787 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
5788 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5789 ///
5790 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
5791 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
5792 /// the `Nearest` rounding mode.
5793 ///
5794 /// $$
5795 /// f(x,y,z,p) = x-yz+\varepsilon.
5796 /// $$
5797 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5798 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
5799 /// |x-yz|\rfloor-p}$.
5800 ///
5801 /// If the output has a precision, it is `prec`.
5802 ///
5803 /// Special cases:
5804 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
5805 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
5806 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
5807 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
5808 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
5809 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
5810 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
5811 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
5812 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
5813 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
5814 /// zero [`Rational`] counting as positive.
5815 /// - $f(x,y,z,p)=0.0$ if $x=yz$ and $x$ is finite and nonzero
5816 ///
5817 /// Overflow and underflow:
5818 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
5819 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
5820 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
5821 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
5822 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
5823 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
5824 ///
5825 /// If you want to use a rounding mode other than `Nearest`, consider using
5826 /// [`Float::sub_mul_rational_prec_round`] instead. If you know that your target precision is
5827 /// the maximum of the precisions of the inputs, consider using
5828 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
5829 ///
5830 /// # Worst-case complexity
5831 /// $T(n, m) = O(n \log n \log\log n + m)$
5832 ///
5833 /// $M(n, m) = O(n \log n + m)$
5834 ///
5835 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5836 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5837 /// prec)`.
5838 ///
5839 /// # Panics
5840 /// Panics if `prec` is zero.
5841 ///
5842 /// # Examples
5843 /// ```
5844 /// use core::f64::consts::{E, PI};
5845 /// use malachite_float::Float;
5846 /// use malachite_q::Rational;
5847 /// use std::cmp::Ordering::*;
5848 ///
5849 /// let x = Float::from(PI);
5850 /// let y = Float::from(E);
5851 /// let z = Rational::from_signeds(22, 7);
5852 ///
5853 /// let (diff, o) = x.clone().sub_mul_rational_prec(y.clone(), z.clone(), 5);
5854 /// assert_eq!(diff.to_string(), "-5.50");
5855 /// assert_eq!(o, Less);
5856 ///
5857 /// let (diff, o) = x.clone().sub_mul_rational_prec(y.clone(), z.clone(), 20);
5858 /// assert_eq!(diff.to_string(), "-5.4015808");
5859 /// assert_eq!(o, Less);
5860 /// ```
5861 #[allow(clippy::needless_pass_by_value)]
5862 #[inline]
5863 pub fn sub_mul_rational_prec(self, y: Self, z: Rational, prec: u64) -> (Self, Ordering) {
5864 self.sub_mul_rational_prec_round(y, z, prec, Nearest)
5865 }
5866
5867 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
5868 /// result to the nearest value of the specified precision. The [`Float`]s are taken by value
5869 /// and the [`Rational`] by reference. An [`Ordering`] is also returned, indicating whether the
5870 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
5871 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
5872 ///
5873 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5874 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
5875 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5876 ///
5877 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
5878 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
5879 /// the `Nearest` rounding mode.
5880 ///
5881 /// $$
5882 /// f(x,y,z,p) = x-yz+\varepsilon.
5883 /// $$
5884 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5885 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
5886 /// |x-yz|\rfloor-p}$.
5887 ///
5888 /// If the output has a precision, it is `prec`.
5889 ///
5890 /// Special cases:
5891 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
5892 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
5893 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
5894 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
5895 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
5896 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
5897 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
5898 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
5899 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
5900 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
5901 /// zero [`Rational`] counting as positive.
5902 /// - $f(x,y,z,p)=0.0$ if $x=yz$ and $x$ is finite and nonzero
5903 ///
5904 /// Overflow and underflow:
5905 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
5906 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
5907 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
5908 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
5909 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
5910 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
5911 ///
5912 /// If you want to use a rounding mode other than `Nearest`, consider using
5913 /// [`Float::sub_mul_rational_prec_round`] instead. If you know that your target precision is
5914 /// the maximum of the precisions of the inputs, consider using
5915 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
5916 ///
5917 /// # Worst-case complexity
5918 /// $T(n, m) = O(n \log n \log\log n + m)$
5919 ///
5920 /// $M(n, m) = O(n \log n + m)$
5921 ///
5922 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
5923 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
5924 /// prec)`.
5925 ///
5926 /// # Panics
5927 /// Panics if `prec` is zero.
5928 ///
5929 /// # Examples
5930 /// ```
5931 /// use core::f64::consts::{E, PI};
5932 /// use malachite_float::Float;
5933 /// use malachite_q::Rational;
5934 /// use std::cmp::Ordering::*;
5935 ///
5936 /// let x = Float::from(PI);
5937 /// let y = Float::from(E);
5938 /// let z = Rational::from_signeds(22, 7);
5939 ///
5940 /// let (diff, o) = x
5941 /// .clone()
5942 /// .sub_mul_rational_prec_val_val_ref(y.clone(), &z, 5);
5943 /// assert_eq!(diff.to_string(), "-5.50");
5944 /// assert_eq!(o, Less);
5945 ///
5946 /// let (diff, o) = x
5947 /// .clone()
5948 /// .sub_mul_rational_prec_val_val_ref(y.clone(), &z, 20);
5949 /// assert_eq!(diff.to_string(), "-5.4015808");
5950 /// assert_eq!(o, Less);
5951 /// ```
5952 #[allow(clippy::needless_pass_by_value)]
5953 #[inline]
5954 pub fn sub_mul_rational_prec_val_val_ref(
5955 self,
5956 y: Self,
5957 z: &Rational,
5958 prec: u64,
5959 ) -> (Self, Ordering) {
5960 self.sub_mul_rational_prec_round_val_val_ref(y, z, prec, Nearest)
5961 }
5962
5963 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
5964 /// result to the nearest value of the specified precision. The first [`Float`] and the
5965 /// [`Rational`] are taken by value and the second [`Float`] by reference. An [`Ordering`] is
5966 /// also returned, indicating whether the rounded diff is less than, equal to, or greater than
5967 /// the exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
5968 /// returns a `NaN` it also returns `Equal`.
5969 ///
5970 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
5971 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
5972 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
5973 ///
5974 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
5975 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
5976 /// the `Nearest` rounding mode.
5977 ///
5978 /// $$
5979 /// f(x,y,z,p) = x-yz+\varepsilon.
5980 /// $$
5981 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5982 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
5983 /// |x-yz|\rfloor-p}$.
5984 ///
5985 /// If the output has a precision, it is `prec`.
5986 ///
5987 /// Special cases:
5988 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
5989 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
5990 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
5991 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
5992 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
5993 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
5994 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
5995 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
5996 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
5997 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
5998 /// zero [`Rational`] counting as positive.
5999 /// - $f(x,y,z,p)=0.0$ if $x=yz$ and $x$ is finite and nonzero
6000 ///
6001 /// Overflow and underflow:
6002 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
6003 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
6004 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
6005 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
6006 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
6007 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
6008 ///
6009 /// If you want to use a rounding mode other than `Nearest`, consider using
6010 /// [`Float::sub_mul_rational_prec_round`] instead. If you know that your target precision is
6011 /// the maximum of the precisions of the inputs, consider using
6012 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
6013 ///
6014 /// # Worst-case complexity
6015 /// $T(n, m) = O(n \log n \log\log n + m)$
6016 ///
6017 /// $M(n, m) = O(n \log n + m)$
6018 ///
6019 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6020 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6021 /// prec)`.
6022 ///
6023 /// # Panics
6024 /// Panics if `prec` is zero.
6025 ///
6026 /// # Examples
6027 /// ```
6028 /// use core::f64::consts::{E, PI};
6029 /// use malachite_float::Float;
6030 /// use malachite_q::Rational;
6031 /// use std::cmp::Ordering::*;
6032 ///
6033 /// let x = Float::from(PI);
6034 /// let y = Float::from(E);
6035 /// let z = Rational::from_signeds(22, 7);
6036 ///
6037 /// let (diff, o) = x
6038 /// .clone()
6039 /// .sub_mul_rational_prec_val_ref_val(&y, z.clone(), 5);
6040 /// assert_eq!(diff.to_string(), "-5.50");
6041 /// assert_eq!(o, Less);
6042 ///
6043 /// let (diff, o) = x
6044 /// .clone()
6045 /// .sub_mul_rational_prec_val_ref_val(&y, z.clone(), 20);
6046 /// assert_eq!(diff.to_string(), "-5.4015808");
6047 /// assert_eq!(o, Less);
6048 /// ```
6049 #[allow(clippy::needless_pass_by_value)]
6050 #[inline]
6051 pub fn sub_mul_rational_prec_val_ref_val(
6052 self,
6053 y: &Self,
6054 z: Rational,
6055 prec: u64,
6056 ) -> (Self, Ordering) {
6057 self.sub_mul_rational_prec_round_val_ref_val(y, z, prec, Nearest)
6058 }
6059
6060 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
6061 /// result to the nearest value of the specified precision. The first [`Float`] is taken by
6062 /// value and the second [`Float`] and the [`Rational`] by reference. An [`Ordering`] is also
6063 /// returned, indicating whether the rounded diff is less than, equal to, or greater than the
6064 /// exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
6065 /// returns a `NaN` it also returns `Equal`.
6066 ///
6067 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6068 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
6069 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6070 ///
6071 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6072 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6073 /// the `Nearest` rounding mode.
6074 ///
6075 /// $$
6076 /// f(x,y,z,p) = x-yz+\varepsilon.
6077 /// $$
6078 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6079 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6080 /// |x-yz|\rfloor-p}$.
6081 ///
6082 /// If the output has a precision, it is `prec`.
6083 ///
6084 /// Special cases:
6085 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
6086 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
6087 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
6088 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
6089 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
6090 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
6091 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
6092 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
6093 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
6094 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
6095 /// zero [`Rational`] counting as positive.
6096 /// - $f(x,y,z,p)=0.0$ if $x=yz$ and $x$ is finite and nonzero
6097 ///
6098 /// Overflow and underflow:
6099 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
6100 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
6101 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
6102 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
6103 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
6104 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
6105 ///
6106 /// If you want to use a rounding mode other than `Nearest`, consider using
6107 /// [`Float::sub_mul_rational_prec_round`] instead. If you know that your target precision is
6108 /// the maximum of the precisions of the inputs, consider using
6109 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
6110 ///
6111 /// # Worst-case complexity
6112 /// $T(n, m) = O(n \log n \log\log n + m)$
6113 ///
6114 /// $M(n, m) = O(n \log n + m)$
6115 ///
6116 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6117 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6118 /// prec)`.
6119 ///
6120 /// # Panics
6121 /// Panics if `prec` is zero.
6122 ///
6123 /// # Examples
6124 /// ```
6125 /// use core::f64::consts::{E, PI};
6126 /// use malachite_float::Float;
6127 /// use malachite_q::Rational;
6128 /// use std::cmp::Ordering::*;
6129 ///
6130 /// let x = Float::from(PI);
6131 /// let y = Float::from(E);
6132 /// let z = Rational::from_signeds(22, 7);
6133 ///
6134 /// let (diff, o) = x.clone().sub_mul_rational_prec_val_ref_ref(&y, &z, 5);
6135 /// assert_eq!(diff.to_string(), "-5.50");
6136 /// assert_eq!(o, Less);
6137 ///
6138 /// let (diff, o) = x.clone().sub_mul_rational_prec_val_ref_ref(&y, &z, 20);
6139 /// assert_eq!(diff.to_string(), "-5.4015808");
6140 /// assert_eq!(o, Less);
6141 /// ```
6142 #[allow(clippy::needless_pass_by_value)]
6143 #[inline]
6144 pub fn sub_mul_rational_prec_val_ref_ref(
6145 self,
6146 y: &Self,
6147 z: &Rational,
6148 prec: u64,
6149 ) -> (Self, Ordering) {
6150 self.sub_mul_rational_prec_round_val_ref_ref(y, z, prec, Nearest)
6151 }
6152
6153 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
6154 /// result to the nearest value of the specified precision. The first [`Float`] is taken by
6155 /// reference and the second [`Float`] and the [`Rational`] by value. An [`Ordering`] is also
6156 /// returned, indicating whether the rounded diff is less than, equal to, or greater than the
6157 /// exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
6158 /// returns a `NaN` it also returns `Equal`.
6159 ///
6160 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6161 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
6162 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6163 ///
6164 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6165 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6166 /// the `Nearest` rounding mode.
6167 ///
6168 /// $$
6169 /// f(x,y,z,p) = x-yz+\varepsilon.
6170 /// $$
6171 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6172 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6173 /// |x-yz|\rfloor-p}$.
6174 ///
6175 /// If the output has a precision, it is `prec`.
6176 ///
6177 /// Special cases:
6178 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
6179 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
6180 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
6181 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
6182 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
6183 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
6184 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
6185 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
6186 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
6187 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
6188 /// zero [`Rational`] counting as positive.
6189 /// - $f(x,y,z,p)=0.0$ if $x=yz$ and $x$ is finite and nonzero
6190 ///
6191 /// Overflow and underflow:
6192 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
6193 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
6194 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
6195 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
6196 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
6197 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
6198 ///
6199 /// If you want to use a rounding mode other than `Nearest`, consider using
6200 /// [`Float::sub_mul_rational_prec_round`] instead. If you know that your target precision is
6201 /// the maximum of the precisions of the inputs, consider using
6202 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
6203 ///
6204 /// # Worst-case complexity
6205 /// $T(n, m) = O(n \log n \log\log n + m)$
6206 ///
6207 /// $M(n, m) = O(n \log n + m)$
6208 ///
6209 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6210 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6211 /// prec)`.
6212 ///
6213 /// # Panics
6214 /// Panics if `prec` is zero.
6215 ///
6216 /// # Examples
6217 /// ```
6218 /// use core::f64::consts::{E, PI};
6219 /// use malachite_float::Float;
6220 /// use malachite_q::Rational;
6221 /// use std::cmp::Ordering::*;
6222 ///
6223 /// let x = Float::from(PI);
6224 /// let y = Float::from(E);
6225 /// let z = Rational::from_signeds(22, 7);
6226 ///
6227 /// let (diff, o) = x.sub_mul_rational_prec_ref_val_val(y.clone(), z.clone(), 5);
6228 /// assert_eq!(diff.to_string(), "-5.50");
6229 /// assert_eq!(o, Less);
6230 ///
6231 /// let (diff, o) = x.sub_mul_rational_prec_ref_val_val(y.clone(), z.clone(), 20);
6232 /// assert_eq!(diff.to_string(), "-5.4015808");
6233 /// assert_eq!(o, Less);
6234 /// ```
6235 #[allow(clippy::needless_pass_by_value)]
6236 #[inline]
6237 pub fn sub_mul_rational_prec_ref_val_val(
6238 &self,
6239 y: Self,
6240 z: Rational,
6241 prec: u64,
6242 ) -> (Self, Ordering) {
6243 self.sub_mul_rational_prec_round_ref_val_val(y, z, prec, Nearest)
6244 }
6245
6246 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
6247 /// result to the nearest value of the specified precision. The second [`Float`] is taken by
6248 /// value and the first [`Float`] and the [`Rational`] by reference. An [`Ordering`] is also
6249 /// returned, indicating whether the rounded diff is less than, equal to, or greater than the
6250 /// exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
6251 /// returns a `NaN` it also returns `Equal`.
6252 ///
6253 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6254 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
6255 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6256 ///
6257 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6258 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6259 /// the `Nearest` rounding mode.
6260 ///
6261 /// $$
6262 /// f(x,y,z,p) = x-yz+\varepsilon.
6263 /// $$
6264 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6265 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6266 /// |x-yz|\rfloor-p}$.
6267 ///
6268 /// If the output has a precision, it is `prec`.
6269 ///
6270 /// Special cases:
6271 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
6272 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
6273 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
6274 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
6275 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
6276 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
6277 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
6278 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
6279 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
6280 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
6281 /// zero [`Rational`] counting as positive.
6282 /// - $f(x,y,z,p)=0.0$ if $x=yz$ and $x$ is finite and nonzero
6283 ///
6284 /// Overflow and underflow:
6285 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
6286 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
6287 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
6288 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
6289 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
6290 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
6291 ///
6292 /// If you want to use a rounding mode other than `Nearest`, consider using
6293 /// [`Float::sub_mul_rational_prec_round`] instead. If you know that your target precision is
6294 /// the maximum of the precisions of the inputs, consider using
6295 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
6296 ///
6297 /// # Worst-case complexity
6298 /// $T(n, m) = O(n \log n \log\log n + m)$
6299 ///
6300 /// $M(n, m) = O(n \log n + m)$
6301 ///
6302 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6303 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6304 /// prec)`.
6305 ///
6306 /// # Panics
6307 /// Panics if `prec` is zero.
6308 ///
6309 /// # Examples
6310 /// ```
6311 /// use core::f64::consts::{E, PI};
6312 /// use malachite_float::Float;
6313 /// use malachite_q::Rational;
6314 /// use std::cmp::Ordering::*;
6315 ///
6316 /// let x = Float::from(PI);
6317 /// let y = Float::from(E);
6318 /// let z = Rational::from_signeds(22, 7);
6319 ///
6320 /// let (diff, o) = x.sub_mul_rational_prec_ref_val_ref(y.clone(), &z, 5);
6321 /// assert_eq!(diff.to_string(), "-5.50");
6322 /// assert_eq!(o, Less);
6323 ///
6324 /// let (diff, o) = x.sub_mul_rational_prec_ref_val_ref(y.clone(), &z, 20);
6325 /// assert_eq!(diff.to_string(), "-5.4015808");
6326 /// assert_eq!(o, Less);
6327 /// ```
6328 #[allow(clippy::needless_pass_by_value)]
6329 #[inline]
6330 pub fn sub_mul_rational_prec_ref_val_ref(
6331 &self,
6332 y: Self,
6333 z: &Rational,
6334 prec: u64,
6335 ) -> (Self, Ordering) {
6336 self.sub_mul_rational_prec_round_ref_val_ref(y, z, prec, Nearest)
6337 }
6338
6339 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
6340 /// result to the nearest value of the specified precision. The [`Float`]s are taken by
6341 /// reference and the [`Rational`] by value. An [`Ordering`] is also returned, indicating
6342 /// whether the rounded diff is less than, equal to, or greater than the exact diff. Although
6343 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
6344 /// returns `Equal`.
6345 ///
6346 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6347 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
6348 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6349 ///
6350 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6351 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6352 /// the `Nearest` rounding mode.
6353 ///
6354 /// $$
6355 /// f(x,y,z,p) = x-yz+\varepsilon.
6356 /// $$
6357 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6358 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6359 /// |x-yz|\rfloor-p}$.
6360 ///
6361 /// If the output has a precision, it is `prec`.
6362 ///
6363 /// Special cases:
6364 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
6365 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
6366 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
6367 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
6368 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
6369 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
6370 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
6371 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
6372 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
6373 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
6374 /// zero [`Rational`] counting as positive.
6375 /// - $f(x,y,z,p)=0.0$ if $x=yz$ and $x$ is finite and nonzero
6376 ///
6377 /// Overflow and underflow:
6378 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
6379 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
6380 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
6381 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
6382 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
6383 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
6384 ///
6385 /// If you want to use a rounding mode other than `Nearest`, consider using
6386 /// [`Float::sub_mul_rational_prec_round`] instead. If you know that your target precision is
6387 /// the maximum of the precisions of the inputs, consider using
6388 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
6389 ///
6390 /// # Worst-case complexity
6391 /// $T(n, m) = O(n \log n \log\log n + m)$
6392 ///
6393 /// $M(n, m) = O(n \log n + m)$
6394 ///
6395 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6396 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6397 /// prec)`.
6398 ///
6399 /// # Panics
6400 /// Panics if `prec` is zero.
6401 ///
6402 /// # Examples
6403 /// ```
6404 /// use core::f64::consts::{E, PI};
6405 /// use malachite_float::Float;
6406 /// use malachite_q::Rational;
6407 /// use std::cmp::Ordering::*;
6408 ///
6409 /// let x = Float::from(PI);
6410 /// let y = Float::from(E);
6411 /// let z = Rational::from_signeds(22, 7);
6412 ///
6413 /// let (diff, o) = x.sub_mul_rational_prec_ref_ref_val(&y, z.clone(), 5);
6414 /// assert_eq!(diff.to_string(), "-5.50");
6415 /// assert_eq!(o, Less);
6416 ///
6417 /// let (diff, o) = x.sub_mul_rational_prec_ref_ref_val(&y, z.clone(), 20);
6418 /// assert_eq!(diff.to_string(), "-5.4015808");
6419 /// assert_eq!(o, Less);
6420 /// ```
6421 #[allow(clippy::needless_pass_by_value)]
6422 #[inline]
6423 pub fn sub_mul_rational_prec_ref_ref_val(
6424 &self,
6425 y: &Self,
6426 z: Rational,
6427 prec: u64,
6428 ) -> (Self, Ordering) {
6429 self.sub_mul_rational_prec_round_ref_ref_val(y, z, prec, Nearest)
6430 }
6431
6432 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
6433 /// result to the nearest value of the specified precision. The [`Float`]s and the [`Rational`]
6434 /// are all taken by reference. An [`Ordering`] is also returned, indicating whether the rounded
6435 /// diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
6436 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
6437 ///
6438 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6439 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
6440 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6441 ///
6442 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6443 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6444 /// the `Nearest` rounding mode.
6445 ///
6446 /// $$
6447 /// f(x,y,z,p) = x-yz+\varepsilon.
6448 /// $$
6449 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6450 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6451 /// |x-yz|\rfloor-p}$.
6452 ///
6453 /// If the output has a precision, it is `prec`.
6454 ///
6455 /// Special cases:
6456 /// - $f(\text{NaN},y,z,p)=f(x,\text{NaN},z,p)=\text{NaN}$
6457 /// - $f(x,\pm\infty,0,p)=\text{NaN}$
6458 /// - $f(\infty,y,z,p)=\text{NaN}$ if $yz=\infty$
6459 /// - $f(-\infty,y,z,p)=\text{NaN}$ if $yz=-\infty$
6460 /// - $f(\infty,y,z,p)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
6461 /// - $f(-\infty,y,z,p)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
6462 /// - $f(x,y,z,p)=-\infty$ if $x$ is finite and $yz=\infty$
6463 /// - $f(x,y,z,p)=\infty$ if $x$ is finite and $yz=-\infty$
6464 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
6465 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
6466 /// zero [`Rational`] counting as positive.
6467 /// - $f(x,y,z,p)=0.0$ if $x=yz$ and $x$ is finite and nonzero
6468 ///
6469 /// Overflow and underflow:
6470 /// - If $f(x,y,z,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
6471 /// - If $f(x,y,z,p)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
6472 /// - If $0<f(x,y,z,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
6473 /// - If $2^{-2^{30}-1}<f(x,y,z,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
6474 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,p)<0$, $-0.0$ is returned instead.
6475 /// - If $-2^{-2^{30}}<f(x,y,z,p)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
6476 ///
6477 /// If you want to use a rounding mode other than `Nearest`, consider using
6478 /// [`Float::sub_mul_rational_prec_round`] instead. If you know that your target precision is
6479 /// the maximum of the precisions of the inputs, consider using
6480 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
6481 ///
6482 /// # Worst-case complexity
6483 /// $T(n, m) = O(n \log n \log\log n + m)$
6484 ///
6485 /// $M(n, m) = O(n \log n + m)$
6486 ///
6487 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6488 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6489 /// prec)`.
6490 ///
6491 /// # Panics
6492 /// Panics if `prec` is zero.
6493 ///
6494 /// # Examples
6495 /// ```
6496 /// use core::f64::consts::{E, PI};
6497 /// use malachite_float::Float;
6498 /// use malachite_q::Rational;
6499 /// use std::cmp::Ordering::*;
6500 ///
6501 /// let x = Float::from(PI);
6502 /// let y = Float::from(E);
6503 /// let z = Rational::from_signeds(22, 7);
6504 ///
6505 /// let (diff, o) = x.sub_mul_rational_prec_ref_ref_ref(&y, &z, 5);
6506 /// assert_eq!(diff.to_string(), "-5.50");
6507 /// assert_eq!(o, Less);
6508 ///
6509 /// let (diff, o) = x.sub_mul_rational_prec_ref_ref_ref(&y, &z, 20);
6510 /// assert_eq!(diff.to_string(), "-5.4015808");
6511 /// assert_eq!(o, Less);
6512 /// ```
6513 #[inline]
6514 pub fn sub_mul_rational_prec_ref_ref_ref(
6515 &self,
6516 y: &Self,
6517 z: &Rational,
6518 prec: u64,
6519 ) -> (Self, Ordering) {
6520 self.sub_mul_rational_prec_round_ref_ref_ref(y, z, prec, Nearest)
6521 }
6522
6523 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place, rounding
6524 /// the result to the nearest value of the specified precision. The [`Float`] and the
6525 /// [`Rational`] on the right-hand side are both taken by value. An [`Ordering`] is returned,
6526 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
6527 /// Although `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN`
6528 /// it also returns `Equal`.
6529 ///
6530 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6531 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
6532 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6533 ///
6534 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6535 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6536 /// the `Nearest` rounding mode.
6537 ///
6538 /// $$
6539 /// x \gets x-yz+\varepsilon.
6540 /// $$
6541 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6542 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6543 /// |x-yz|\rfloor-p}$.
6544 ///
6545 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
6546 /// cases, overflow, and underflow.
6547 ///
6548 /// If you want to use a rounding mode other than `Nearest`, consider using
6549 /// [`Float::sub_mul_rational_prec_round_assign`] instead. If you know that your target
6550 /// precision is the maximum of the precisions of the inputs, consider using
6551 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
6552 /// instead.
6553 ///
6554 /// # Worst-case complexity
6555 /// $T(n, m) = O(n \log n \log\log n + m)$
6556 ///
6557 /// $M(n, m) = O(n \log n + m)$
6558 ///
6559 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6560 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6561 /// prec)`.
6562 ///
6563 /// # Panics
6564 /// Panics if `prec` is zero.
6565 ///
6566 /// # Examples
6567 /// ```
6568 /// use core::f64::consts::{E, PI};
6569 /// use malachite_float::Float;
6570 /// use malachite_q::Rational;
6571 /// use std::cmp::Ordering::*;
6572 ///
6573 /// let y = Float::from(E);
6574 /// let z = Rational::from_signeds(22, 7);
6575 ///
6576 /// let mut x = Float::from(PI);
6577 /// assert_eq!(
6578 /// x.sub_mul_rational_prec_assign(y.clone(), z.clone(), 5),
6579 /// Less
6580 /// );
6581 /// assert_eq!(x.to_string(), "-5.50");
6582 ///
6583 /// let mut x = Float::from(PI);
6584 /// assert_eq!(
6585 /// x.sub_mul_rational_prec_assign(y.clone(), z.clone(), 20),
6586 /// Less
6587 /// );
6588 /// assert_eq!(x.to_string(), "-5.4015808");
6589 /// ```
6590 #[allow(clippy::needless_pass_by_value)]
6591 #[inline]
6592 pub fn sub_mul_rational_prec_assign(&mut self, y: Self, z: Rational, prec: u64) -> Ordering {
6593 self.sub_mul_rational_prec_round_assign(y, z, prec, Nearest)
6594 }
6595
6596 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place, rounding
6597 /// the result to the nearest value of the specified precision. The [`Float`] on the right-hand
6598 /// side is taken by value and the [`Rational`] by reference. An [`Ordering`] is returned,
6599 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
6600 /// Although `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN`
6601 /// it also returns `Equal`.
6602 ///
6603 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6604 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
6605 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6606 ///
6607 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6608 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6609 /// the `Nearest` rounding mode.
6610 ///
6611 /// $$
6612 /// x \gets x-yz+\varepsilon.
6613 /// $$
6614 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6615 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6616 /// |x-yz|\rfloor-p}$.
6617 ///
6618 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
6619 /// cases, overflow, and underflow.
6620 ///
6621 /// If you want to use a rounding mode other than `Nearest`, consider using
6622 /// [`Float::sub_mul_rational_prec_round_assign`] instead. If you know that your target
6623 /// precision is the maximum of the precisions of the inputs, consider using
6624 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
6625 /// instead.
6626 ///
6627 /// # Worst-case complexity
6628 /// $T(n, m) = O(n \log n \log\log n + m)$
6629 ///
6630 /// $M(n, m) = O(n \log n + m)$
6631 ///
6632 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6633 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6634 /// prec)`.
6635 ///
6636 /// # Panics
6637 /// Panics if `prec` is zero.
6638 ///
6639 /// # Examples
6640 /// ```
6641 /// use core::f64::consts::{E, PI};
6642 /// use malachite_float::Float;
6643 /// use malachite_q::Rational;
6644 /// use std::cmp::Ordering::*;
6645 ///
6646 /// let y = Float::from(E);
6647 /// let z = Rational::from_signeds(22, 7);
6648 ///
6649 /// let mut x = Float::from(PI);
6650 /// assert_eq!(
6651 /// x.sub_mul_rational_prec_assign_val_ref(y.clone(), &z, 5),
6652 /// Less
6653 /// );
6654 /// assert_eq!(x.to_string(), "-5.50");
6655 ///
6656 /// let mut x = Float::from(PI);
6657 /// assert_eq!(
6658 /// x.sub_mul_rational_prec_assign_val_ref(y.clone(), &z, 20),
6659 /// Less
6660 /// );
6661 /// assert_eq!(x.to_string(), "-5.4015808");
6662 /// ```
6663 #[allow(clippy::needless_pass_by_value)]
6664 #[inline]
6665 pub fn sub_mul_rational_prec_assign_val_ref(
6666 &mut self,
6667 y: Self,
6668 z: &Rational,
6669 prec: u64,
6670 ) -> Ordering {
6671 self.sub_mul_rational_prec_round_assign_val_ref(y, z, prec, Nearest)
6672 }
6673
6674 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place, rounding
6675 /// the result to the nearest value of the specified precision. The [`Float`] on the right-hand
6676 /// side is taken by reference and the [`Rational`] by value. An [`Ordering`] is returned,
6677 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
6678 /// Although `NaN`s are not comparable to any [`Float`], whenever this function assigns a `NaN`
6679 /// it also returns `Equal`.
6680 ///
6681 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6682 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
6683 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6684 ///
6685 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6686 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6687 /// the `Nearest` rounding mode.
6688 ///
6689 /// $$
6690 /// x \gets x-yz+\varepsilon.
6691 /// $$
6692 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6693 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6694 /// |x-yz|\rfloor-p}$.
6695 ///
6696 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
6697 /// cases, overflow, and underflow.
6698 ///
6699 /// If you want to use a rounding mode other than `Nearest`, consider using
6700 /// [`Float::sub_mul_rational_prec_round_assign`] instead. If you know that your target
6701 /// precision is the maximum of the precisions of the inputs, consider using
6702 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
6703 /// instead.
6704 ///
6705 /// # Worst-case complexity
6706 /// $T(n, m) = O(n \log n \log\log n + m)$
6707 ///
6708 /// $M(n, m) = O(n \log n + m)$
6709 ///
6710 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6711 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6712 /// prec)`.
6713 ///
6714 /// # Panics
6715 /// Panics if `prec` is zero.
6716 ///
6717 /// # Examples
6718 /// ```
6719 /// use core::f64::consts::{E, PI};
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 = Rational::from_signeds(22, 7);
6726 ///
6727 /// let mut x = Float::from(PI);
6728 /// assert_eq!(
6729 /// x.sub_mul_rational_prec_assign_ref_val(&y, z.clone(), 5),
6730 /// Less
6731 /// );
6732 /// assert_eq!(x.to_string(), "-5.50");
6733 ///
6734 /// let mut x = Float::from(PI);
6735 /// assert_eq!(
6736 /// x.sub_mul_rational_prec_assign_ref_val(&y, z.clone(), 20),
6737 /// Less
6738 /// );
6739 /// assert_eq!(x.to_string(), "-5.4015808");
6740 /// ```
6741 #[allow(clippy::needless_pass_by_value)]
6742 #[inline]
6743 pub fn sub_mul_rational_prec_assign_ref_val(
6744 &mut self,
6745 y: &Self,
6746 z: Rational,
6747 prec: u64,
6748 ) -> Ordering {
6749 self.sub_mul_rational_prec_round_assign_ref_val(y, z, prec, Nearest)
6750 }
6751
6752 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place, rounding
6753 /// the result to the nearest value of the specified precision. The [`Float`] and the
6754 /// [`Rational`] on the right-hand side are both taken by reference. An [`Ordering`] is
6755 /// returned, indicating whether the rounded diff is less than, equal to, or greater than the
6756 /// exact diff. Although `NaN`s are not comparable to any [`Float`], whenever this function
6757 /// assigns a `NaN` it also returns `Equal`.
6758 ///
6759 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6760 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
6761 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6762 ///
6763 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
6764 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
6765 /// the `Nearest` rounding mode.
6766 ///
6767 /// $$
6768 /// x \gets x-yz+\varepsilon.
6769 /// $$
6770 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6771 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
6772 /// |x-yz|\rfloor-p}$.
6773 ///
6774 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
6775 /// cases, overflow, and underflow.
6776 ///
6777 /// If you want to use a rounding mode other than `Nearest`, consider using
6778 /// [`Float::sub_mul_rational_prec_round_assign`] instead. If you know that your target
6779 /// precision is the maximum of the precisions of the inputs, consider using
6780 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
6781 /// instead.
6782 ///
6783 /// # Worst-case complexity
6784 /// $T(n, m) = O(n \log n \log\log n + m)$
6785 ///
6786 /// $M(n, m) = O(n \log n + m)$
6787 ///
6788 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6789 /// y.significant_bits() + z.significant_bits()`, and $m$ is `max(self.significant_bits(),
6790 /// prec)`.
6791 ///
6792 /// # Panics
6793 /// Panics if `prec` is zero.
6794 ///
6795 /// # Examples
6796 /// ```
6797 /// use core::f64::consts::{E, PI};
6798 /// use malachite_float::Float;
6799 /// use malachite_q::Rational;
6800 /// use std::cmp::Ordering::*;
6801 ///
6802 /// let y = Float::from(E);
6803 /// let z = Rational::from_signeds(22, 7);
6804 ///
6805 /// let mut x = Float::from(PI);
6806 /// assert_eq!(x.sub_mul_rational_prec_assign_ref_ref(&y, &z, 5), Less);
6807 /// assert_eq!(x.to_string(), "-5.50");
6808 ///
6809 /// let mut x = Float::from(PI);
6810 /// assert_eq!(x.sub_mul_rational_prec_assign_ref_ref(&y, &z, 20), Less);
6811 /// assert_eq!(x.to_string(), "-5.4015808");
6812 /// ```
6813 #[inline]
6814 pub fn sub_mul_rational_prec_assign_ref_ref(
6815 &mut self,
6816 y: &Self,
6817 z: &Rational,
6818 prec: u64,
6819 ) -> Ordering {
6820 self.sub_mul_rational_prec_round_assign_ref_ref(y, z, prec, Nearest)
6821 }
6822
6823 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
6824 /// result with the specified rounding mode. The [`Float`]s and the [`Rational`] are all taken
6825 /// by value. An [`Ordering`] is also returned, indicating whether the rounded diff is less
6826 /// than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
6827 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
6828 ///
6829 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6830 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
6831 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6832 ///
6833 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
6834 /// [`RoundingMode`] for a description of the possible rounding modes.
6835 ///
6836 /// $$
6837 /// f(x,y,z,m) = x-yz+\varepsilon.
6838 /// $$
6839 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6840 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6841 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
6842 /// [`Float`]s.
6843 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6844 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input
6845 /// [`Float`]s.
6846 ///
6847 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
6848 ///
6849 /// Special cases:
6850 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
6851 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
6852 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
6853 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
6854 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
6855 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
6856 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
6857 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
6858 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
6859 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
6860 /// zero [`Rational`] counting as positive.
6861 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
6862 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
6863 ///
6864 /// Overflow and underflow:
6865 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
6866 /// returned instead.
6867 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
6868 /// is returned instead, where `p` is the precision of the output.
6869 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
6870 /// returned instead.
6871 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
6872 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6873 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
6874 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
6875 /// instead.
6876 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
6877 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
6878 /// instead.
6879 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
6880 /// instead.
6881 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
6882 /// instead.
6883 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
6884 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
6885 /// returned instead.
6886 ///
6887 /// If you want to specify an output precision, consider using
6888 /// [`Float::sub_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
6889 /// rounding mode, consider using
6890 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
6891 ///
6892 /// # Worst-case complexity
6893 /// $T(n, m) = O(n \log n \log\log n + m)$
6894 ///
6895 /// $M(n, m) = O(n \log n + m)$
6896 ///
6897 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
6898 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
6899 ///
6900 /// # Panics
6901 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
6902 /// enough to represent the output.
6903 ///
6904 /// # Examples
6905 /// ```
6906 /// use core::f64::consts::{E, PI};
6907 /// use malachite_base::rounding_modes::RoundingMode::*;
6908 /// use malachite_float::Float;
6909 /// use malachite_q::Rational;
6910 /// use std::cmp::Ordering::*;
6911 ///
6912 /// let x = Float::from(PI);
6913 /// let y = Float::from(E);
6914 /// let z = Rational::from_signeds(22, 7);
6915 ///
6916 /// let (diff, o) = x
6917 /// .clone()
6918 /// .sub_mul_rational_round(y.clone(), z.clone(), Floor);
6919 /// assert_eq!(diff.to_string(), "-5.4015788072814921");
6920 /// assert_eq!(o, Less);
6921 ///
6922 /// let (diff, o) = x
6923 /// .clone()
6924 /// .sub_mul_rational_round(y.clone(), z.clone(), Ceiling);
6925 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
6926 /// assert_eq!(o, Greater);
6927 ///
6928 /// let (diff, o) = x
6929 /// .clone()
6930 /// .sub_mul_rational_round(y.clone(), z.clone(), Nearest);
6931 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
6932 /// assert_eq!(o, Greater);
6933 /// ```
6934 #[allow(clippy::needless_pass_by_value)]
6935 #[inline]
6936 pub fn sub_mul_rational_round(
6937 self,
6938 y: Self,
6939 z: Rational,
6940 rm: RoundingMode,
6941 ) -> (Self, Ordering) {
6942 let prec = max(self.significant_bits(), y.significant_bits());
6943 self.sub_mul_rational_prec_round(y, z, prec, rm)
6944 }
6945
6946 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
6947 /// result with the specified rounding mode. The [`Float`]s are taken by value and the
6948 /// [`Rational`] by reference. An [`Ordering`] is also returned, indicating whether the rounded
6949 /// diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
6950 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
6951 ///
6952 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
6953 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
6954 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
6955 ///
6956 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
6957 /// [`RoundingMode`] for a description of the possible rounding modes.
6958 ///
6959 /// $$
6960 /// f(x,y,z,m) = x-yz+\varepsilon.
6961 /// $$
6962 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
6963 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
6964 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
6965 /// [`Float`]s.
6966 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
6967 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input
6968 /// [`Float`]s.
6969 ///
6970 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
6971 ///
6972 /// Special cases:
6973 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
6974 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
6975 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
6976 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
6977 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
6978 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
6979 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
6980 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
6981 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
6982 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
6983 /// zero [`Rational`] counting as positive.
6984 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
6985 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
6986 ///
6987 /// Overflow and underflow:
6988 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
6989 /// returned instead.
6990 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
6991 /// is returned instead, where `p` is the precision of the output.
6992 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
6993 /// returned instead.
6994 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
6995 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
6996 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
6997 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
6998 /// instead.
6999 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
7000 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
7001 /// instead.
7002 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
7003 /// instead.
7004 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
7005 /// instead.
7006 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
7007 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
7008 /// returned instead.
7009 ///
7010 /// If you want to specify an output precision, consider using
7011 /// [`Float::sub_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
7012 /// rounding mode, consider using
7013 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
7014 ///
7015 /// # Worst-case complexity
7016 /// $T(n, m) = O(n \log n \log\log n + m)$
7017 ///
7018 /// $M(n, m) = O(n \log n + m)$
7019 ///
7020 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7021 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
7022 ///
7023 /// # Panics
7024 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
7025 /// enough to represent the output.
7026 ///
7027 /// # Examples
7028 /// ```
7029 /// use core::f64::consts::{E, PI};
7030 /// use malachite_base::rounding_modes::RoundingMode::*;
7031 /// use malachite_float::Float;
7032 /// use malachite_q::Rational;
7033 /// use std::cmp::Ordering::*;
7034 ///
7035 /// let x = Float::from(PI);
7036 /// let y = Float::from(E);
7037 /// let z = Rational::from_signeds(22, 7);
7038 ///
7039 /// let (diff, o) = x
7040 /// .clone()
7041 /// .sub_mul_rational_round_val_val_ref(y.clone(), &z, Floor);
7042 /// assert_eq!(diff.to_string(), "-5.4015788072814921");
7043 /// assert_eq!(o, Less);
7044 ///
7045 /// let (diff, o) = x
7046 /// .clone()
7047 /// .sub_mul_rational_round_val_val_ref(y.clone(), &z, Ceiling);
7048 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
7049 /// assert_eq!(o, Greater);
7050 ///
7051 /// let (diff, o) = x
7052 /// .clone()
7053 /// .sub_mul_rational_round_val_val_ref(y.clone(), &z, Nearest);
7054 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
7055 /// assert_eq!(o, Greater);
7056 /// ```
7057 #[allow(clippy::needless_pass_by_value)]
7058 #[inline]
7059 pub fn sub_mul_rational_round_val_val_ref(
7060 self,
7061 y: Self,
7062 z: &Rational,
7063 rm: RoundingMode,
7064 ) -> (Self, Ordering) {
7065 let prec = max(self.significant_bits(), y.significant_bits());
7066 self.sub_mul_rational_prec_round_val_val_ref(y, z, prec, rm)
7067 }
7068
7069 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
7070 /// result with the specified rounding mode. The first [`Float`] and the [`Rational`] are taken
7071 /// by value and the second [`Float`] by reference. An [`Ordering`] is also returned, indicating
7072 /// whether the rounded diff is less than, equal to, or greater than the exact diff. Although
7073 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
7074 /// returns `Equal`.
7075 ///
7076 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7077 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
7078 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7079 ///
7080 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
7081 /// [`RoundingMode`] for a description of the possible rounding modes.
7082 ///
7083 /// $$
7084 /// f(x,y,z,m) = x-yz+\varepsilon.
7085 /// $$
7086 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7087 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7088 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
7089 /// [`Float`]s.
7090 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7091 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input
7092 /// [`Float`]s.
7093 ///
7094 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
7095 ///
7096 /// Special cases:
7097 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
7098 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
7099 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
7100 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
7101 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
7102 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
7103 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
7104 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
7105 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
7106 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
7107 /// zero [`Rational`] counting as positive.
7108 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
7109 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
7110 ///
7111 /// Overflow and underflow:
7112 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
7113 /// returned instead.
7114 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
7115 /// is returned instead, where `p` is the precision of the output.
7116 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
7117 /// returned instead.
7118 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
7119 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
7120 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
7121 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
7122 /// instead.
7123 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
7124 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
7125 /// instead.
7126 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
7127 /// instead.
7128 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
7129 /// instead.
7130 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
7131 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
7132 /// returned instead.
7133 ///
7134 /// If you want to specify an output precision, consider using
7135 /// [`Float::sub_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
7136 /// rounding mode, consider using
7137 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
7138 ///
7139 /// # Worst-case complexity
7140 /// $T(n, m) = O(n \log n \log\log n + m)$
7141 ///
7142 /// $M(n, m) = O(n \log n + m)$
7143 ///
7144 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7145 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
7146 ///
7147 /// # Panics
7148 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
7149 /// enough to represent the output.
7150 ///
7151 /// # Examples
7152 /// ```
7153 /// use core::f64::consts::{E, PI};
7154 /// use malachite_base::rounding_modes::RoundingMode::*;
7155 /// use malachite_float::Float;
7156 /// use malachite_q::Rational;
7157 /// use std::cmp::Ordering::*;
7158 ///
7159 /// let x = Float::from(PI);
7160 /// let y = Float::from(E);
7161 /// let z = Rational::from_signeds(22, 7);
7162 ///
7163 /// let (diff, o) = x
7164 /// .clone()
7165 /// .sub_mul_rational_round_val_ref_val(&y, z.clone(), Floor);
7166 /// assert_eq!(diff.to_string(), "-5.4015788072814921");
7167 /// assert_eq!(o, Less);
7168 ///
7169 /// let (diff, o) = x
7170 /// .clone()
7171 /// .sub_mul_rational_round_val_ref_val(&y, z.clone(), Ceiling);
7172 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
7173 /// assert_eq!(o, Greater);
7174 ///
7175 /// let (diff, o) = x
7176 /// .clone()
7177 /// .sub_mul_rational_round_val_ref_val(&y, z.clone(), Nearest);
7178 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
7179 /// assert_eq!(o, Greater);
7180 /// ```
7181 #[allow(clippy::needless_pass_by_value)]
7182 #[inline]
7183 pub fn sub_mul_rational_round_val_ref_val(
7184 self,
7185 y: &Self,
7186 z: Rational,
7187 rm: RoundingMode,
7188 ) -> (Self, Ordering) {
7189 let prec = max(self.significant_bits(), y.significant_bits());
7190 self.sub_mul_rational_prec_round_val_ref_val(y, z, prec, rm)
7191 }
7192
7193 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
7194 /// result with the specified rounding mode. The first [`Float`] is taken by value and the
7195 /// second [`Float`] and the [`Rational`] by reference. An [`Ordering`] is also returned,
7196 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
7197 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
7198 /// it also returns `Equal`.
7199 ///
7200 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7201 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
7202 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7203 ///
7204 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
7205 /// [`RoundingMode`] for a description of the possible rounding modes.
7206 ///
7207 /// $$
7208 /// f(x,y,z,m) = x-yz+\varepsilon.
7209 /// $$
7210 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7211 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7212 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
7213 /// [`Float`]s.
7214 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7215 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input
7216 /// [`Float`]s.
7217 ///
7218 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
7219 ///
7220 /// Special cases:
7221 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
7222 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
7223 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
7224 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
7225 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
7226 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
7227 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
7228 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
7229 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
7230 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
7231 /// zero [`Rational`] counting as positive.
7232 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
7233 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
7234 ///
7235 /// Overflow and underflow:
7236 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
7237 /// returned instead.
7238 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
7239 /// is returned instead, where `p` is the precision of the output.
7240 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
7241 /// returned instead.
7242 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
7243 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
7244 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
7245 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
7246 /// instead.
7247 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
7248 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
7249 /// instead.
7250 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
7251 /// instead.
7252 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
7253 /// instead.
7254 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
7255 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
7256 /// returned instead.
7257 ///
7258 /// If you want to specify an output precision, consider using
7259 /// [`Float::sub_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
7260 /// rounding mode, consider using
7261 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
7262 ///
7263 /// # Worst-case complexity
7264 /// $T(n, m) = O(n \log n \log\log n + m)$
7265 ///
7266 /// $M(n, m) = O(n \log n + m)$
7267 ///
7268 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7269 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
7270 ///
7271 /// # Panics
7272 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
7273 /// enough to represent the output.
7274 ///
7275 /// # Examples
7276 /// ```
7277 /// use core::f64::consts::{E, PI};
7278 /// use malachite_base::rounding_modes::RoundingMode::*;
7279 /// use malachite_float::Float;
7280 /// use malachite_q::Rational;
7281 /// use std::cmp::Ordering::*;
7282 ///
7283 /// let x = Float::from(PI);
7284 /// let y = Float::from(E);
7285 /// let z = Rational::from_signeds(22, 7);
7286 ///
7287 /// let (diff, o) = x.clone().sub_mul_rational_round_val_ref_ref(&y, &z, Floor);
7288 /// assert_eq!(diff.to_string(), "-5.4015788072814921");
7289 /// assert_eq!(o, Less);
7290 ///
7291 /// let (diff, o) = x
7292 /// .clone()
7293 /// .sub_mul_rational_round_val_ref_ref(&y, &z, Ceiling);
7294 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
7295 /// assert_eq!(o, Greater);
7296 ///
7297 /// let (diff, o) = x
7298 /// .clone()
7299 /// .sub_mul_rational_round_val_ref_ref(&y, &z, Nearest);
7300 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
7301 /// assert_eq!(o, Greater);
7302 /// ```
7303 #[allow(clippy::needless_pass_by_value)]
7304 #[inline]
7305 pub fn sub_mul_rational_round_val_ref_ref(
7306 self,
7307 y: &Self,
7308 z: &Rational,
7309 rm: RoundingMode,
7310 ) -> (Self, Ordering) {
7311 let prec = max(self.significant_bits(), y.significant_bits());
7312 self.sub_mul_rational_prec_round_val_ref_ref(y, z, prec, rm)
7313 }
7314
7315 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
7316 /// result with the specified rounding mode. The first [`Float`] is taken by reference and the
7317 /// second [`Float`] and the [`Rational`] by value. An [`Ordering`] is also returned, indicating
7318 /// whether the rounded diff is less than, equal to, or greater than the exact diff. Although
7319 /// `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN` it also
7320 /// returns `Equal`.
7321 ///
7322 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7323 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
7324 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7325 ///
7326 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
7327 /// [`RoundingMode`] for a description of the possible rounding modes.
7328 ///
7329 /// $$
7330 /// f(x,y,z,m) = x-yz+\varepsilon.
7331 /// $$
7332 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7333 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7334 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
7335 /// [`Float`]s.
7336 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7337 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input
7338 /// [`Float`]s.
7339 ///
7340 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
7341 ///
7342 /// Special cases:
7343 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
7344 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
7345 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
7346 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
7347 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
7348 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
7349 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
7350 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
7351 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
7352 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
7353 /// zero [`Rational`] counting as positive.
7354 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
7355 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
7356 ///
7357 /// Overflow and underflow:
7358 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
7359 /// returned instead.
7360 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
7361 /// is returned instead, where `p` is the precision of the output.
7362 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
7363 /// returned instead.
7364 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
7365 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
7366 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
7367 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
7368 /// instead.
7369 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
7370 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
7371 /// instead.
7372 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
7373 /// instead.
7374 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
7375 /// instead.
7376 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
7377 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
7378 /// returned instead.
7379 ///
7380 /// If you want to specify an output precision, consider using
7381 /// [`Float::sub_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
7382 /// rounding mode, consider using
7383 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
7384 ///
7385 /// # Worst-case complexity
7386 /// $T(n, m) = O(n \log n \log\log n + m)$
7387 ///
7388 /// $M(n, m) = O(n \log n + m)$
7389 ///
7390 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7391 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
7392 ///
7393 /// # Panics
7394 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
7395 /// enough to represent the output.
7396 ///
7397 /// # Examples
7398 /// ```
7399 /// use core::f64::consts::{E, PI};
7400 /// use malachite_base::rounding_modes::RoundingMode::*;
7401 /// use malachite_float::Float;
7402 /// use malachite_q::Rational;
7403 /// use std::cmp::Ordering::*;
7404 ///
7405 /// let x = Float::from(PI);
7406 /// let y = Float::from(E);
7407 /// let z = Rational::from_signeds(22, 7);
7408 ///
7409 /// let (diff, o) = x.sub_mul_rational_round_ref_val_val(y.clone(), z.clone(), Floor);
7410 /// assert_eq!(diff.to_string(), "-5.4015788072814921");
7411 /// assert_eq!(o, Less);
7412 ///
7413 /// let (diff, o) = x.sub_mul_rational_round_ref_val_val(y.clone(), z.clone(), Ceiling);
7414 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
7415 /// assert_eq!(o, Greater);
7416 ///
7417 /// let (diff, o) = x.sub_mul_rational_round_ref_val_val(y.clone(), z.clone(), Nearest);
7418 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
7419 /// assert_eq!(o, Greater);
7420 /// ```
7421 #[allow(clippy::needless_pass_by_value)]
7422 #[inline]
7423 pub fn sub_mul_rational_round_ref_val_val(
7424 &self,
7425 y: Self,
7426 z: Rational,
7427 rm: RoundingMode,
7428 ) -> (Self, Ordering) {
7429 let prec = max(self.significant_bits(), y.significant_bits());
7430 self.sub_mul_rational_prec_round_ref_val_val(y, z, prec, rm)
7431 }
7432
7433 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
7434 /// result with the specified rounding mode. The second [`Float`] is taken by value and the
7435 /// first [`Float`] and the [`Rational`] by reference. An [`Ordering`] is also returned,
7436 /// indicating whether the rounded diff is less than, equal to, or greater than the exact diff.
7437 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
7438 /// it also returns `Equal`.
7439 ///
7440 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7441 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
7442 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7443 ///
7444 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
7445 /// [`RoundingMode`] for a description of the possible rounding modes.
7446 ///
7447 /// $$
7448 /// f(x,y,z,m) = x-yz+\varepsilon.
7449 /// $$
7450 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7451 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7452 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
7453 /// [`Float`]s.
7454 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7455 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input
7456 /// [`Float`]s.
7457 ///
7458 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
7459 ///
7460 /// Special cases:
7461 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
7462 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
7463 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
7464 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
7465 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
7466 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
7467 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
7468 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
7469 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
7470 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
7471 /// zero [`Rational`] counting as positive.
7472 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
7473 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
7474 ///
7475 /// Overflow and underflow:
7476 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
7477 /// returned instead.
7478 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
7479 /// is returned instead, where `p` is the precision of the output.
7480 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
7481 /// returned instead.
7482 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
7483 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
7484 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
7485 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
7486 /// instead.
7487 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
7488 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
7489 /// instead.
7490 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
7491 /// instead.
7492 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
7493 /// instead.
7494 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
7495 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
7496 /// returned instead.
7497 ///
7498 /// If you want to specify an output precision, consider using
7499 /// [`Float::sub_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
7500 /// rounding mode, consider using
7501 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
7502 ///
7503 /// # Worst-case complexity
7504 /// $T(n, m) = O(n \log n \log\log n + m)$
7505 ///
7506 /// $M(n, m) = O(n \log n + m)$
7507 ///
7508 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7509 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
7510 ///
7511 /// # Panics
7512 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
7513 /// enough to represent the output.
7514 ///
7515 /// # Examples
7516 /// ```
7517 /// use core::f64::consts::{E, PI};
7518 /// use malachite_base::rounding_modes::RoundingMode::*;
7519 /// use malachite_float::Float;
7520 /// use malachite_q::Rational;
7521 /// use std::cmp::Ordering::*;
7522 ///
7523 /// let x = Float::from(PI);
7524 /// let y = Float::from(E);
7525 /// let z = Rational::from_signeds(22, 7);
7526 ///
7527 /// let (diff, o) = x.sub_mul_rational_round_ref_val_ref(y.clone(), &z, Floor);
7528 /// assert_eq!(diff.to_string(), "-5.4015788072814921");
7529 /// assert_eq!(o, Less);
7530 ///
7531 /// let (diff, o) = x.sub_mul_rational_round_ref_val_ref(y.clone(), &z, Ceiling);
7532 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
7533 /// assert_eq!(o, Greater);
7534 ///
7535 /// let (diff, o) = x.sub_mul_rational_round_ref_val_ref(y.clone(), &z, Nearest);
7536 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
7537 /// assert_eq!(o, Greater);
7538 /// ```
7539 #[allow(clippy::needless_pass_by_value)]
7540 #[inline]
7541 pub fn sub_mul_rational_round_ref_val_ref(
7542 &self,
7543 y: Self,
7544 z: &Rational,
7545 rm: RoundingMode,
7546 ) -> (Self, Ordering) {
7547 let prec = max(self.significant_bits(), y.significant_bits());
7548 self.sub_mul_rational_prec_round_ref_val_ref(y, z, prec, rm)
7549 }
7550
7551 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
7552 /// result with the specified rounding mode. The [`Float`]s are taken by reference and the
7553 /// [`Rational`] by value. An [`Ordering`] is also returned, indicating whether the rounded diff
7554 /// is less than, equal to, or greater than the exact diff. Although `NaN`s are not comparable
7555 /// to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
7556 ///
7557 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7558 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
7559 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7560 ///
7561 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
7562 /// [`RoundingMode`] for a description of the possible rounding modes.
7563 ///
7564 /// $$
7565 /// f(x,y,z,m) = x-yz+\varepsilon.
7566 /// $$
7567 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7568 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7569 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
7570 /// [`Float`]s.
7571 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7572 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input
7573 /// [`Float`]s.
7574 ///
7575 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
7576 ///
7577 /// Special cases:
7578 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
7579 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
7580 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
7581 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
7582 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
7583 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
7584 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
7585 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
7586 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
7587 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
7588 /// zero [`Rational`] counting as positive.
7589 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
7590 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
7591 ///
7592 /// Overflow and underflow:
7593 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
7594 /// returned instead.
7595 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
7596 /// is returned instead, where `p` is the precision of the output.
7597 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
7598 /// returned instead.
7599 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
7600 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
7601 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
7602 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
7603 /// instead.
7604 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
7605 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
7606 /// instead.
7607 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
7608 /// instead.
7609 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
7610 /// instead.
7611 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
7612 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
7613 /// returned instead.
7614 ///
7615 /// If you want to specify an output precision, consider using
7616 /// [`Float::sub_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
7617 /// rounding mode, consider using
7618 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
7619 ///
7620 /// # Worst-case complexity
7621 /// $T(n, m) = O(n \log n \log\log n + m)$
7622 ///
7623 /// $M(n, m) = O(n \log n + m)$
7624 ///
7625 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7626 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
7627 ///
7628 /// # Panics
7629 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
7630 /// enough to represent the output.
7631 ///
7632 /// # Examples
7633 /// ```
7634 /// use core::f64::consts::{E, PI};
7635 /// use malachite_base::rounding_modes::RoundingMode::*;
7636 /// use malachite_float::Float;
7637 /// use malachite_q::Rational;
7638 /// use std::cmp::Ordering::*;
7639 ///
7640 /// let x = Float::from(PI);
7641 /// let y = Float::from(E);
7642 /// let z = Rational::from_signeds(22, 7);
7643 ///
7644 /// let (diff, o) = x.sub_mul_rational_round_ref_ref_val(&y, z.clone(), Floor);
7645 /// assert_eq!(diff.to_string(), "-5.4015788072814921");
7646 /// assert_eq!(o, Less);
7647 ///
7648 /// let (diff, o) = x.sub_mul_rational_round_ref_ref_val(&y, z.clone(), Ceiling);
7649 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
7650 /// assert_eq!(o, Greater);
7651 ///
7652 /// let (diff, o) = x.sub_mul_rational_round_ref_ref_val(&y, z.clone(), Nearest);
7653 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
7654 /// assert_eq!(o, Greater);
7655 /// ```
7656 #[allow(clippy::needless_pass_by_value)]
7657 #[inline]
7658 pub fn sub_mul_rational_round_ref_ref_val(
7659 &self,
7660 y: &Self,
7661 z: Rational,
7662 rm: RoundingMode,
7663 ) -> (Self, Ordering) {
7664 let prec = max(self.significant_bits(), y.significant_bits());
7665 self.sub_mul_rational_prec_round_ref_ref_val(y, z, prec, rm)
7666 }
7667
7668 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], rounding the
7669 /// result with the specified rounding mode. The [`Float`]s and the [`Rational`] are all taken
7670 /// by reference. An [`Ordering`] is also returned, indicating whether the rounded diff is less
7671 /// than, equal to, or greater than the exact diff. Although `NaN`s are not comparable to any
7672 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
7673 ///
7674 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7675 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
7676 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7677 ///
7678 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
7679 /// [`RoundingMode`] for a description of the possible rounding modes.
7680 ///
7681 /// $$
7682 /// f(x,y,z,m) = x-yz+\varepsilon.
7683 /// $$
7684 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7685 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7686 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
7687 /// [`Float`]s.
7688 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7689 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input
7690 /// [`Float`]s.
7691 ///
7692 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
7693 ///
7694 /// Special cases:
7695 /// - $f(\text{NaN},y,z,m)=f(x,\text{NaN},z,m)=\text{NaN}$
7696 /// - $f(x,\pm\infty,0,m)=\text{NaN}$
7697 /// - $f(\infty,y,z,m)=\text{NaN}$ if $yz=\infty$
7698 /// - $f(-\infty,y,z,m)=\text{NaN}$ if $yz=-\infty$
7699 /// - $f(\infty,y,z,m)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
7700 /// - $f(-\infty,y,z,m)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
7701 /// - $f(x,y,z,m)=-\infty$ if $x$ is finite and $yz=\infty$
7702 /// - $f(x,y,z,m)=\infty$ if $x$ is finite and $yz=-\infty$
7703 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
7704 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
7705 /// zero [`Rational`] counting as positive.
7706 /// - $f(x,y,z,m)=0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is not `Floor`
7707 /// - $f(x,y,z,m)=-0.0$ if $x=yz$, $x$ is finite and nonzero, and $m$ is `Floor`
7708 ///
7709 /// Overflow and underflow:
7710 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Ceiling`, `Up`, or `Nearest`, $\infty$ is
7711 /// returned instead.
7712 /// - If $f(x,y,z,m)\geq 2^{2^{30}-1}$ and $m$ is `Floor` or `Down`, $(1-(1/2)^p)2^{2^{30}-1}$
7713 /// is returned instead, where `p` is the precision of the output.
7714 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Floor`, `Up`, or `Nearest`, $-\infty$ is
7715 /// returned instead.
7716 /// - If $f(x,y,z,m)\leq -2^{2^{30}-1}$ and $m$ is `Ceiling` or `Down`,
7717 /// $-(1-(1/2)^p)2^{2^{30}-1}$ is returned instead, where `p` is the precision of the output.
7718 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Floor` or `Down`, $0.0$ is returned instead.
7719 /// - If $0<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Ceiling` or `Up`, $2^{-2^{30}}$ is returned
7720 /// instead.
7721 /// - If $0<f(x,y,z,m)\leq2^{-2^{30}-1}$, and $m$ is `Nearest`, $0.0$ is returned instead.
7722 /// - If $2^{-2^{30}-1}<f(x,y,z,m)<2^{-2^{30}}$, and $m$ is `Nearest`, $2^{-2^{30}}$ is returned
7723 /// instead.
7724 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Ceiling` or `Down`, $-0.0$ is returned
7725 /// instead.
7726 /// - If $-2^{-2^{30}}<f(x,y,z,m)<0$, and $m$ is `Floor` or `Up`, $-2^{-2^{30}}$ is returned
7727 /// instead.
7728 /// - If $-2^{-2^{30}-1}\leq f(x,y,z,m)<0$, and $m$ is `Nearest`, $-0.0$ is returned instead.
7729 /// - If $-2^{-2^{30}}<f(x,y,z,m)<-2^{-2^{30}-1}$, and $m$ is `Nearest`, $-2^{-2^{30}}$ is
7730 /// returned instead.
7731 ///
7732 /// If you want to specify an output precision, consider using
7733 /// [`Float::sub_mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
7734 /// rounding mode, consider using
7735 /// [`sub_mul`](malachite_base::num::arithmetic::traits::SubMul::sub_mul) instead.
7736 ///
7737 /// # Worst-case complexity
7738 /// $T(n, m) = O(n \log n \log\log n + m)$
7739 ///
7740 /// $M(n, m) = O(n \log n + m)$
7741 ///
7742 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7743 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
7744 ///
7745 /// # Panics
7746 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
7747 /// enough to represent the output.
7748 ///
7749 /// # Examples
7750 /// ```
7751 /// use core::f64::consts::{E, PI};
7752 /// use malachite_base::rounding_modes::RoundingMode::*;
7753 /// use malachite_float::Float;
7754 /// use malachite_q::Rational;
7755 /// use std::cmp::Ordering::*;
7756 ///
7757 /// let x = Float::from(PI);
7758 /// let y = Float::from(E);
7759 /// let z = Rational::from_signeds(22, 7);
7760 ///
7761 /// let (diff, o) = x.sub_mul_rational_round_ref_ref_ref(&y, &z, Floor);
7762 /// assert_eq!(diff.to_string(), "-5.4015788072814921");
7763 /// assert_eq!(o, Less);
7764 ///
7765 /// let (diff, o) = x.sub_mul_rational_round_ref_ref_ref(&y, &z, Ceiling);
7766 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
7767 /// assert_eq!(o, Greater);
7768 ///
7769 /// let (diff, o) = x.sub_mul_rational_round_ref_ref_ref(&y, &z, Nearest);
7770 /// assert_eq!(diff.to_string(), "-5.4015788072814912");
7771 /// assert_eq!(o, Greater);
7772 /// ```
7773 #[inline]
7774 pub fn sub_mul_rational_round_ref_ref_ref(
7775 &self,
7776 y: &Self,
7777 z: &Rational,
7778 rm: RoundingMode,
7779 ) -> (Self, Ordering) {
7780 let prec = max(self.significant_bits(), y.significant_bits());
7781 self.sub_mul_rational_prec_round_ref_ref_ref(y, z, prec, rm)
7782 }
7783
7784 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place, rounding
7785 /// the result with the specified rounding mode. The [`Float`] and the [`Rational`] on the
7786 /// right-hand side are both taken by value. An [`Ordering`] is returned, indicating whether the
7787 /// rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are not
7788 /// comparable to any [`Float`], whenever this function assigns a `NaN` it also returns `Equal`.
7789 ///
7790 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7791 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
7792 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7793 ///
7794 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
7795 /// [`RoundingMode`] for a description of the possible rounding modes.
7796 ///
7797 /// $$
7798 /// x \gets x-yz+\varepsilon.
7799 /// $$
7800 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7801 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7802 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
7803 /// [`Float`]s.
7804 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7805 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input
7806 /// [`Float`]s.
7807 ///
7808 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
7809 /// cases, overflow, and underflow.
7810 ///
7811 /// If you want to specify an output precision, consider using
7812 /// [`Float::sub_mul_rational_prec_round_assign`] instead. If you know you'll be using the
7813 /// `Nearest` rounding mode, consider using
7814 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
7815 /// instead.
7816 ///
7817 /// # Worst-case complexity
7818 /// $T(n, m) = O(n \log n \log\log n + m)$
7819 ///
7820 /// $M(n, m) = O(n \log n + m)$
7821 ///
7822 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7823 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
7824 ///
7825 /// # Panics
7826 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
7827 /// enough to represent the output.
7828 ///
7829 /// # Examples
7830 /// ```
7831 /// use core::f64::consts::{E, PI};
7832 /// use malachite_base::rounding_modes::RoundingMode::*;
7833 /// use malachite_float::Float;
7834 /// use malachite_q::Rational;
7835 /// use std::cmp::Ordering::*;
7836 ///
7837 /// let y = Float::from(E);
7838 /// let z = Rational::from_signeds(22, 7);
7839 ///
7840 /// let mut x = Float::from(PI);
7841 /// assert_eq!(
7842 /// x.sub_mul_rational_round_assign(y.clone(), z.clone(), Floor),
7843 /// Less
7844 /// );
7845 /// assert_eq!(x.to_string(), "-5.4015788072814921");
7846 ///
7847 /// let mut x = Float::from(PI);
7848 /// assert_eq!(
7849 /// x.sub_mul_rational_round_assign(y.clone(), z.clone(), Ceiling),
7850 /// Greater
7851 /// );
7852 /// assert_eq!(x.to_string(), "-5.4015788072814912");
7853 ///
7854 /// let mut x = Float::from(PI);
7855 /// assert_eq!(
7856 /// x.sub_mul_rational_round_assign(y.clone(), z.clone(), Nearest),
7857 /// Greater
7858 /// );
7859 /// assert_eq!(x.to_string(), "-5.4015788072814912");
7860 /// ```
7861 #[allow(clippy::needless_pass_by_value)]
7862 #[inline]
7863 pub fn sub_mul_rational_round_assign(
7864 &mut self,
7865 y: Self,
7866 z: Rational,
7867 rm: RoundingMode,
7868 ) -> Ordering {
7869 let prec = max(self.significant_bits(), y.significant_bits());
7870 self.sub_mul_rational_prec_round_assign(y, z, prec, rm)
7871 }
7872
7873 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place, rounding
7874 /// the result with the specified rounding mode. The [`Float`] on the right-hand side is taken
7875 /// by value and the [`Rational`] by reference. An [`Ordering`] is returned, indicating whether
7876 /// the rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are
7877 /// not comparable to any [`Float`], whenever this function assigns a `NaN` it also returns
7878 /// `Equal`.
7879 ///
7880 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7881 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
7882 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7883 ///
7884 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
7885 /// [`RoundingMode`] for a description of the possible rounding modes.
7886 ///
7887 /// $$
7888 /// x \gets x-yz+\varepsilon.
7889 /// $$
7890 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7891 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7892 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
7893 /// [`Float`]s.
7894 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7895 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input
7896 /// [`Float`]s.
7897 ///
7898 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
7899 /// cases, overflow, and underflow.
7900 ///
7901 /// If you want to specify an output precision, consider using
7902 /// [`Float::sub_mul_rational_prec_round_assign`] instead. If you know you'll be using the
7903 /// `Nearest` rounding mode, consider using
7904 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
7905 /// instead.
7906 ///
7907 /// # Worst-case complexity
7908 /// $T(n, m) = O(n \log n \log\log n + m)$
7909 ///
7910 /// $M(n, m) = O(n \log n + m)$
7911 ///
7912 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
7913 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
7914 ///
7915 /// # Panics
7916 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
7917 /// enough to represent the output.
7918 ///
7919 /// # Examples
7920 /// ```
7921 /// use core::f64::consts::{E, PI};
7922 /// use malachite_base::rounding_modes::RoundingMode::*;
7923 /// use malachite_float::Float;
7924 /// use malachite_q::Rational;
7925 /// use std::cmp::Ordering::*;
7926 ///
7927 /// let y = Float::from(E);
7928 /// let z = Rational::from_signeds(22, 7);
7929 ///
7930 /// let mut x = Float::from(PI);
7931 /// assert_eq!(
7932 /// x.sub_mul_rational_round_assign_val_ref(y.clone(), &z, Floor),
7933 /// Less
7934 /// );
7935 /// assert_eq!(x.to_string(), "-5.4015788072814921");
7936 ///
7937 /// let mut x = Float::from(PI);
7938 /// assert_eq!(
7939 /// x.sub_mul_rational_round_assign_val_ref(y.clone(), &z, Ceiling),
7940 /// Greater
7941 /// );
7942 /// assert_eq!(x.to_string(), "-5.4015788072814912");
7943 ///
7944 /// let mut x = Float::from(PI);
7945 /// assert_eq!(
7946 /// x.sub_mul_rational_round_assign_val_ref(y.clone(), &z, Nearest),
7947 /// Greater
7948 /// );
7949 /// assert_eq!(x.to_string(), "-5.4015788072814912");
7950 /// ```
7951 #[allow(clippy::needless_pass_by_value)]
7952 #[inline]
7953 pub fn sub_mul_rational_round_assign_val_ref(
7954 &mut self,
7955 y: Self,
7956 z: &Rational,
7957 rm: RoundingMode,
7958 ) -> Ordering {
7959 let prec = max(self.significant_bits(), y.significant_bits());
7960 self.sub_mul_rational_prec_round_assign_val_ref(y, z, prec, rm)
7961 }
7962
7963 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place, rounding
7964 /// the result with the specified rounding mode. The [`Float`] on the right-hand side is taken
7965 /// by reference and the [`Rational`] by value. An [`Ordering`] is returned, indicating whether
7966 /// the rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are
7967 /// not comparable to any [`Float`], whenever this function assigns a `NaN` it also returns
7968 /// `Equal`.
7969 ///
7970 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
7971 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
7972 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
7973 ///
7974 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
7975 /// [`RoundingMode`] for a description of the possible rounding modes.
7976 ///
7977 /// $$
7978 /// x \gets x-yz+\varepsilon.
7979 /// $$
7980 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
7981 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
7982 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
7983 /// [`Float`]s.
7984 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
7985 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input
7986 /// [`Float`]s.
7987 ///
7988 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
7989 /// cases, overflow, and underflow.
7990 ///
7991 /// If you want to specify an output precision, consider using
7992 /// [`Float::sub_mul_rational_prec_round_assign`] instead. If you know you'll be using the
7993 /// `Nearest` rounding mode, consider using
7994 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
7995 /// instead.
7996 ///
7997 /// # Worst-case complexity
7998 /// $T(n, m) = O(n \log n \log\log n + m)$
7999 ///
8000 /// $M(n, m) = O(n \log n + m)$
8001 ///
8002 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8003 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8004 ///
8005 /// # Panics
8006 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
8007 /// enough to represent the output.
8008 ///
8009 /// # Examples
8010 /// ```
8011 /// use core::f64::consts::{E, PI};
8012 /// use malachite_base::rounding_modes::RoundingMode::*;
8013 /// use malachite_float::Float;
8014 /// use malachite_q::Rational;
8015 /// use std::cmp::Ordering::*;
8016 ///
8017 /// let y = Float::from(E);
8018 /// let z = Rational::from_signeds(22, 7);
8019 ///
8020 /// let mut x = Float::from(PI);
8021 /// assert_eq!(
8022 /// x.sub_mul_rational_round_assign_ref_val(&y, z.clone(), Floor),
8023 /// Less
8024 /// );
8025 /// assert_eq!(x.to_string(), "-5.4015788072814921");
8026 ///
8027 /// let mut x = Float::from(PI);
8028 /// assert_eq!(
8029 /// x.sub_mul_rational_round_assign_ref_val(&y, z.clone(), Ceiling),
8030 /// Greater
8031 /// );
8032 /// assert_eq!(x.to_string(), "-5.4015788072814912");
8033 ///
8034 /// let mut x = Float::from(PI);
8035 /// assert_eq!(
8036 /// x.sub_mul_rational_round_assign_ref_val(&y, z.clone(), Nearest),
8037 /// Greater
8038 /// );
8039 /// assert_eq!(x.to_string(), "-5.4015788072814912");
8040 /// ```
8041 #[allow(clippy::needless_pass_by_value)]
8042 #[inline]
8043 pub fn sub_mul_rational_round_assign_ref_val(
8044 &mut self,
8045 y: &Self,
8046 z: Rational,
8047 rm: RoundingMode,
8048 ) -> Ordering {
8049 let prec = max(self.significant_bits(), y.significant_bits());
8050 self.sub_mul_rational_prec_round_assign_ref_val(y, z, prec, rm)
8051 }
8052
8053 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place, rounding
8054 /// the result with the specified rounding mode. The [`Float`] and the [`Rational`] on the
8055 /// right-hand side are both taken by reference. An [`Ordering`] is returned, indicating whether
8056 /// the rounded diff is less than, equal to, or greater than the exact diff. Although `NaN`s are
8057 /// not comparable to any [`Float`], whenever this function assigns a `NaN` it also returns
8058 /// `Equal`.
8059 ///
8060 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8061 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
8062 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8063 ///
8064 /// The precision of the output is the maximum of the precisions of the input [`Float`]s. See
8065 /// [`RoundingMode`] for a description of the possible rounding modes.
8066 ///
8067 /// $$
8068 /// x \gets x-yz+\varepsilon.
8069 /// $$
8070 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8071 /// - If $x-yz$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
8072 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p+1}$, where $p$ is the maximum precision of the input
8073 /// [`Float`]s.
8074 /// - If $x-yz$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| \leq
8075 /// 2^{\lfloor\log_2 |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input
8076 /// [`Float`]s.
8077 ///
8078 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
8079 /// cases, overflow, and underflow.
8080 ///
8081 /// If you want to specify an output precision, consider using
8082 /// [`Float::sub_mul_rational_prec_round_assign`] instead. If you know you'll be using the
8083 /// `Nearest` rounding mode, consider using
8084 /// [`sub_mul_assign`](malachite_base::num::arithmetic::traits::SubMulAssign::sub_mul_assign)
8085 /// instead.
8086 ///
8087 /// # Worst-case complexity
8088 /// $T(n, m) = O(n \log n \log\log n + m)$
8089 ///
8090 /// $M(n, m) = O(n \log n + m)$
8091 ///
8092 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8093 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8094 ///
8095 /// # Panics
8096 /// Panics if `rm` is `Exact` but the maximum precision of the input [`Float`]s is not high
8097 /// enough to represent the output.
8098 ///
8099 /// # Examples
8100 /// ```
8101 /// use core::f64::consts::{E, PI};
8102 /// use malachite_base::rounding_modes::RoundingMode::*;
8103 /// use malachite_float::Float;
8104 /// use malachite_q::Rational;
8105 /// use std::cmp::Ordering::*;
8106 ///
8107 /// let y = Float::from(E);
8108 /// let z = Rational::from_signeds(22, 7);
8109 ///
8110 /// let mut x = Float::from(PI);
8111 /// assert_eq!(x.sub_mul_rational_round_assign_ref_ref(&y, &z, Floor), Less);
8112 /// assert_eq!(x.to_string(), "-5.4015788072814921");
8113 ///
8114 /// let mut x = Float::from(PI);
8115 /// assert_eq!(
8116 /// x.sub_mul_rational_round_assign_ref_ref(&y, &z, Ceiling),
8117 /// Greater
8118 /// );
8119 /// assert_eq!(x.to_string(), "-5.4015788072814912");
8120 ///
8121 /// let mut x = Float::from(PI);
8122 /// assert_eq!(
8123 /// x.sub_mul_rational_round_assign_ref_ref(&y, &z, Nearest),
8124 /// Greater
8125 /// );
8126 /// assert_eq!(x.to_string(), "-5.4015788072814912");
8127 /// ```
8128 #[inline]
8129 pub fn sub_mul_rational_round_assign_ref_ref(
8130 &mut self,
8131 y: &Self,
8132 z: &Rational,
8133 rm: RoundingMode,
8134 ) -> Ordering {
8135 let prec = max(self.significant_bits(), y.significant_bits());
8136 self.sub_mul_rational_prec_round_assign_ref_ref(y, z, prec, rm)
8137 }
8138}
8139
8140impl SubMul<Self, Rational> for Float {
8141 type Output = Self;
8142 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], taking all
8143 /// three by value.
8144 ///
8145 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8146 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
8147 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8148 ///
8149 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8150 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8151 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8152 /// the `Nearest` rounding mode.
8153 ///
8154 /// $$
8155 /// f(x,y,z) = x-yz+\varepsilon.
8156 /// $$
8157 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8158 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8159 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8160 ///
8161 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8162 ///
8163 /// Special cases:
8164 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
8165 /// - $f(x,\pm\infty,0)=\text{NaN}$
8166 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
8167 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
8168 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
8169 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
8170 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
8171 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
8172 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
8173 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
8174 /// zero [`Rational`] counting as positive.
8175 /// - $f(x,y,z)=0.0$ if $x=yz$ and $x$ is finite and nonzero
8176 ///
8177 /// Overflow and underflow:
8178 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8179 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8180 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8181 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8182 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
8183 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8184 ///
8185 /// If you want to use a rounding mode other than `Nearest`, consider using
8186 /// [`Float::sub_mul_rational_round`]. If you want to specify the output precision, consider
8187 /// using [`Float::sub_mul_rational_prec`]. If you want both of these things, consider using
8188 /// [`Float::sub_mul_rational_prec_round`].
8189 ///
8190 /// # Worst-case complexity
8191 /// $T(n, m) = O(n \log n \log\log n + m)$
8192 ///
8193 /// $M(n, m) = O(n \log n + m)$
8194 ///
8195 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8196 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8197 ///
8198 /// # Examples
8199 /// ```
8200 /// use core::f64::consts::{E, PI};
8201 /// use malachite_base::num::arithmetic::traits::SubMul;
8202 /// use malachite_float::Float;
8203 /// use malachite_q::Rational;
8204 ///
8205 /// let x = Float::from(PI);
8206 /// let y = Float::from(E);
8207 /// let z = Rational::from_signeds(22, 7);
8208 /// assert_eq!(x.sub_mul(y, z).to_string(), "-5.4015788072814912");
8209 /// ```
8210 #[inline]
8211 fn sub_mul(self, y: Self, z: Rational) -> Self {
8212 let prec = max(self.significant_bits(), y.significant_bits());
8213 self.sub_mul_rational_prec(y, z, prec).0
8214 }
8215}
8216
8217impl SubMul<Self, &Rational> for Float {
8218 type Output = Self;
8219 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], taking the
8220 /// [`Float`]s by value and the [`Rational`] by reference.
8221 ///
8222 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8223 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
8224 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8225 ///
8226 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8227 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8228 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8229 /// the `Nearest` rounding mode.
8230 ///
8231 /// $$
8232 /// f(x,y,z) = x-yz+\varepsilon.
8233 /// $$
8234 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8235 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8236 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8237 ///
8238 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8239 ///
8240 /// Special cases:
8241 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
8242 /// - $f(x,\pm\infty,0)=\text{NaN}$
8243 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
8244 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
8245 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
8246 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
8247 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
8248 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
8249 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
8250 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
8251 /// zero [`Rational`] counting as positive.
8252 /// - $f(x,y,z)=0.0$ if $x=yz$ and $x$ is finite and nonzero
8253 ///
8254 /// Overflow and underflow:
8255 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8256 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8257 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8258 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8259 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
8260 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8261 ///
8262 /// If you want to use a rounding mode other than `Nearest`, consider using
8263 /// [`Float::sub_mul_rational_round`]. If you want to specify the output precision, consider
8264 /// using [`Float::sub_mul_rational_prec`]. If you want both of these things, consider using
8265 /// [`Float::sub_mul_rational_prec_round`].
8266 ///
8267 /// # Worst-case complexity
8268 /// $T(n, m) = O(n \log n \log\log n + m)$
8269 ///
8270 /// $M(n, m) = O(n \log n + m)$
8271 ///
8272 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8273 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8274 ///
8275 /// # Examples
8276 /// ```
8277 /// use core::f64::consts::{E, PI};
8278 /// use malachite_base::num::arithmetic::traits::SubMul;
8279 /// use malachite_float::Float;
8280 /// use malachite_q::Rational;
8281 ///
8282 /// let x = Float::from(PI);
8283 /// let y = Float::from(E);
8284 /// let z = Rational::from_signeds(22, 7);
8285 /// assert_eq!(x.sub_mul(y, &z).to_string(), "-5.4015788072814912");
8286 /// ```
8287 #[inline]
8288 fn sub_mul(self, y: Self, z: &Rational) -> Self {
8289 let prec = max(self.significant_bits(), y.significant_bits());
8290 self.sub_mul_rational_prec_val_val_ref(y, z, prec).0
8291 }
8292}
8293
8294impl SubMul<&Self, Rational> for Float {
8295 type Output = Self;
8296 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], taking the
8297 /// first [`Float`] and the [`Rational`] by value and the second [`Float`] by reference.
8298 ///
8299 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8300 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
8301 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8302 ///
8303 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8304 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8305 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8306 /// the `Nearest` rounding mode.
8307 ///
8308 /// $$
8309 /// f(x,y,z) = x-yz+\varepsilon.
8310 /// $$
8311 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8312 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8313 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8314 ///
8315 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8316 ///
8317 /// Special cases:
8318 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
8319 /// - $f(x,\pm\infty,0)=\text{NaN}$
8320 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
8321 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
8322 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
8323 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
8324 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
8325 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
8326 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
8327 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
8328 /// zero [`Rational`] counting as positive.
8329 /// - $f(x,y,z)=0.0$ if $x=yz$ and $x$ is finite and nonzero
8330 ///
8331 /// Overflow and underflow:
8332 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8333 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8334 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8335 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8336 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
8337 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8338 ///
8339 /// If you want to use a rounding mode other than `Nearest`, consider using
8340 /// [`Float::sub_mul_rational_round`]. If you want to specify the output precision, consider
8341 /// using [`Float::sub_mul_rational_prec`]. If you want both of these things, consider using
8342 /// [`Float::sub_mul_rational_prec_round`].
8343 ///
8344 /// # Worst-case complexity
8345 /// $T(n, m) = O(n \log n \log\log n + m)$
8346 ///
8347 /// $M(n, m) = O(n \log n + m)$
8348 ///
8349 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8350 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8351 ///
8352 /// # Examples
8353 /// ```
8354 /// use core::f64::consts::{E, PI};
8355 /// use malachite_base::num::arithmetic::traits::SubMul;
8356 /// use malachite_float::Float;
8357 /// use malachite_q::Rational;
8358 ///
8359 /// let x = Float::from(PI);
8360 /// let y = Float::from(E);
8361 /// let z = Rational::from_signeds(22, 7);
8362 /// assert_eq!(x.sub_mul(&y, z).to_string(), "-5.4015788072814912");
8363 /// ```
8364 #[inline]
8365 fn sub_mul(self, y: &Self, z: Rational) -> Self {
8366 let prec = max(self.significant_bits(), y.significant_bits());
8367 self.sub_mul_rational_prec_val_ref_val(y, z, prec).0
8368 }
8369}
8370
8371impl SubMul<&Self, &Rational> for Float {
8372 type Output = Self;
8373 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], taking the
8374 /// first [`Float`] by value and the second [`Float`] and the [`Rational`] by reference.
8375 ///
8376 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8377 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
8378 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8379 ///
8380 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8381 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8382 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8383 /// the `Nearest` rounding mode.
8384 ///
8385 /// $$
8386 /// f(x,y,z) = x-yz+\varepsilon.
8387 /// $$
8388 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8389 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8390 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8391 ///
8392 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8393 ///
8394 /// Special cases:
8395 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
8396 /// - $f(x,\pm\infty,0)=\text{NaN}$
8397 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
8398 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
8399 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
8400 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
8401 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
8402 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
8403 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
8404 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
8405 /// zero [`Rational`] counting as positive.
8406 /// - $f(x,y,z)=0.0$ if $x=yz$ and $x$ is finite and nonzero
8407 ///
8408 /// Overflow and underflow:
8409 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8410 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8411 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8412 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8413 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
8414 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8415 ///
8416 /// If you want to use a rounding mode other than `Nearest`, consider using
8417 /// [`Float::sub_mul_rational_round`]. If you want to specify the output precision, consider
8418 /// using [`Float::sub_mul_rational_prec`]. If you want both of these things, consider using
8419 /// [`Float::sub_mul_rational_prec_round`].
8420 ///
8421 /// # Worst-case complexity
8422 /// $T(n, m) = O(n \log n \log\log n + m)$
8423 ///
8424 /// $M(n, m) = O(n \log n + m)$
8425 ///
8426 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8427 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8428 ///
8429 /// # Examples
8430 /// ```
8431 /// use core::f64::consts::{E, PI};
8432 /// use malachite_base::num::arithmetic::traits::SubMul;
8433 /// use malachite_float::Float;
8434 /// use malachite_q::Rational;
8435 ///
8436 /// let x = Float::from(PI);
8437 /// let y = Float::from(E);
8438 /// let z = Rational::from_signeds(22, 7);
8439 /// assert_eq!(x.sub_mul(&y, &z).to_string(), "-5.4015788072814912");
8440 /// ```
8441 #[inline]
8442 fn sub_mul(self, y: &Self, z: &Rational) -> Self {
8443 let prec = max(self.significant_bits(), y.significant_bits());
8444 self.sub_mul_rational_prec_val_ref_ref(y, z, prec).0
8445 }
8446}
8447
8448impl SubMul<Float, Rational> for &Float {
8449 type Output = Float;
8450 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], taking the
8451 /// first [`Float`] by reference and the second [`Float`] and the [`Rational`] by value.
8452 ///
8453 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8454 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
8455 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8456 ///
8457 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8458 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8459 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8460 /// the `Nearest` rounding mode.
8461 ///
8462 /// $$
8463 /// f(x,y,z) = x-yz+\varepsilon.
8464 /// $$
8465 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8466 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8467 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8468 ///
8469 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8470 ///
8471 /// Special cases:
8472 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
8473 /// - $f(x,\pm\infty,0)=\text{NaN}$
8474 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
8475 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
8476 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
8477 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
8478 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
8479 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
8480 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
8481 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
8482 /// zero [`Rational`] counting as positive.
8483 /// - $f(x,y,z)=0.0$ if $x=yz$ and $x$ is finite and nonzero
8484 ///
8485 /// Overflow and underflow:
8486 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8487 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8488 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8489 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8490 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
8491 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8492 ///
8493 /// If you want to use a rounding mode other than `Nearest`, consider using
8494 /// [`Float::sub_mul_rational_round`]. If you want to specify the output precision, consider
8495 /// using [`Float::sub_mul_rational_prec`]. If you want both of these things, consider using
8496 /// [`Float::sub_mul_rational_prec_round`].
8497 ///
8498 /// # Worst-case complexity
8499 /// $T(n, m) = O(n \log n \log\log n + m)$
8500 ///
8501 /// $M(n, m) = O(n \log n + m)$
8502 ///
8503 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8504 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8505 ///
8506 /// # Examples
8507 /// ```
8508 /// use core::f64::consts::{E, PI};
8509 /// use malachite_base::num::arithmetic::traits::SubMul;
8510 /// use malachite_float::Float;
8511 /// use malachite_q::Rational;
8512 ///
8513 /// let x = Float::from(PI);
8514 /// let y = Float::from(E);
8515 /// let z = Rational::from_signeds(22, 7);
8516 /// assert_eq!(&x.sub_mul(y, z).to_string(), "-5.4015788072814912");
8517 /// ```
8518 #[inline]
8519 fn sub_mul(self, y: Float, z: Rational) -> Float {
8520 let prec = max(self.significant_bits(), y.significant_bits());
8521 self.sub_mul_rational_prec_ref_val_val(y, z, prec).0
8522 }
8523}
8524
8525impl SubMul<Float, &Rational> for &Float {
8526 type Output = Float;
8527 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], taking the
8528 /// second [`Float`] by value and the first [`Float`] and the [`Rational`] by reference.
8529 ///
8530 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8531 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
8532 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8533 ///
8534 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8535 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8536 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8537 /// the `Nearest` rounding mode.
8538 ///
8539 /// $$
8540 /// f(x,y,z) = x-yz+\varepsilon.
8541 /// $$
8542 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8543 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8544 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8545 ///
8546 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8547 ///
8548 /// Special cases:
8549 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
8550 /// - $f(x,\pm\infty,0)=\text{NaN}$
8551 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
8552 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
8553 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
8554 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
8555 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
8556 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
8557 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
8558 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
8559 /// zero [`Rational`] counting as positive.
8560 /// - $f(x,y,z)=0.0$ if $x=yz$ and $x$ is finite and nonzero
8561 ///
8562 /// Overflow and underflow:
8563 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8564 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8565 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8566 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8567 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
8568 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8569 ///
8570 /// If you want to use a rounding mode other than `Nearest`, consider using
8571 /// [`Float::sub_mul_rational_round`]. If you want to specify the output precision, consider
8572 /// using [`Float::sub_mul_rational_prec`]. If you want both of these things, consider using
8573 /// [`Float::sub_mul_rational_prec_round`].
8574 ///
8575 /// # Worst-case complexity
8576 /// $T(n, m) = O(n \log n \log\log n + m)$
8577 ///
8578 /// $M(n, m) = O(n \log n + m)$
8579 ///
8580 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8581 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8582 ///
8583 /// # Examples
8584 /// ```
8585 /// use core::f64::consts::{E, PI};
8586 /// use malachite_base::num::arithmetic::traits::SubMul;
8587 /// use malachite_float::Float;
8588 /// use malachite_q::Rational;
8589 ///
8590 /// let x = Float::from(PI);
8591 /// let y = Float::from(E);
8592 /// let z = Rational::from_signeds(22, 7);
8593 /// assert_eq!(&x.sub_mul(y, &z).to_string(), "-5.4015788072814912");
8594 /// ```
8595 #[inline]
8596 fn sub_mul(self, y: Float, z: &Rational) -> Float {
8597 let prec = max(self.significant_bits(), y.significant_bits());
8598 self.sub_mul_rational_prec_ref_val_ref(y, z, prec).0
8599 }
8600}
8601
8602impl SubMul<&Float, Rational> for &Float {
8603 type Output = Float;
8604 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], taking the
8605 /// [`Float`]s by reference and the [`Rational`] by value.
8606 ///
8607 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8608 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
8609 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8610 ///
8611 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8612 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8613 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8614 /// the `Nearest` rounding mode.
8615 ///
8616 /// $$
8617 /// f(x,y,z) = x-yz+\varepsilon.
8618 /// $$
8619 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8620 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8621 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8622 ///
8623 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8624 ///
8625 /// Special cases:
8626 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
8627 /// - $f(x,\pm\infty,0)=\text{NaN}$
8628 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
8629 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
8630 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
8631 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
8632 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
8633 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
8634 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
8635 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
8636 /// zero [`Rational`] counting as positive.
8637 /// - $f(x,y,z)=0.0$ if $x=yz$ and $x$ is finite and nonzero
8638 ///
8639 /// Overflow and underflow:
8640 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8641 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8642 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8643 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8644 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
8645 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8646 ///
8647 /// If you want to use a rounding mode other than `Nearest`, consider using
8648 /// [`Float::sub_mul_rational_round`]. If you want to specify the output precision, consider
8649 /// using [`Float::sub_mul_rational_prec`]. If you want both of these things, consider using
8650 /// [`Float::sub_mul_rational_prec_round`].
8651 ///
8652 /// # Worst-case complexity
8653 /// $T(n, m) = O(n \log n \log\log n + m)$
8654 ///
8655 /// $M(n, m) = O(n \log n + m)$
8656 ///
8657 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8658 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8659 ///
8660 /// # Examples
8661 /// ```
8662 /// use core::f64::consts::{E, PI};
8663 /// use malachite_base::num::arithmetic::traits::SubMul;
8664 /// use malachite_float::Float;
8665 /// use malachite_q::Rational;
8666 ///
8667 /// let x = Float::from(PI);
8668 /// let y = Float::from(E);
8669 /// let z = Rational::from_signeds(22, 7);
8670 /// assert_eq!(&x.sub_mul(&y, z).to_string(), "-5.4015788072814912");
8671 /// ```
8672 #[inline]
8673 fn sub_mul(self, y: &Float, z: Rational) -> Float {
8674 let prec = max(self.significant_bits(), y.significant_bits());
8675 self.sub_mul_rational_prec_ref_ref_val(y, z, prec).0
8676 }
8677}
8678
8679impl SubMul<&Float, &Rational> for &Float {
8680 type Output = Float;
8681 /// Subtracts the product of a [`Float`] and a [`Rational`] from another [`Float`], taking all
8682 /// three by reference.
8683 ///
8684 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8685 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
8686 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8687 ///
8688 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8689 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8690 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8691 /// the `Nearest` rounding mode.
8692 ///
8693 /// $$
8694 /// f(x,y,z) = x-yz+\varepsilon.
8695 /// $$
8696 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8697 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8698 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8699 ///
8700 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8701 ///
8702 /// Special cases:
8703 /// - $f(\text{NaN},y,z)=f(x,\text{NaN},z)=\text{NaN}$
8704 /// - $f(x,\pm\infty,0)=\text{NaN}$
8705 /// - $f(\infty,y,z)=\text{NaN}$ if $yz=\infty$
8706 /// - $f(-\infty,y,z)=\text{NaN}$ if $yz=-\infty$
8707 /// - $f(\infty,y,z)=\infty$ if $y$ is not `NaN` and $yz\neq\infty$
8708 /// - $f(-\infty,y,z)=-\infty$ if $y$ is not `NaN` and $yz\neq-\infty$
8709 /// - $f(x,y,z)=-\infty$ if $x$ is finite and $yz=\infty$
8710 /// - $f(x,y,z)=\infty$ if $x$ is finite and $yz=-\infty$
8711 /// - If $x$ and the product $yz$ are both zeros, the sign rules of [`Float`] addition apply to
8712 /// $x$ and $-yz$; the product is a zero whose sign is the XOR of the signs of $y$ and $z$, a
8713 /// zero [`Rational`] counting as positive.
8714 /// - $f(x,y,z)=0.0$ if $x=yz$ and $x$ is finite and nonzero
8715 ///
8716 /// Overflow and underflow:
8717 /// - If $f(x,y,z)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
8718 /// - If $f(x,y,z)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
8719 /// - If $0<f(x,y,z)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
8720 /// - If $2^{-2^{30}-1}<f(x,y,z)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
8721 /// - If $-2^{-2^{30}-1}\leq f(x,y,z)<0$, $-0.0$ is returned instead.
8722 /// - If $-2^{-2^{30}}<f(x,y,z)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
8723 ///
8724 /// If you want to use a rounding mode other than `Nearest`, consider using
8725 /// [`Float::sub_mul_rational_round`]. If you want to specify the output precision, consider
8726 /// using [`Float::sub_mul_rational_prec`]. If you want both of these things, consider using
8727 /// [`Float::sub_mul_rational_prec_round`].
8728 ///
8729 /// # Worst-case complexity
8730 /// $T(n, m) = O(n \log n \log\log n + m)$
8731 ///
8732 /// $M(n, m) = O(n \log n + m)$
8733 ///
8734 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8735 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8736 ///
8737 /// # Examples
8738 /// ```
8739 /// use core::f64::consts::{E, PI};
8740 /// use malachite_base::num::arithmetic::traits::SubMul;
8741 /// use malachite_float::Float;
8742 /// use malachite_q::Rational;
8743 ///
8744 /// let x = Float::from(PI);
8745 /// let y = Float::from(E);
8746 /// let z = Rational::from_signeds(22, 7);
8747 /// assert_eq!(&x.sub_mul(&y, &z).to_string(), "-5.4015788072814912");
8748 /// ```
8749 #[inline]
8750 fn sub_mul(self, y: &Float, z: &Rational) -> Float {
8751 let prec = max(self.significant_bits(), y.significant_bits());
8752 self.sub_mul_rational_prec_ref_ref_ref(y, z, prec).0
8753 }
8754}
8755
8756impl SubMulAssign<Self, Rational> for Float {
8757 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place. The
8758 /// [`Float`] and the [`Rational`] on the right-hand side are both taken by value.
8759 ///
8760 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8761 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
8762 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8763 ///
8764 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8765 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8766 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8767 /// the `Nearest` rounding mode.
8768 ///
8769 /// $$
8770 /// x \gets x-yz+\varepsilon.
8771 /// $$
8772 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8773 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8774 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8775 ///
8776 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
8777 /// cases, overflow, and underflow.
8778 ///
8779 /// If you want to use a rounding mode other than `Nearest`, consider using
8780 /// [`Float::sub_mul_rational_round_assign`]. If you want to specify the output precision,
8781 /// consider using [`Float::sub_mul_rational_prec_assign`]. If you want both of these things,
8782 /// consider using [`Float::sub_mul_rational_prec_round_assign`].
8783 ///
8784 /// # Worst-case complexity
8785 /// $T(n, m) = O(n \log n \log\log n + m)$
8786 ///
8787 /// $M(n, m) = O(n \log n + m)$
8788 ///
8789 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8790 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8791 ///
8792 /// # Examples
8793 /// ```
8794 /// use core::f64::consts::{E, PI};
8795 /// use malachite_base::num::arithmetic::traits::SubMulAssign;
8796 /// use malachite_float::Float;
8797 /// use malachite_q::Rational;
8798 ///
8799 /// let mut x = Float::from(PI);
8800 /// let y = Float::from(E);
8801 /// let z = Rational::from_signeds(22, 7);
8802 /// x.sub_mul_assign(y, z);
8803 /// assert_eq!(x.to_string(), "-5.4015788072814912");
8804 /// ```
8805 #[inline]
8806 fn sub_mul_assign(&mut self, y: Self, z: Rational) {
8807 let prec = max(self.significant_bits(), y.significant_bits());
8808 self.sub_mul_rational_prec_assign(y, z, prec);
8809 }
8810}
8811
8812impl SubMulAssign<Self, &Rational> for Float {
8813 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place. The
8814 /// [`Float`] on the right-hand side is taken by value and the [`Rational`] by reference.
8815 ///
8816 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8817 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
8818 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8819 ///
8820 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8821 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8822 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8823 /// the `Nearest` rounding mode.
8824 ///
8825 /// $$
8826 /// x \gets x-yz+\varepsilon.
8827 /// $$
8828 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8829 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8830 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8831 ///
8832 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
8833 /// cases, overflow, and underflow.
8834 ///
8835 /// If you want to use a rounding mode other than `Nearest`, consider using
8836 /// [`Float::sub_mul_rational_round_assign`]. If you want to specify the output precision,
8837 /// consider using [`Float::sub_mul_rational_prec_assign`]. If you want both of these things,
8838 /// consider using [`Float::sub_mul_rational_prec_round_assign`].
8839 ///
8840 /// # Worst-case complexity
8841 /// $T(n, m) = O(n \log n \log\log n + m)$
8842 ///
8843 /// $M(n, m) = O(n \log n + m)$
8844 ///
8845 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8846 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8847 ///
8848 /// # Examples
8849 /// ```
8850 /// use core::f64::consts::{E, PI};
8851 /// use malachite_base::num::arithmetic::traits::SubMulAssign;
8852 /// use malachite_float::Float;
8853 /// use malachite_q::Rational;
8854 ///
8855 /// let mut x = Float::from(PI);
8856 /// let y = Float::from(E);
8857 /// let z = Rational::from_signeds(22, 7);
8858 /// x.sub_mul_assign(y, &z);
8859 /// assert_eq!(x.to_string(), "-5.4015788072814912");
8860 /// ```
8861 #[inline]
8862 fn sub_mul_assign(&mut self, y: Self, z: &Rational) {
8863 let prec = max(self.significant_bits(), y.significant_bits());
8864 self.sub_mul_rational_prec_assign_val_ref(y, z, prec);
8865 }
8866}
8867
8868impl SubMulAssign<&Self, Rational> for Float {
8869 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place. The
8870 /// [`Float`] on the right-hand side is taken by reference and the [`Rational`] by value.
8871 ///
8872 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8873 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
8874 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8875 ///
8876 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8877 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8878 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8879 /// the `Nearest` rounding mode.
8880 ///
8881 /// $$
8882 /// x \gets x-yz+\varepsilon.
8883 /// $$
8884 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8885 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8886 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8887 ///
8888 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
8889 /// cases, overflow, and underflow.
8890 ///
8891 /// If you want to use a rounding mode other than `Nearest`, consider using
8892 /// [`Float::sub_mul_rational_round_assign`]. If you want to specify the output precision,
8893 /// consider using [`Float::sub_mul_rational_prec_assign`]. If you want both of these things,
8894 /// consider using [`Float::sub_mul_rational_prec_round_assign`].
8895 ///
8896 /// # Worst-case complexity
8897 /// $T(n, m) = O(n \log n \log\log n + m)$
8898 ///
8899 /// $M(n, m) = O(n \log n + m)$
8900 ///
8901 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8902 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8903 ///
8904 /// # Examples
8905 /// ```
8906 /// use core::f64::consts::{E, PI};
8907 /// use malachite_base::num::arithmetic::traits::SubMulAssign;
8908 /// use malachite_float::Float;
8909 /// use malachite_q::Rational;
8910 ///
8911 /// let mut x = Float::from(PI);
8912 /// let y = Float::from(E);
8913 /// let z = Rational::from_signeds(22, 7);
8914 /// x.sub_mul_assign(&y, z);
8915 /// assert_eq!(x.to_string(), "-5.4015788072814912");
8916 /// ```
8917 #[inline]
8918 fn sub_mul_assign(&mut self, y: &Self, z: Rational) {
8919 let prec = max(self.significant_bits(), y.significant_bits());
8920 self.sub_mul_rational_prec_assign_ref_val(y, z, prec);
8921 }
8922}
8923
8924impl SubMulAssign<&Self, &Rational> for Float {
8925 /// Subtracts the product of a [`Float`] and a [`Rational`] from a [`Float`] in place. The
8926 /// [`Float`] and the [`Rational`] on the right-hand side are both taken by reference.
8927 ///
8928 /// The [`Rational`] multiplicand enters the product exactly: it is never rounded to a [`Float`]
8929 /// first, so the result is the true value of $x-yz$ with a single rounding at the end. Rounding
8930 /// the [`Rational`] first would perturb the result by $y$ times the conversion error.
8931 ///
8932 /// If the output has a precision, it is the maximum of the precisions of the input [`Float`]s.
8933 /// If the diff is equidistant from two [`Float`]s with the specified precision, the [`Float`]
8934 /// with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of
8935 /// the `Nearest` rounding mode.
8936 ///
8937 /// $$
8938 /// x \gets x-yz+\varepsilon.
8939 /// $$
8940 /// - If $x-yz$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
8941 /// - If $x-yz$ is finite and nonzero, then $|\varepsilon| \leq 2^{\lfloor\log_2
8942 /// |x-yz|\rfloor-p}$, where $p$ is the maximum precision of the input [`Float`]s.
8943 ///
8944 /// See the [`Float::sub_mul_rational_prec_round`] documentation for information on special
8945 /// cases, overflow, and underflow.
8946 ///
8947 /// If you want to use a rounding mode other than `Nearest`, consider using
8948 /// [`Float::sub_mul_rational_round_assign`]. If you want to specify the output precision,
8949 /// consider using [`Float::sub_mul_rational_prec_assign`]. If you want both of these things,
8950 /// consider using [`Float::sub_mul_rational_prec_round_assign`].
8951 ///
8952 /// # Worst-case complexity
8953 /// $T(n, m) = O(n \log n \log\log n + m)$
8954 ///
8955 /// $M(n, m) = O(n \log n + m)$
8956 ///
8957 /// where $T$ is time, $M$ is additional memory, $n$ is `self.significant_bits() +
8958 /// y.significant_bits() + z.significant_bits()`, and $m$ is `self.significant_bits()`.
8959 ///
8960 /// # Examples
8961 /// ```
8962 /// use core::f64::consts::{E, PI};
8963 /// use malachite_base::num::arithmetic::traits::SubMulAssign;
8964 /// use malachite_float::Float;
8965 /// use malachite_q::Rational;
8966 ///
8967 /// let mut x = Float::from(PI);
8968 /// let y = Float::from(E);
8969 /// let z = Rational::from_signeds(22, 7);
8970 /// x.sub_mul_assign(&y, &z);
8971 /// assert_eq!(x.to_string(), "-5.4015788072814912");
8972 /// ```
8973 #[inline]
8974 fn sub_mul_assign(&mut self, y: &Self, z: &Rational) {
8975 let prec = max(self.significant_bits(), y.significant_bits());
8976 self.sub_mul_rational_prec_assign_ref_ref(y, z, prec);
8977 }
8978}
8979
8980/// Subtracts the product of two primitive floats from another primitive float with a single
8981/// rounding, using emulated [`Float`] arithmetic.
8982///
8983/// This is a correctly-rounded fused multiply-subtract: the product is not rounded before the
8984/// subtraction, so the result is the true value of $x-yz$ rounded once to the nearest representable
8985/// value. It agrees with the standard library's hardware-backed `mul_add` with the multiplicand
8986/// negated, up to argument order.
8987///
8988/// # Worst-case complexity
8989/// Constant time and additional memory.
8990///
8991/// # Examples
8992/// ```
8993/// use core::f64::consts::{E, PI, SQRT_2};
8994/// use malachite_base::num::float::NiceFloat;
8995/// use malachite_float::float::arithmetic::sub_mul::*;
8996///
8997/// assert_eq!(
8998/// NiceFloat(primitive_float_sub_mul(PI, E, SQRT_2)),
8999/// NiceFloat(-0.7026383745693238)
9000/// );
9001/// ```
9002#[allow(clippy::type_repetition_in_bounds)]
9003#[inline]
9004pub fn primitive_float_sub_mul<T: PrimitiveFloat>(x: T, y: T, z: T) -> T
9005where
9006 Float: From<T> + PartialOrd<T>,
9007 for<'a> T: ExactFrom<&'a Float>,
9008{
9009 emulate_float_float_float_to_float_fn(Float::sub_mul_prec, x, y, z)
9010}
9011
9012/// Subtracts the product of a primitive float and a [`Rational`] from another primitive float, with
9013/// a single rounding, using emulated [`Float`] arithmetic.
9014///
9015/// The [`Rational`] multiplicand enters the product exactly, and the result is the true value of
9016/// $x-yz$ rounded once to the nearest representable value.
9017///
9018/// # Worst-case complexity
9019/// $T(n) = O(n \log n \log\log n)$
9020///
9021/// $M(n) = O(n \log n)$
9022///
9023/// where $T$ is time, $M$ is additional memory, and $n$ is `z.significant_bits()`.
9024///
9025/// # Examples
9026/// ```
9027/// use core::f64::consts::{E, PI};
9028/// use malachite_base::num::float::NiceFloat;
9029/// use malachite_float::float::arithmetic::sub_mul::*;
9030/// use malachite_q::Rational;
9031///
9032/// assert_eq!(
9033/// NiceFloat(primitive_float_sub_mul_rational(
9034/// PI,
9035/// E,
9036/// &Rational::from_signeds(22, 7)
9037/// )),
9038/// NiceFloat(-5.401578807281491)
9039/// );
9040/// ```
9041#[allow(clippy::type_repetition_in_bounds)]
9042#[inline]
9043pub fn primitive_float_sub_mul_rational<T: PrimitiveFloat>(x: T, y: T, z: &Rational) -> T
9044where
9045 Float: From<T> + PartialOrd<T>,
9046 for<'a> T: ExactFrom<&'a Float>,
9047{
9048 emulate_float_float_to_float_fn(
9049 |x, y, prec| x.sub_mul_rational_prec_val_val_ref(y, z, prec),
9050 x,
9051 y,
9052 )
9053}