malachite_float/float/arithmetic/positive_difference.rs
1// Copyright © 2026 Mikhail Hogrefe
2//
3// Uses code adopted from the GNU MPFR Library.
4//
5// Copyright © 2001-2025 Free Software Foundation, Inc.
6//
7// This file is part of Malachite.
8//
9// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
10// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
11// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
12
13use crate::InnerFloat::NaN;
14use crate::{Float, emulate_float_float_to_float_fn, emulate_float_to_float_fn, float_nan};
15use core::cmp::Ordering::{self, Equal, Greater, Less};
16use core::cmp::max;
17use malachite_base::num::basic::floats::PrimitiveFloat;
18use malachite_base::num::basic::traits::Zero as ZeroTrait;
19use malachite_base::num::conversion::traits::ExactFrom;
20use malachite_base::num::logic::traits::SignificantBits;
21use malachite_base::rounding_modes::RoundingMode::{self, Nearest};
22use malachite_q::Rational;
23
24// This is mpfr_dim from dim.c, MPFR 4.2.2, with the result's precision passed explicitly. The
25// positive difference is x - y if x > y, and +0 otherwise (a definition choice: negative values are
26// representable, but the function returns zero for them); NaN if either input is NaN. The
27// comparison treats zeros of both signs as equal and infinities as their usual extremes, so
28// dim(Infinity, Infinity) is +0.
29
30impl Float {
31 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
32 /// — rounding the result to the specified precision and with the specified rounding mode.
33 /// Both [`Float`]s are taken by value. An [`Ordering`] is also returned, indicating whether the
34 /// rounded result is less than, equal to, or greater than the exact positive difference.
35 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
36 /// it also returns `Equal`.
37 ///
38 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
39 /// as a matter of definition — negative values are representable, but the function chooses
40 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
41 /// both signs as equal and infinities as their usual extremes.
42 ///
43 /// Special cases:
44 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
45 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
46 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
47 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
48 ///
49 /// Overflow and underflow are as for subtraction:
50 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
51 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
52 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
53 ///
54 /// $$
55 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
56 /// $$
57 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
58 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
59 ///
60 /// If you know you'll be using `Nearest`, consider using [`Float::positive_difference_prec`]
61 /// instead. If you know that your target precision is the maximum of the precisions of the two
62 /// inputs, consider using [`Float::positive_difference_round`] instead. If both of these things
63 /// are true, consider using [`Float::positive_difference`] instead.
64 ///
65 /// # Worst-case complexity
66 /// $T(n) = O(n)$
67 ///
68 /// $M(n) = O(n)$
69 ///
70 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
71 /// other.significant_bits(), prec)`.
72 ///
73 /// # Panics
74 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
75 /// representable with `prec` bits.
76 ///
77 /// # Examples
78 /// ```
79 /// use core::cmp::Ordering::*;
80 /// use malachite_base::num::basic::traits::One;
81 /// use malachite_base::rounding_modes::RoundingMode::*;
82 /// use malachite_float::Float;
83 ///
84 /// let (d, o) = Float::from(3u32).positive_difference_prec_round(Float::ONE, 10, Floor);
85 /// assert_eq!(d.to_string(), "2.0000");
86 /// assert_eq!(o, Equal);
87 ///
88 /// let (d, o) = Float::from(10u32).positive_difference_prec_round(Float::from(7u32), 1, Floor);
89 /// assert_eq!(d.to_string(), "2.0");
90 /// assert_eq!(o, Less);
91 ///
92 /// let (d, o) =
93 /// Float::from(10u32).positive_difference_prec_round(Float::from(7u32), 1, Ceiling);
94 /// assert_eq!(d.to_string(), "4.0");
95 /// assert_eq!(o, Greater);
96 /// ```
97 pub fn positive_difference_prec_round(
98 self,
99 other: Self,
100 prec: u64,
101 rm: RoundingMode,
102 ) -> (Self, Ordering) {
103 assert_ne!(prec, 0);
104 if matches!(self.partial_cmp(&other), Some(Greater)) {
105 self.sub_prec_round(other, prec, rm)
106 } else if matches!(self, Self(NaN)) || matches!(other, Self(NaN)) {
107 (float_nan!(), Equal)
108 } else {
109 (Self::ZERO, Equal)
110 }
111 }
112
113 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
114 /// — rounding the result to the specified precision and with the specified rounding mode. The
115 /// first [`Float`] is taken by value and the second by reference. An [`Ordering`] is also
116 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
117 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
118 /// this function returns a `NaN` it also returns `Equal`.
119 ///
120 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
121 /// as a matter of definition — negative values are representable, but the function chooses
122 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
123 /// both signs as equal and infinities as their usual extremes.
124 ///
125 /// Special cases:
126 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
127 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
128 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
129 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
130 ///
131 /// Overflow and underflow are as for subtraction:
132 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
133 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
134 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
135 ///
136 /// $$
137 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
138 /// $$
139 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
140 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
141 ///
142 /// If you know you'll be using `Nearest`, consider using [`Float::positive_difference_prec`]
143 /// instead. If you know that your target precision is the maximum of the precisions of the two
144 /// inputs, consider using [`Float::positive_difference_round`] instead. If both of these things
145 /// are true, consider using [`Float::positive_difference`] instead.
146 ///
147 /// # Worst-case complexity
148 /// $T(n) = O(n)$
149 ///
150 /// $M(n) = O(n)$
151 ///
152 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
153 /// other.significant_bits(), prec)`.
154 ///
155 /// # Panics
156 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
157 /// representable with `prec` bits.
158 ///
159 /// # Examples
160 /// ```
161 /// use core::cmp::Ordering::*;
162 /// use malachite_base::num::basic::traits::One;
163 /// use malachite_base::rounding_modes::RoundingMode::*;
164 /// use malachite_float::Float;
165 ///
166 /// let (d, o) =
167 /// Float::from(3u32).positive_difference_prec_round_val_ref(&Float::ONE, 10, Floor);
168 /// assert_eq!(d.to_string(), "2.0000");
169 /// assert_eq!(o, Equal);
170 ///
171 /// let (d, o) =
172 /// Float::from(10u32).positive_difference_prec_round_val_ref(&Float::from(7u32), 1, Floor);
173 /// assert_eq!(d.to_string(), "2.0");
174 /// assert_eq!(o, Less);
175 ///
176 /// let (d, o) = Float::from(10u32).positive_difference_prec_round_val_ref(
177 /// &Float::from(7u32),
178 /// 1,
179 /// Ceiling,
180 /// );
181 /// assert_eq!(d.to_string(), "4.0");
182 /// assert_eq!(o, Greater);
183 /// ```
184 pub fn positive_difference_prec_round_val_ref(
185 self,
186 other: &Self,
187 prec: u64,
188 rm: RoundingMode,
189 ) -> (Self, Ordering) {
190 assert_ne!(prec, 0);
191 if matches!(self.partial_cmp(other), Some(Greater)) {
192 self.sub_prec_round_val_ref(other, prec, rm)
193 } else if matches!(self, Self(NaN)) || matches!(other, Self(NaN)) {
194 (float_nan!(), Equal)
195 } else {
196 (Self::ZERO, Equal)
197 }
198 }
199
200 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
201 /// — rounding the result to the specified precision and with the specified rounding mode. The
202 /// first [`Float`] is taken by reference and the second by value. An [`Ordering`] is also
203 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
204 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
205 /// this function returns a `NaN` it also returns `Equal`.
206 ///
207 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
208 /// as a matter of definition — negative values are representable, but the function chooses
209 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
210 /// both signs as equal and infinities as their usual extremes.
211 ///
212 /// Special cases:
213 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
214 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
215 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
216 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
217 ///
218 /// Overflow and underflow are as for subtraction:
219 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
220 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
221 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
222 ///
223 /// $$
224 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
225 /// $$
226 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
227 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
228 ///
229 /// If you know you'll be using `Nearest`, consider using [`Float::positive_difference_prec`]
230 /// instead. If you know that your target precision is the maximum of the precisions of the two
231 /// inputs, consider using [`Float::positive_difference_round`] instead. If both of these things
232 /// are true, consider using [`Float::positive_difference`] instead.
233 ///
234 /// # Worst-case complexity
235 /// $T(n) = O(n)$
236 ///
237 /// $M(n) = O(n)$
238 ///
239 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
240 /// other.significant_bits(), prec)`.
241 ///
242 /// # Panics
243 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
244 /// representable with `prec` bits.
245 ///
246 /// # Examples
247 /// ```
248 /// use core::cmp::Ordering::*;
249 /// use malachite_base::num::basic::traits::One;
250 /// use malachite_base::rounding_modes::RoundingMode::*;
251 /// use malachite_float::Float;
252 ///
253 /// let (d, o) =
254 /// Float::from(3u32).positive_difference_prec_round_ref_val(Float::ONE, 10, Floor);
255 /// assert_eq!(d.to_string(), "2.0000");
256 /// assert_eq!(o, Equal);
257 ///
258 /// let (d, o) =
259 /// Float::from(10u32).positive_difference_prec_round_ref_val(Float::from(7u32), 1, Floor);
260 /// assert_eq!(d.to_string(), "2.0");
261 /// assert_eq!(o, Less);
262 ///
263 /// let (d, o) = Float::from(10u32).positive_difference_prec_round_ref_val(
264 /// Float::from(7u32),
265 /// 1,
266 /// Ceiling,
267 /// );
268 /// assert_eq!(d.to_string(), "4.0");
269 /// assert_eq!(o, Greater);
270 /// ```
271 pub fn positive_difference_prec_round_ref_val(
272 &self,
273 other: Self,
274 prec: u64,
275 rm: RoundingMode,
276 ) -> (Self, Ordering) {
277 assert_ne!(prec, 0);
278 if matches!((*self).partial_cmp(&other), Some(Greater)) {
279 self.sub_prec_round_ref_val(other, prec, rm)
280 } else if matches!(self, Self(NaN)) || matches!(other, Self(NaN)) {
281 (float_nan!(), Equal)
282 } else {
283 (Self::ZERO, Equal)
284 }
285 }
286
287 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
288 /// — rounding the result to the specified precision and with the specified rounding mode.
289 /// Both [`Float`]s are taken by reference. An [`Ordering`] is also returned, indicating whether
290 /// the rounded result is less than, equal to, or greater than the exact positive difference.
291 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
292 /// it also returns `Equal`.
293 ///
294 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
295 /// as a matter of definition — negative values are representable, but the function chooses
296 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
297 /// both signs as equal and infinities as their usual extremes.
298 ///
299 /// Special cases:
300 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
301 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
302 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
303 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
304 ///
305 /// Overflow and underflow are as for subtraction:
306 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
307 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
308 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
309 ///
310 /// $$
311 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
312 /// $$
313 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
314 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
315 ///
316 /// If you know you'll be using `Nearest`, consider using [`Float::positive_difference_prec`]
317 /// instead. If you know that your target precision is the maximum of the precisions of the two
318 /// inputs, consider using [`Float::positive_difference_round`] instead. If both of these things
319 /// are true, consider using [`Float::positive_difference`] instead.
320 ///
321 /// # Worst-case complexity
322 /// $T(n) = O(n)$
323 ///
324 /// $M(n) = O(n)$
325 ///
326 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
327 /// other.significant_bits(), prec)`.
328 ///
329 /// # Panics
330 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
331 /// representable with `prec` bits.
332 ///
333 /// # Examples
334 /// ```
335 /// use core::cmp::Ordering::*;
336 /// use malachite_base::num::basic::traits::One;
337 /// use malachite_base::rounding_modes::RoundingMode::*;
338 /// use malachite_float::Float;
339 ///
340 /// let (d, o) =
341 /// Float::from(3u32).positive_difference_prec_round_ref_ref(&Float::ONE, 10, Floor);
342 /// assert_eq!(d.to_string(), "2.0000");
343 /// assert_eq!(o, Equal);
344 ///
345 /// let (d, o) =
346 /// Float::from(10u32).positive_difference_prec_round_ref_ref(&Float::from(7u32), 1, Floor);
347 /// assert_eq!(d.to_string(), "2.0");
348 /// assert_eq!(o, Less);
349 ///
350 /// let (d, o) = Float::from(10u32).positive_difference_prec_round_ref_ref(
351 /// &Float::from(7u32),
352 /// 1,
353 /// Ceiling,
354 /// );
355 /// assert_eq!(d.to_string(), "4.0");
356 /// assert_eq!(o, Greater);
357 /// ```
358 pub fn positive_difference_prec_round_ref_ref(
359 &self,
360 other: &Self,
361 prec: u64,
362 rm: RoundingMode,
363 ) -> (Self, Ordering) {
364 assert_ne!(prec, 0);
365 if matches!((*self).partial_cmp(other), Some(Greater)) {
366 self.sub_prec_round_ref_ref(other, prec, rm)
367 } else if matches!(self, Self(NaN)) || matches!(other, Self(NaN)) {
368 (float_nan!(), Equal)
369 } else {
370 (Self::ZERO, Equal)
371 }
372 }
373
374 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
375 /// — rounding the result to the nearest value of the specified precision. Both [`Float`]s are
376 /// taken by value. An [`Ordering`] is also returned, indicating whether the rounded result is
377 /// less than, equal to, or greater than the exact positive difference. Although `NaN`s are not
378 /// comparable to any [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
379 ///
380 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
381 /// as a matter of definition — negative values are representable, but the function chooses
382 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
383 /// both signs as equal and infinities as their usual extremes.
384 ///
385 /// Special cases:
386 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
387 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
388 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
389 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
390 ///
391 /// Overflow and underflow are as for subtraction:
392 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
393 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
394 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
395 ///
396 /// $$
397 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
398 /// $$
399 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
400 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
401 ///
402 /// If you want to use a rounding mode other than `Nearest`, consider using
403 /// [`Float::positive_difference_prec_round`] instead. If you know that your target precision is
404 /// the maximum of the precisions of the two inputs, consider using
405 /// [`Float::positive_difference`] instead.
406 ///
407 /// # Worst-case complexity
408 /// $T(n) = O(n)$
409 ///
410 /// $M(n) = O(n)$
411 ///
412 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
413 /// other.significant_bits(), prec)`.
414 ///
415 /// # Panics
416 /// Panics if `prec` is zero.
417 ///
418 /// # Examples
419 /// ```
420 /// use core::cmp::Ordering::*;
421 /// use malachite_base::num::basic::traits::One;
422 /// use malachite_float::Float;
423 ///
424 /// let (d, o) = Float::from(3u32).positive_difference_prec(Float::ONE, 10);
425 /// assert_eq!(d.to_string(), "2.0000");
426 /// assert_eq!(o, Equal);
427 /// ```
428 #[inline]
429 pub fn positive_difference_prec(self, other: Self, prec: u64) -> (Self, Ordering) {
430 self.positive_difference_prec_round(other, prec, Nearest)
431 }
432
433 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
434 /// — rounding the result to the nearest value of the specified precision. The first [`Float`]
435 /// is taken by value and the second by reference. An [`Ordering`] is also returned, indicating
436 /// whether the rounded result is less than, equal to, or greater than the exact positive
437 /// difference. Although `NaN`s are not comparable to any [`Float`], whenever this function
438 /// returns a `NaN` it also returns `Equal`.
439 ///
440 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
441 /// as a matter of definition — negative values are representable, but the function chooses
442 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
443 /// both signs as equal and infinities as their usual extremes.
444 ///
445 /// Special cases:
446 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
447 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
448 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
449 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
450 ///
451 /// Overflow and underflow are as for subtraction:
452 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
453 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
454 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
455 ///
456 /// $$
457 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
458 /// $$
459 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
460 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
461 ///
462 /// If you want to use a rounding mode other than `Nearest`, consider using
463 /// [`Float::positive_difference_prec_round`] instead. If you know that your target precision is
464 /// the maximum of the precisions of the two inputs, consider using
465 /// [`Float::positive_difference`] instead.
466 ///
467 /// # Worst-case complexity
468 /// $T(n) = O(n)$
469 ///
470 /// $M(n) = O(n)$
471 ///
472 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
473 /// other.significant_bits(), prec)`.
474 ///
475 /// # Panics
476 /// Panics if `prec` is zero.
477 ///
478 /// # Examples
479 /// ```
480 /// use core::cmp::Ordering::*;
481 /// use malachite_base::num::basic::traits::One;
482 /// use malachite_float::Float;
483 ///
484 /// let (d, o) = Float::from(3u32).positive_difference_prec_val_ref(&Float::ONE, 10);
485 /// assert_eq!(d.to_string(), "2.0000");
486 /// assert_eq!(o, Equal);
487 /// ```
488 #[inline]
489 pub fn positive_difference_prec_val_ref(self, other: &Self, prec: u64) -> (Self, Ordering) {
490 self.positive_difference_prec_round_val_ref(other, prec, Nearest)
491 }
492
493 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
494 /// — rounding the result to the nearest value of the specified precision. The first [`Float`]
495 /// is taken by reference and the second by value. An [`Ordering`] is also returned, indicating
496 /// whether the rounded result is less than, equal to, or greater than the exact positive
497 /// difference. Although `NaN`s are not comparable to any [`Float`], whenever this function
498 /// returns a `NaN` it also returns `Equal`.
499 ///
500 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
501 /// as a matter of definition — negative values are representable, but the function chooses
502 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
503 /// both signs as equal and infinities as their usual extremes.
504 ///
505 /// Special cases:
506 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
507 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
508 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
509 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
510 ///
511 /// Overflow and underflow are as for subtraction:
512 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
513 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
514 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
515 ///
516 /// $$
517 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
518 /// $$
519 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
520 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
521 ///
522 /// If you want to use a rounding mode other than `Nearest`, consider using
523 /// [`Float::positive_difference_prec_round`] instead. If you know that your target precision is
524 /// the maximum of the precisions of the two inputs, consider using
525 /// [`Float::positive_difference`] instead.
526 ///
527 /// # Worst-case complexity
528 /// $T(n) = O(n)$
529 ///
530 /// $M(n) = O(n)$
531 ///
532 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
533 /// other.significant_bits(), prec)`.
534 ///
535 /// # Panics
536 /// Panics if `prec` is zero.
537 ///
538 /// # Examples
539 /// ```
540 /// use core::cmp::Ordering::*;
541 /// use malachite_base::num::basic::traits::One;
542 /// use malachite_float::Float;
543 ///
544 /// let (d, o) = Float::from(3u32).positive_difference_prec_ref_val(Float::ONE, 10);
545 /// assert_eq!(d.to_string(), "2.0000");
546 /// assert_eq!(o, Equal);
547 /// ```
548 #[inline]
549 pub fn positive_difference_prec_ref_val(&self, other: Self, prec: u64) -> (Self, Ordering) {
550 self.positive_difference_prec_round_ref_val(other, prec, Nearest)
551 }
552
553 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
554 /// — rounding the result to the nearest value of the specified precision. Both [`Float`]s are
555 /// taken by reference. An [`Ordering`] is also returned, indicating whether the rounded result
556 /// is less than, equal to, or greater than the exact positive difference. Although `NaN`s are
557 /// not comparable to any [`Float`], whenever this function returns a `NaN` it also returns
558 /// `Equal`.
559 ///
560 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
561 /// as a matter of definition — negative values are representable, but the function chooses
562 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
563 /// both signs as equal and infinities as their usual extremes.
564 ///
565 /// Special cases:
566 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
567 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
568 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
569 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
570 ///
571 /// Overflow and underflow are as for subtraction:
572 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
573 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
574 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
575 ///
576 /// $$
577 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
578 /// $$
579 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
580 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
581 ///
582 /// If you want to use a rounding mode other than `Nearest`, consider using
583 /// [`Float::positive_difference_prec_round`] instead. If you know that your target precision is
584 /// the maximum of the precisions of the two inputs, consider using
585 /// [`Float::positive_difference`] instead.
586 ///
587 /// # Worst-case complexity
588 /// $T(n) = O(n)$
589 ///
590 /// $M(n) = O(n)$
591 ///
592 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
593 /// other.significant_bits(), prec)`.
594 ///
595 /// # Panics
596 /// Panics if `prec` is zero.
597 ///
598 /// # Examples
599 /// ```
600 /// use core::cmp::Ordering::*;
601 /// use malachite_base::num::basic::traits::One;
602 /// use malachite_float::Float;
603 ///
604 /// let (d, o) = Float::from(3u32).positive_difference_prec_ref_ref(&Float::ONE, 10);
605 /// assert_eq!(d.to_string(), "2.0000");
606 /// assert_eq!(o, Equal);
607 /// ```
608 #[inline]
609 pub fn positive_difference_prec_ref_ref(&self, other: &Self, prec: u64) -> (Self, Ordering) {
610 self.positive_difference_prec_round_ref_ref(other, prec, Nearest)
611 }
612
613 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
614 /// — rounding the result to the maximum of the precisions of the inputs, with the specified
615 /// rounding mode. Both [`Float`]s are taken by value. An [`Ordering`] is also returned,
616 /// indicating whether the rounded result is less than, equal to, or greater than the exact
617 /// positive difference. Although `NaN`s are not comparable to any [`Float`], whenever this
618 /// function returns a `NaN` it also returns `Equal`.
619 ///
620 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
621 /// as a matter of definition — negative values are representable, but the function chooses
622 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
623 /// both signs as equal and infinities as their usual extremes.
624 ///
625 /// Special cases:
626 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
627 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
628 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
629 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
630 ///
631 /// Overflow and underflow are as for subtraction:
632 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
633 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
634 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
635 ///
636 /// $$
637 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
638 /// $$
639 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
640 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
641 ///
642 /// If you want to specify an output precision, consider using
643 /// [`Float::positive_difference_prec_round`] instead. If you know you'll be using the `Nearest`
644 /// rounding mode, consider using [`Float::positive_difference`] instead.
645 ///
646 /// # Worst-case complexity
647 /// $T(n) = O(n)$
648 ///
649 /// $M(n) = O(n)$
650 ///
651 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
652 /// other.significant_bits())`.
653 ///
654 /// # Panics
655 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
656 /// output precision.
657 ///
658 /// # Examples
659 /// ```
660 /// use core::cmp::Ordering::*;
661 /// use malachite_base::num::basic::traits::One;
662 /// use malachite_base::rounding_modes::RoundingMode::*;
663 /// use malachite_float::Float;
664 ///
665 /// let (d, o) = Float::from(3u32).positive_difference_round(Float::ONE, Floor);
666 /// assert_eq!(d.to_string(), "2.0");
667 /// assert_eq!(o, Equal);
668 /// ```
669 pub fn positive_difference_round(self, other: Self, rm: RoundingMode) -> (Self, Ordering) {
670 let prec = max(self.significant_bits(), other.significant_bits());
671 self.positive_difference_prec_round(other, prec, rm)
672 }
673
674 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
675 /// — rounding the result to the maximum of the precisions of the inputs, with the specified
676 /// rounding mode. The first [`Float`] is taken by value and the second by reference. An
677 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
678 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
679 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
680 ///
681 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
682 /// as a matter of definition — negative values are representable, but the function chooses
683 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
684 /// both signs as equal and infinities as their usual extremes.
685 ///
686 /// Special cases:
687 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
688 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
689 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
690 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
691 ///
692 /// Overflow and underflow are as for subtraction:
693 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
694 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
695 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
696 ///
697 /// $$
698 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
699 /// $$
700 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
701 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
702 ///
703 /// If you want to specify an output precision, consider using
704 /// [`Float::positive_difference_prec_round`] instead. If you know you'll be using the `Nearest`
705 /// rounding mode, consider using [`Float::positive_difference`] instead.
706 ///
707 /// # Worst-case complexity
708 /// $T(n) = O(n)$
709 ///
710 /// $M(n) = O(n)$
711 ///
712 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
713 /// other.significant_bits())`.
714 ///
715 /// # Panics
716 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
717 /// output precision.
718 ///
719 /// # Examples
720 /// ```
721 /// use core::cmp::Ordering::*;
722 /// use malachite_base::num::basic::traits::One;
723 /// use malachite_base::rounding_modes::RoundingMode::*;
724 /// use malachite_float::Float;
725 ///
726 /// let (d, o) = Float::from(3u32).positive_difference_round_val_ref(&Float::ONE, Floor);
727 /// assert_eq!(d.to_string(), "2.0");
728 /// assert_eq!(o, Equal);
729 /// ```
730 pub fn positive_difference_round_val_ref(
731 self,
732 other: &Self,
733 rm: RoundingMode,
734 ) -> (Self, Ordering) {
735 let prec = max(self.significant_bits(), other.significant_bits());
736 self.positive_difference_prec_round_val_ref(other, prec, rm)
737 }
738
739 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
740 /// — rounding the result to the maximum of the precisions of the inputs, with the specified
741 /// rounding mode. The first [`Float`] is taken by reference and the second by value. An
742 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
743 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
744 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
745 ///
746 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
747 /// as a matter of definition — negative values are representable, but the function chooses
748 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
749 /// both signs as equal and infinities as their usual extremes.
750 ///
751 /// Special cases:
752 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
753 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
754 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
755 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
756 ///
757 /// Overflow and underflow are as for subtraction:
758 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
759 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
760 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
761 ///
762 /// $$
763 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
764 /// $$
765 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
766 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
767 ///
768 /// If you want to specify an output precision, consider using
769 /// [`Float::positive_difference_prec_round`] instead. If you know you'll be using the `Nearest`
770 /// rounding mode, consider using [`Float::positive_difference`] instead.
771 ///
772 /// # Worst-case complexity
773 /// $T(n) = O(n)$
774 ///
775 /// $M(n) = O(n)$
776 ///
777 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
778 /// other.significant_bits())`.
779 ///
780 /// # Panics
781 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
782 /// output precision.
783 ///
784 /// # Examples
785 /// ```
786 /// use core::cmp::Ordering::*;
787 /// use malachite_base::num::basic::traits::One;
788 /// use malachite_base::rounding_modes::RoundingMode::*;
789 /// use malachite_float::Float;
790 ///
791 /// let (d, o) = Float::from(3u32).positive_difference_round_ref_val(Float::ONE, Floor);
792 /// assert_eq!(d.to_string(), "2.0");
793 /// assert_eq!(o, Equal);
794 /// ```
795 pub fn positive_difference_round_ref_val(
796 &self,
797 other: Self,
798 rm: RoundingMode,
799 ) -> (Self, Ordering) {
800 let prec = max(self.significant_bits(), other.significant_bits());
801 self.positive_difference_prec_round_ref_val(other, prec, rm)
802 }
803
804 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
805 /// — rounding the result to the maximum of the precisions of the inputs, with the specified
806 /// rounding mode. Both [`Float`]s are taken by reference. An [`Ordering`] is also returned,
807 /// indicating whether the rounded result is less than, equal to, or greater than the exact
808 /// positive difference. Although `NaN`s are not comparable to any [`Float`], whenever this
809 /// function returns a `NaN` it also returns `Equal`.
810 ///
811 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
812 /// as a matter of definition — negative values are representable, but the function chooses
813 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
814 /// both signs as equal and infinities as their usual extremes.
815 ///
816 /// Special cases:
817 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
818 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
819 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
820 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
821 ///
822 /// Overflow and underflow are as for subtraction:
823 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
824 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
825 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
826 ///
827 /// $$
828 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
829 /// $$
830 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
831 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
832 ///
833 /// If you want to specify an output precision, consider using
834 /// [`Float::positive_difference_prec_round`] instead. If you know you'll be using the `Nearest`
835 /// rounding mode, consider using [`Float::positive_difference`] instead.
836 ///
837 /// # Worst-case complexity
838 /// $T(n) = O(n)$
839 ///
840 /// $M(n) = O(n)$
841 ///
842 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
843 /// other.significant_bits())`.
844 ///
845 /// # Panics
846 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
847 /// output precision.
848 ///
849 /// # Examples
850 /// ```
851 /// use core::cmp::Ordering::*;
852 /// use malachite_base::num::basic::traits::One;
853 /// use malachite_base::rounding_modes::RoundingMode::*;
854 /// use malachite_float::Float;
855 ///
856 /// let (d, o) = Float::from(3u32).positive_difference_round_ref_ref(&Float::ONE, Floor);
857 /// assert_eq!(d.to_string(), "2.0");
858 /// assert_eq!(o, Equal);
859 /// ```
860 pub fn positive_difference_round_ref_ref(
861 &self,
862 other: &Self,
863 rm: RoundingMode,
864 ) -> (Self, Ordering) {
865 let prec = max(self.significant_bits(), other.significant_bits());
866 self.positive_difference_prec_round_ref_ref(other, prec, rm)
867 }
868
869 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
870 /// — rounding the result to the nearest value of the maximum of the precisions of the inputs.
871 /// Both [`Float`]s are taken by value. An [`Ordering`] is also returned, indicating whether the
872 /// rounded result is less than, equal to, or greater than the exact positive difference.
873 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
874 /// it also returns `Equal`.
875 ///
876 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
877 /// as a matter of definition — negative values are representable, but the function chooses
878 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
879 /// both signs as equal and infinities as their usual extremes.
880 ///
881 /// Special cases:
882 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
883 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
884 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
885 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
886 ///
887 /// Overflow and underflow are as for subtraction:
888 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
889 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
890 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
891 ///
892 /// $$
893 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
894 /// $$
895 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
896 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
897 ///
898 /// If you want to specify an output precision, consider using
899 /// [`Float::positive_difference_prec`] instead. If you want to use a rounding mode other than
900 /// `Nearest`, consider using [`Float::positive_difference_round`] instead.
901 ///
902 /// # Worst-case complexity
903 /// $T(n) = O(n)$
904 ///
905 /// $M(n) = O(n)$
906 ///
907 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
908 /// other.significant_bits())`.
909 ///
910 /// # Examples
911 /// ```
912 /// use core::cmp::Ordering::*;
913 /// use malachite_base::num::basic::traits::One;
914 /// use malachite_float::Float;
915 ///
916 /// let (d, o) = Float::from(3u32).positive_difference(Float::ONE);
917 /// assert_eq!(d.to_string(), "2.0");
918 /// assert_eq!(o, Equal);
919 ///
920 /// let (d, o) = Float::from(3u32).positive_difference(Float::from(5u32));
921 /// assert_eq!(d.to_string(), "0.0");
922 /// assert_eq!(o, Equal);
923 /// ```
924 #[inline]
925 pub fn positive_difference(self, other: Self) -> (Self, Ordering) {
926 self.positive_difference_round(other, Nearest)
927 }
928
929 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
930 /// — rounding the result to the nearest value of the maximum of the precisions of the inputs.
931 /// The first [`Float`] is taken by value and the second by reference. An [`Ordering`] is also
932 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
933 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
934 /// this function returns a `NaN` it also returns `Equal`.
935 ///
936 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
937 /// as a matter of definition — negative values are representable, but the function chooses
938 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
939 /// both signs as equal and infinities as their usual extremes.
940 ///
941 /// Special cases:
942 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
943 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
944 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
945 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
946 ///
947 /// Overflow and underflow are as for subtraction:
948 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
949 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
950 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
951 ///
952 /// $$
953 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
954 /// $$
955 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
956 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
957 ///
958 /// If you want to specify an output precision, consider using
959 /// [`Float::positive_difference_prec`] instead. If you want to use a rounding mode other than
960 /// `Nearest`, consider using [`Float::positive_difference_round`] instead.
961 ///
962 /// # Worst-case complexity
963 /// $T(n) = O(n)$
964 ///
965 /// $M(n) = O(n)$
966 ///
967 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
968 /// other.significant_bits())`.
969 ///
970 /// # Examples
971 /// ```
972 /// use core::cmp::Ordering::*;
973 /// use malachite_base::num::basic::traits::One;
974 /// use malachite_float::Float;
975 ///
976 /// let (d, o) = Float::from(3u32).positive_difference_val_ref(&Float::ONE);
977 /// assert_eq!(d.to_string(), "2.0");
978 /// assert_eq!(o, Equal);
979 ///
980 /// let (d, o) = Float::from(3u32).positive_difference_val_ref(&Float::from(5u32));
981 /// assert_eq!(d.to_string(), "0.0");
982 /// assert_eq!(o, Equal);
983 /// ```
984 #[inline]
985 pub fn positive_difference_val_ref(self, other: &Self) -> (Self, Ordering) {
986 self.positive_difference_round_val_ref(other, Nearest)
987 }
988
989 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
990 /// — rounding the result to the nearest value of the maximum of the precisions of the inputs.
991 /// The first [`Float`] is taken by reference and the second by value. An [`Ordering`] is also
992 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
993 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
994 /// this function returns a `NaN` it also returns `Equal`.
995 ///
996 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
997 /// as a matter of definition — negative values are representable, but the function chooses
998 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
999 /// both signs as equal and infinities as their usual extremes.
1000 ///
1001 /// Special cases:
1002 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
1003 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
1004 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
1005 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
1006 ///
1007 /// Overflow and underflow are as for subtraction:
1008 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1009 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1010 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1011 ///
1012 /// $$
1013 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1014 /// $$
1015 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1016 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
1017 ///
1018 /// If you want to specify an output precision, consider using
1019 /// [`Float::positive_difference_prec`] instead. If you want to use a rounding mode other than
1020 /// `Nearest`, consider using [`Float::positive_difference_round`] instead.
1021 ///
1022 /// # Worst-case complexity
1023 /// $T(n) = O(n)$
1024 ///
1025 /// $M(n) = O(n)$
1026 ///
1027 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
1028 /// other.significant_bits())`.
1029 ///
1030 /// # Examples
1031 /// ```
1032 /// use core::cmp::Ordering::*;
1033 /// use malachite_base::num::basic::traits::One;
1034 /// use malachite_float::Float;
1035 ///
1036 /// let (d, o) = Float::from(3u32).positive_difference_ref_val(Float::ONE);
1037 /// assert_eq!(d.to_string(), "2.0");
1038 /// assert_eq!(o, Equal);
1039 ///
1040 /// let (d, o) = Float::from(3u32).positive_difference_ref_val(Float::from(5u32));
1041 /// assert_eq!(d.to_string(), "0.0");
1042 /// assert_eq!(o, Equal);
1043 /// ```
1044 #[inline]
1045 pub fn positive_difference_ref_val(&self, other: Self) -> (Self, Ordering) {
1046 self.positive_difference_round_ref_val(other, Nearest)
1047 }
1048
1049 /// Computes the positive difference of two [`Float`]s — $x-y$ if $x>y$, and $+0.0$ otherwise
1050 /// — rounding the result to the nearest value of the maximum of the precisions of the inputs.
1051 /// Both [`Float`]s are taken by reference. An [`Ordering`] is also returned, indicating whether
1052 /// the rounded result is less than, equal to, or greater than the exact positive difference.
1053 /// Although `NaN`s are not comparable to any [`Float`], whenever this function returns a `NaN`
1054 /// it also returns `Equal`.
1055 ///
1056 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
1057 /// as a matter of definition — negative values are representable, but the function chooses
1058 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
1059 /// both signs as equal and infinities as their usual extremes.
1060 ///
1061 /// Special cases:
1062 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
1063 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
1064 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
1065 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
1066 ///
1067 /// Overflow and underflow are as for subtraction:
1068 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1069 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1070 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1071 ///
1072 /// $$
1073 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1074 /// $$
1075 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1076 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
1077 ///
1078 /// If you want to specify an output precision, consider using
1079 /// [`Float::positive_difference_prec`] instead. If you want to use a rounding mode other than
1080 /// `Nearest`, consider using [`Float::positive_difference_round`] instead.
1081 ///
1082 /// # Worst-case complexity
1083 /// $T(n) = O(n)$
1084 ///
1085 /// $M(n) = O(n)$
1086 ///
1087 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
1088 /// other.significant_bits())`.
1089 ///
1090 /// # Examples
1091 /// ```
1092 /// use core::cmp::Ordering::*;
1093 /// use malachite_base::num::basic::traits::One;
1094 /// use malachite_float::Float;
1095 ///
1096 /// let (d, o) = Float::from(3u32).positive_difference_ref_ref(&Float::ONE);
1097 /// assert_eq!(d.to_string(), "2.0");
1098 /// assert_eq!(o, Equal);
1099 ///
1100 /// let (d, o) = Float::from(3u32).positive_difference_ref_ref(&Float::from(5u32));
1101 /// assert_eq!(d.to_string(), "0.0");
1102 /// assert_eq!(o, Equal);
1103 /// ```
1104 #[inline]
1105 pub fn positive_difference_ref_ref(&self, other: &Self) -> (Self, Ordering) {
1106 self.positive_difference_round_ref_ref(other, Nearest)
1107 }
1108
1109 /// Computes the positive difference of two [`Float`]s in place — $x-y$ if $x>y$, and $+0.0$
1110 /// otherwise — rounding the result to the specified precision and with the specified rounding
1111 /// mode. The [`Float`] on the right-hand side is taken by value. An [`Ordering`] is also
1112 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
1113 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
1114 /// this function returns a `NaN` it also returns `Equal`.
1115 ///
1116 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
1117 /// as a matter of definition — negative values are representable, but the function chooses
1118 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
1119 /// both signs as equal and infinities as their usual extremes.
1120 ///
1121 /// Special cases:
1122 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
1123 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
1124 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
1125 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
1126 ///
1127 /// Overflow and underflow are as for subtraction:
1128 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1129 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1130 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1131 ///
1132 /// $$
1133 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1134 /// $$
1135 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1136 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
1137 ///
1138 /// # Worst-case complexity
1139 /// $T(n) = O(n)$
1140 ///
1141 /// $M(n) = O(n)$
1142 ///
1143 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
1144 /// other.significant_bits(), prec)`.
1145 ///
1146 /// # Panics
1147 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
1148 /// representable with `prec` bits.
1149 ///
1150 /// # Examples
1151 /// ```
1152 /// use core::cmp::Ordering::*;
1153 /// use malachite_base::num::basic::traits::One;
1154 /// use malachite_base::rounding_modes::RoundingMode::*;
1155 /// use malachite_float::Float;
1156 ///
1157 /// let mut x = Float::from(3u32);
1158 /// assert_eq!(
1159 /// x.positive_difference_prec_round_assign(Float::ONE, 10, Floor),
1160 /// Equal
1161 /// );
1162 /// assert_eq!(x.to_string(), "2.0000");
1163 /// ```
1164 pub fn positive_difference_prec_round_assign(
1165 &mut self,
1166 other: Self,
1167 prec: u64,
1168 rm: RoundingMode,
1169 ) -> Ordering {
1170 assert_ne!(prec, 0);
1171 if matches!((*self).partial_cmp(&other), Some(Greater)) {
1172 self.sub_prec_round_assign(other, prec, rm)
1173 } else if matches!(self, Self(NaN)) || matches!(other, Self(NaN)) {
1174 *self = float_nan!();
1175 Equal
1176 } else {
1177 *self = Self::ZERO;
1178 Equal
1179 }
1180 }
1181
1182 /// Computes the positive difference of two [`Float`]s in place — $x-y$ if $x>y$, and $+0.0$
1183 /// otherwise — rounding the result to the specified precision and with the specified rounding
1184 /// mode. The [`Float`] on the right-hand side is taken by reference. An [`Ordering`] is also
1185 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
1186 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
1187 /// this function returns a `NaN` it also returns `Equal`.
1188 ///
1189 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
1190 /// as a matter of definition — negative values are representable, but the function chooses
1191 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
1192 /// both signs as equal and infinities as their usual extremes.
1193 ///
1194 /// Special cases:
1195 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
1196 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
1197 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
1198 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
1199 ///
1200 /// Overflow and underflow are as for subtraction:
1201 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1202 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1203 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1204 ///
1205 /// $$
1206 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1207 /// $$
1208 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1209 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
1210 ///
1211 /// # Worst-case complexity
1212 /// $T(n) = O(n)$
1213 ///
1214 /// $M(n) = O(n)$
1215 ///
1216 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
1217 /// other.significant_bits(), prec)`.
1218 ///
1219 /// # Panics
1220 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
1221 /// representable with `prec` bits.
1222 ///
1223 /// # Examples
1224 /// ```
1225 /// use core::cmp::Ordering::*;
1226 /// use malachite_base::num::basic::traits::One;
1227 /// use malachite_base::rounding_modes::RoundingMode::*;
1228 /// use malachite_float::Float;
1229 ///
1230 /// let mut x = Float::from(3u32);
1231 /// let y = Float::ONE;
1232 /// assert_eq!(
1233 /// x.positive_difference_prec_round_assign_ref(&y, 10, Floor),
1234 /// Equal
1235 /// );
1236 /// assert_eq!(x.to_string(), "2.0000");
1237 /// ```
1238 pub fn positive_difference_prec_round_assign_ref(
1239 &mut self,
1240 other: &Self,
1241 prec: u64,
1242 rm: RoundingMode,
1243 ) -> Ordering {
1244 assert_ne!(prec, 0);
1245 if matches!((*self).partial_cmp(other), Some(Greater)) {
1246 self.sub_prec_round_assign_ref(other, prec, rm)
1247 } else if matches!(self, Self(NaN)) || matches!(other, Self(NaN)) {
1248 *self = float_nan!();
1249 Equal
1250 } else {
1251 *self = Self::ZERO;
1252 Equal
1253 }
1254 }
1255
1256 /// Computes the positive difference of two [`Float`]s in place — $x-y$ if $x>y$, and $+0.0$
1257 /// otherwise — rounding the result to the nearest value of the specified precision. The
1258 /// [`Float`] on the right-hand side is taken by value. An [`Ordering`] is also returned,
1259 /// indicating whether the rounded result is less than, equal to, or greater than the exact
1260 /// positive difference. Although `NaN`s are not comparable to any [`Float`], whenever this
1261 /// function returns a `NaN` it also returns `Equal`.
1262 ///
1263 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
1264 /// as a matter of definition — negative values are representable, but the function chooses
1265 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
1266 /// both signs as equal and infinities as their usual extremes.
1267 ///
1268 /// Special cases:
1269 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
1270 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
1271 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
1272 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
1273 ///
1274 /// Overflow and underflow are as for subtraction:
1275 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1276 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1277 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1278 ///
1279 /// $$
1280 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1281 /// $$
1282 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1283 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
1284 ///
1285 /// # Worst-case complexity
1286 /// $T(n) = O(n)$
1287 ///
1288 /// $M(n) = O(n)$
1289 ///
1290 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
1291 /// other.significant_bits(), prec)`.
1292 ///
1293 /// # Panics
1294 /// Panics if `prec` is zero.
1295 ///
1296 /// # Examples
1297 /// ```
1298 /// use core::cmp::Ordering::*;
1299 /// use malachite_base::num::basic::traits::One;
1300 /// use malachite_float::Float;
1301 ///
1302 /// let mut x = Float::from(3u32);
1303 /// assert_eq!(x.positive_difference_prec_assign(Float::ONE, 10), Equal);
1304 /// assert_eq!(x.to_string(), "2.0000");
1305 /// ```
1306 #[inline]
1307 pub fn positive_difference_prec_assign(&mut self, other: Self, prec: u64) -> Ordering {
1308 self.positive_difference_prec_round_assign(other, prec, Nearest)
1309 }
1310
1311 /// Computes the positive difference of two [`Float`]s in place — $x-y$ if $x>y$, and $+0.0$
1312 /// otherwise — rounding the result to the nearest value of the specified precision. The
1313 /// [`Float`] on the right-hand side is taken by reference. An [`Ordering`] is also returned,
1314 /// indicating whether the rounded result is less than, equal to, or greater than the exact
1315 /// positive difference. Although `NaN`s are not comparable to any [`Float`], whenever this
1316 /// function returns a `NaN` it also returns `Equal`.
1317 ///
1318 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
1319 /// as a matter of definition — negative values are representable, but the function chooses
1320 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
1321 /// both signs as equal and infinities as their usual extremes.
1322 ///
1323 /// Special cases:
1324 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
1325 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
1326 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
1327 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
1328 ///
1329 /// Overflow and underflow are as for subtraction:
1330 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1331 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1332 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1333 ///
1334 /// $$
1335 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1336 /// $$
1337 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1338 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
1339 ///
1340 /// # Worst-case complexity
1341 /// $T(n) = O(n)$
1342 ///
1343 /// $M(n) = O(n)$
1344 ///
1345 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
1346 /// other.significant_bits(), prec)`.
1347 ///
1348 /// # Panics
1349 /// Panics if `prec` is zero.
1350 ///
1351 /// # Examples
1352 /// ```
1353 /// use core::cmp::Ordering::*;
1354 /// use malachite_base::num::basic::traits::One;
1355 /// use malachite_float::Float;
1356 ///
1357 /// let mut x = Float::from(3u32);
1358 /// assert_eq!(
1359 /// x.positive_difference_prec_assign_ref(&Float::ONE, 10),
1360 /// Equal
1361 /// );
1362 /// assert_eq!(x.to_string(), "2.0000");
1363 /// ```
1364 #[inline]
1365 pub fn positive_difference_prec_assign_ref(&mut self, other: &Self, prec: u64) -> Ordering {
1366 self.positive_difference_prec_round_assign_ref(other, prec, Nearest)
1367 }
1368
1369 /// Computes the positive difference of two [`Float`]s in place — $x-y$ if $x>y$, and $+0.0$
1370 /// otherwise — rounding the result to the maximum of the precisions of the inputs, with the
1371 /// specified rounding mode. The [`Float`] on the right-hand side is taken by value. An
1372 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
1373 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
1374 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1375 ///
1376 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
1377 /// as a matter of definition — negative values are representable, but the function chooses
1378 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
1379 /// both signs as equal and infinities as their usual extremes.
1380 ///
1381 /// Special cases:
1382 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
1383 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
1384 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
1385 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
1386 ///
1387 /// Overflow and underflow are as for subtraction:
1388 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1389 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1390 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1391 ///
1392 /// $$
1393 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1394 /// $$
1395 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1396 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
1397 ///
1398 /// # Worst-case complexity
1399 /// $T(n) = O(n)$
1400 ///
1401 /// $M(n) = O(n)$
1402 ///
1403 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
1404 /// other.significant_bits())`.
1405 ///
1406 /// # Panics
1407 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
1408 /// output precision.
1409 ///
1410 /// # Examples
1411 /// ```
1412 /// use core::cmp::Ordering::*;
1413 /// use malachite_base::num::basic::traits::One;
1414 /// use malachite_base::rounding_modes::RoundingMode::*;
1415 /// use malachite_float::Float;
1416 ///
1417 /// let mut x = Float::from(3u32);
1418 /// assert_eq!(x.positive_difference_round_assign(Float::ONE, Floor), Equal);
1419 /// assert_eq!(x.to_string(), "2.0");
1420 /// ```
1421 pub fn positive_difference_round_assign(&mut self, other: Self, rm: RoundingMode) -> Ordering {
1422 let prec = max(self.significant_bits(), other.significant_bits());
1423 self.positive_difference_prec_round_assign(other, prec, rm)
1424 }
1425
1426 /// Computes the positive difference of two [`Float`]s in place — $x-y$ if $x>y$, and $+0.0$
1427 /// otherwise — rounding the result to the maximum of the precisions of the inputs, with the
1428 /// specified rounding mode. The [`Float`] on the right-hand side is taken by reference. An
1429 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
1430 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
1431 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1432 ///
1433 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
1434 /// as a matter of definition — negative values are representable, but the function chooses
1435 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
1436 /// both signs as equal and infinities as their usual extremes.
1437 ///
1438 /// Special cases:
1439 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
1440 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
1441 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
1442 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
1443 ///
1444 /// Overflow and underflow are as for subtraction:
1445 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1446 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1447 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1448 ///
1449 /// $$
1450 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1451 /// $$
1452 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1453 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
1454 ///
1455 /// # Worst-case complexity
1456 /// $T(n) = O(n)$
1457 ///
1458 /// $M(n) = O(n)$
1459 ///
1460 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
1461 /// other.significant_bits())`.
1462 ///
1463 /// # Panics
1464 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
1465 /// output precision.
1466 ///
1467 /// # Examples
1468 /// ```
1469 /// use core::cmp::Ordering::*;
1470 /// use malachite_base::num::basic::traits::One;
1471 /// use malachite_base::rounding_modes::RoundingMode::*;
1472 /// use malachite_float::Float;
1473 ///
1474 /// let mut x = Float::from(3u32);
1475 /// assert_eq!(
1476 /// x.positive_difference_round_assign_ref(&Float::ONE, Floor),
1477 /// Equal
1478 /// );
1479 /// assert_eq!(x.to_string(), "2.0");
1480 /// ```
1481 pub fn positive_difference_round_assign_ref(
1482 &mut self,
1483 other: &Self,
1484 rm: RoundingMode,
1485 ) -> Ordering {
1486 let prec = max(self.significant_bits(), other.significant_bits());
1487 self.positive_difference_prec_round_assign_ref(other, prec, rm)
1488 }
1489
1490 /// Computes the positive difference of two [`Float`]s in place — $x-y$ if $x>y$, and $+0.0$
1491 /// otherwise — rounding the result to the nearest value of the maximum of the precisions of
1492 /// the inputs. The [`Float`] on the right-hand side is taken by value. An [`Ordering`] is also
1493 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
1494 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
1495 /// this function returns a `NaN` it also returns `Equal`.
1496 ///
1497 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
1498 /// as a matter of definition — negative values are representable, but the function chooses
1499 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
1500 /// both signs as equal and infinities as their usual extremes.
1501 ///
1502 /// Special cases:
1503 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
1504 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
1505 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
1506 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
1507 ///
1508 /// Overflow and underflow are as for subtraction:
1509 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1510 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1511 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1512 ///
1513 /// $$
1514 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1515 /// $$
1516 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1517 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
1518 ///
1519 /// # Worst-case complexity
1520 /// $T(n) = O(n)$
1521 ///
1522 /// $M(n) = O(n)$
1523 ///
1524 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
1525 /// other.significant_bits())`.
1526 ///
1527 /// # Examples
1528 /// ```
1529 /// use core::cmp::Ordering::*;
1530 /// use malachite_base::num::basic::traits::One;
1531 /// use malachite_float::Float;
1532 ///
1533 /// let mut x = Float::from(3u32);
1534 /// assert_eq!(x.positive_difference_assign(Float::ONE), Equal);
1535 /// assert_eq!(x.to_string(), "2.0");
1536 /// ```
1537 #[inline]
1538 pub fn positive_difference_assign(&mut self, other: Self) -> Ordering {
1539 self.positive_difference_round_assign(other, Nearest)
1540 }
1541
1542 /// Computes the positive difference of two [`Float`]s in place — $x-y$ if $x>y$, and $+0.0$
1543 /// otherwise — rounding the result to the nearest value of the maximum of the precisions of
1544 /// the inputs. The [`Float`] on the right-hand side is taken by reference. An [`Ordering`] is
1545 /// also returned, indicating whether the rounded result is less than, equal to, or greater than
1546 /// the exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
1547 /// this function returns a `NaN` it also returns `Equal`.
1548 ///
1549 /// This is the positive difference, `mpfr_dim` and C's `fdim`. Zero is returned for $x\leq y$
1550 /// as a matter of definition — negative values are representable, but the function chooses
1551 /// $+0.0$ instead — so this is not a saturating subtraction. The comparison treats zeros of
1552 /// both signs as equal and infinities as their usual extremes.
1553 ///
1554 /// Special cases:
1555 /// - $f(\text{NaN},y,p)=f(x,\text{NaN},p)=\text{NaN}$
1556 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including $f(\pm0.0,\pm0.0,p)$ and $f(\infty,\infty,p)$
1557 /// - $f(\infty,y,p)=\infty$ if $y$ is not `NaN` and $y\neq\infty$
1558 /// - $f(x,-\infty,p)=\infty$ if $x$ is not `NaN` and $x\neq-\infty$
1559 ///
1560 /// Overflow and underflow are as for subtraction:
1561 /// - If $f(x,y,p)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
1562 /// - If $0<f(x,y,p)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
1563 /// - If $2^{-2^{30}-1}<f(x,y,p)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
1564 ///
1565 /// $$
1566 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1567 /// $$
1568 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1569 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
1570 ///
1571 /// # Worst-case complexity
1572 /// $T(n) = O(n)$
1573 ///
1574 /// $M(n) = O(n)$
1575 ///
1576 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
1577 /// other.significant_bits())`.
1578 ///
1579 /// # Examples
1580 /// ```
1581 /// use core::cmp::Ordering::*;
1582 /// use malachite_base::num::basic::traits::One;
1583 /// use malachite_float::Float;
1584 ///
1585 /// let mut x = Float::from(3u32);
1586 /// assert_eq!(x.positive_difference_assign_ref(&Float::ONE), Equal);
1587 /// assert_eq!(x.to_string(), "2.0");
1588 /// ```
1589 #[inline]
1590 pub fn positive_difference_assign_ref(&mut self, other: &Self) -> Ordering {
1591 self.positive_difference_round_assign_ref(other, Nearest)
1592 }
1593 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
1594 /// $+0.0$ otherwise — rounding the result to the specified precision and with the specified
1595 /// rounding mode. The [`Float`] and the [`Rational`] are both taken by value. An [`Ordering`]
1596 /// is also returned, indicating whether the rounded result is less than, equal to, or greater
1597 /// than the exact positive difference. Although `NaN`s are not comparable to any [`Float`],
1598 /// whenever this function returns a `NaN` it also returns `Equal`.
1599 ///
1600 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
1601 /// before use, so the correct branch is always chosen and the winning difference is correctly
1602 /// rounded.
1603 ///
1604 /// Special cases:
1605 /// - $f(\text{NaN},y,p)=\text{NaN}$
1606 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
1607 /// [`Rational`]
1608 /// - $f(\infty,y,p)=\infty$
1609 ///
1610 /// $$
1611 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1612 /// $$
1613 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1614 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
1615 ///
1616 /// If you know you'll be using `Nearest`, consider using
1617 /// [`Float::positive_difference_rational_prec`] instead. If you know that your target precision
1618 /// is the [`Float`]'s, consider using [`Float::positive_difference_rational_round`] instead. If
1619 /// both of these things are true, consider using [`Float::positive_difference_rational`]
1620 /// instead.
1621 ///
1622 /// # Worst-case complexity
1623 /// $T(n) = O(n \log n \log\log n)$
1624 ///
1625 /// $M(n) = O(n)$
1626 ///
1627 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
1628 /// other.significant_bits(), prec)`.
1629 ///
1630 /// # Panics
1631 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
1632 /// representable with `prec` bits.
1633 ///
1634 /// # Examples
1635 /// ```
1636 /// use core::cmp::Ordering::*;
1637 /// use malachite_base::rounding_modes::RoundingMode::*;
1638 /// use malachite_float::Float;
1639 /// use malachite_q::Rational;
1640 ///
1641 /// let (d, o) = Float::from(3u32).positive_difference_rational_prec_round(
1642 /// Rational::from_signeds(1, 3),
1643 /// 10,
1644 /// Floor,
1645 /// );
1646 /// assert_eq!(d.to_string(), "2.6641");
1647 /// assert_eq!(o, Less);
1648 ///
1649 /// let (d, o) = Float::from(3u32).positive_difference_rational_prec_round(
1650 /// Rational::from_signeds(1, 3),
1651 /// 10,
1652 /// Ceiling,
1653 /// );
1654 /// assert_eq!(d.to_string(), "2.6680");
1655 /// assert_eq!(o, Greater);
1656 /// ```
1657 #[allow(clippy::needless_pass_by_value)]
1658 pub fn positive_difference_rational_prec_round(
1659 self,
1660 other: Rational,
1661 prec: u64,
1662 rm: RoundingMode,
1663 ) -> (Self, Ordering) {
1664 assert_ne!(prec, 0);
1665 if matches!(self.partial_cmp(&other), Some(Greater)) {
1666 self.sub_rational_prec_round(other, prec, rm)
1667 } else if matches!(self, Self(NaN)) {
1668 (float_nan!(), Equal)
1669 } else {
1670 (Self::ZERO, Equal)
1671 }
1672 }
1673
1674 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
1675 /// $+0.0$ otherwise — rounding the result to the specified precision and with the specified
1676 /// rounding mode. The [`Float`] is taken by value and the [`Rational`] by reference. An
1677 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
1678 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
1679 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1680 ///
1681 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
1682 /// before use, so the correct branch is always chosen and the winning difference is correctly
1683 /// rounded.
1684 ///
1685 /// Special cases:
1686 /// - $f(\text{NaN},y,p)=\text{NaN}$
1687 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
1688 /// [`Rational`]
1689 /// - $f(\infty,y,p)=\infty$
1690 ///
1691 /// $$
1692 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1693 /// $$
1694 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1695 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
1696 ///
1697 /// If you know you'll be using `Nearest`, consider using
1698 /// [`Float::positive_difference_rational_prec`] instead. If you know that your target precision
1699 /// is the [`Float`]'s, consider using [`Float::positive_difference_rational_round`] instead. If
1700 /// both of these things are true, consider using [`Float::positive_difference_rational`]
1701 /// instead.
1702 ///
1703 /// # Worst-case complexity
1704 /// $T(n) = O(n \log n \log\log n)$
1705 ///
1706 /// $M(n) = O(n)$
1707 ///
1708 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
1709 /// other.significant_bits(), prec)`.
1710 ///
1711 /// # Panics
1712 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
1713 /// representable with `prec` bits.
1714 ///
1715 /// # Examples
1716 /// ```
1717 /// use core::cmp::Ordering::*;
1718 /// use malachite_base::rounding_modes::RoundingMode::*;
1719 /// use malachite_float::Float;
1720 /// use malachite_q::Rational;
1721 ///
1722 /// let (d, o) = Float::from(3u32).positive_difference_rational_prec_round_val_ref(
1723 /// &Rational::from_signeds(1, 3),
1724 /// 10,
1725 /// Floor,
1726 /// );
1727 /// assert_eq!(d.to_string(), "2.6641");
1728 /// assert_eq!(o, Less);
1729 ///
1730 /// let (d, o) = Float::from(3u32).positive_difference_rational_prec_round_val_ref(
1731 /// &Rational::from_signeds(1, 3),
1732 /// 10,
1733 /// Ceiling,
1734 /// );
1735 /// assert_eq!(d.to_string(), "2.6680");
1736 /// assert_eq!(o, Greater);
1737 /// ```
1738 pub fn positive_difference_rational_prec_round_val_ref(
1739 self,
1740 other: &Rational,
1741 prec: u64,
1742 rm: RoundingMode,
1743 ) -> (Self, Ordering) {
1744 assert_ne!(prec, 0);
1745 if matches!(self.partial_cmp(other), Some(Greater)) {
1746 self.sub_rational_prec_round_val_ref(other, prec, rm)
1747 } else if matches!(self, Self(NaN)) {
1748 (float_nan!(), Equal)
1749 } else {
1750 (Self::ZERO, Equal)
1751 }
1752 }
1753
1754 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
1755 /// $+0.0$ otherwise — rounding the result to the specified precision and with the specified
1756 /// rounding mode. The [`Float`] is taken by reference and the [`Rational`] by value. An
1757 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
1758 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
1759 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1760 ///
1761 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
1762 /// before use, so the correct branch is always chosen and the winning difference is correctly
1763 /// rounded.
1764 ///
1765 /// Special cases:
1766 /// - $f(\text{NaN},y,p)=\text{NaN}$
1767 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
1768 /// [`Rational`]
1769 /// - $f(\infty,y,p)=\infty$
1770 ///
1771 /// $$
1772 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1773 /// $$
1774 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1775 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
1776 ///
1777 /// If you know you'll be using `Nearest`, consider using
1778 /// [`Float::positive_difference_rational_prec`] instead. If you know that your target precision
1779 /// is the [`Float`]'s, consider using [`Float::positive_difference_rational_round`] instead. If
1780 /// both of these things are true, consider using [`Float::positive_difference_rational`]
1781 /// instead.
1782 ///
1783 /// # Worst-case complexity
1784 /// $T(n) = O(n \log n \log\log n)$
1785 ///
1786 /// $M(n) = O(n)$
1787 ///
1788 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
1789 /// other.significant_bits(), prec)`.
1790 ///
1791 /// # Panics
1792 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
1793 /// representable with `prec` bits.
1794 ///
1795 /// # Examples
1796 /// ```
1797 /// use core::cmp::Ordering::*;
1798 /// use malachite_base::rounding_modes::RoundingMode::*;
1799 /// use malachite_float::Float;
1800 /// use malachite_q::Rational;
1801 ///
1802 /// let (d, o) = Float::from(3u32).positive_difference_rational_prec_round_ref_val(
1803 /// Rational::from_signeds(1, 3),
1804 /// 10,
1805 /// Floor,
1806 /// );
1807 /// assert_eq!(d.to_string(), "2.6641");
1808 /// assert_eq!(o, Less);
1809 ///
1810 /// let (d, o) = Float::from(3u32).positive_difference_rational_prec_round_ref_val(
1811 /// Rational::from_signeds(1, 3),
1812 /// 10,
1813 /// Ceiling,
1814 /// );
1815 /// assert_eq!(d.to_string(), "2.6680");
1816 /// assert_eq!(o, Greater);
1817 /// ```
1818 #[allow(clippy::needless_pass_by_value)]
1819 pub fn positive_difference_rational_prec_round_ref_val(
1820 &self,
1821 other: Rational,
1822 prec: u64,
1823 rm: RoundingMode,
1824 ) -> (Self, Ordering) {
1825 assert_ne!(prec, 0);
1826 if matches!((*self).partial_cmp(&other), Some(Greater)) {
1827 self.sub_rational_prec_round_ref_val(other, prec, rm)
1828 } else if matches!(self, Self(NaN)) {
1829 (float_nan!(), Equal)
1830 } else {
1831 (Self::ZERO, Equal)
1832 }
1833 }
1834
1835 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
1836 /// $+0.0$ otherwise — rounding the result to the specified precision and with the specified
1837 /// rounding mode. The [`Float`] and the [`Rational`] are both taken by reference. An
1838 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
1839 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
1840 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
1841 ///
1842 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
1843 /// before use, so the correct branch is always chosen and the winning difference is correctly
1844 /// rounded.
1845 ///
1846 /// Special cases:
1847 /// - $f(\text{NaN},y,p)=\text{NaN}$
1848 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
1849 /// [`Rational`]
1850 /// - $f(\infty,y,p)=\infty$
1851 ///
1852 /// $$
1853 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1854 /// $$
1855 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1856 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
1857 ///
1858 /// If you know you'll be using `Nearest`, consider using
1859 /// [`Float::positive_difference_rational_prec`] instead. If you know that your target precision
1860 /// is the [`Float`]'s, consider using [`Float::positive_difference_rational_round`] instead. If
1861 /// both of these things are true, consider using [`Float::positive_difference_rational`]
1862 /// instead.
1863 ///
1864 /// # Worst-case complexity
1865 /// $T(n) = O(n \log n \log\log n)$
1866 ///
1867 /// $M(n) = O(n)$
1868 ///
1869 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
1870 /// other.significant_bits(), prec)`.
1871 ///
1872 /// # Panics
1873 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
1874 /// representable with `prec` bits.
1875 ///
1876 /// # Examples
1877 /// ```
1878 /// use core::cmp::Ordering::*;
1879 /// use malachite_base::rounding_modes::RoundingMode::*;
1880 /// use malachite_float::Float;
1881 /// use malachite_q::Rational;
1882 ///
1883 /// let (d, o) = Float::from(3u32).positive_difference_rational_prec_round_ref_ref(
1884 /// &Rational::from_signeds(1, 3),
1885 /// 10,
1886 /// Floor,
1887 /// );
1888 /// assert_eq!(d.to_string(), "2.6641");
1889 /// assert_eq!(o, Less);
1890 ///
1891 /// let (d, o) = Float::from(3u32).positive_difference_rational_prec_round_ref_ref(
1892 /// &Rational::from_signeds(1, 3),
1893 /// 10,
1894 /// Ceiling,
1895 /// );
1896 /// assert_eq!(d.to_string(), "2.6680");
1897 /// assert_eq!(o, Greater);
1898 /// ```
1899 pub fn positive_difference_rational_prec_round_ref_ref(
1900 &self,
1901 other: &Rational,
1902 prec: u64,
1903 rm: RoundingMode,
1904 ) -> (Self, Ordering) {
1905 assert_ne!(prec, 0);
1906 if matches!((*self).partial_cmp(other), Some(Greater)) {
1907 self.sub_rational_prec_round_ref_ref(other, prec, rm)
1908 } else if matches!(self, Self(NaN)) {
1909 (float_nan!(), Equal)
1910 } else {
1911 (Self::ZERO, Equal)
1912 }
1913 }
1914
1915 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
1916 /// $+0.0$ otherwise — rounding the result to the nearest value of the specified precision.
1917 /// The [`Float`] and the [`Rational`] are both taken by value. An [`Ordering`] is also
1918 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
1919 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
1920 /// this function returns a `NaN` it also returns `Equal`.
1921 ///
1922 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
1923 /// before use, so the correct branch is always chosen and the winning difference is correctly
1924 /// rounded.
1925 ///
1926 /// Special cases:
1927 /// - $f(\text{NaN},y,p)=\text{NaN}$
1928 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
1929 /// [`Rational`]
1930 /// - $f(\infty,y,p)=\infty$
1931 ///
1932 /// $$
1933 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1934 /// $$
1935 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1936 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
1937 ///
1938 /// If you want to use a rounding mode other than `Nearest`, consider using
1939 /// [`Float::positive_difference_rational_prec_round`] instead. If you know that your target
1940 /// precision is the [`Float`]'s, consider using [`Float::positive_difference_rational`]
1941 /// instead.
1942 ///
1943 /// # Worst-case complexity
1944 /// $T(n) = O(n \log n \log\log n)$
1945 ///
1946 /// $M(n) = O(n)$
1947 ///
1948 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
1949 /// other.significant_bits(), prec)`.
1950 ///
1951 /// # Panics
1952 /// Panics if `prec` is zero.
1953 ///
1954 /// # Examples
1955 /// ```
1956 /// use core::cmp::Ordering::*;
1957 /// use malachite_float::Float;
1958 /// use malachite_q::Rational;
1959 ///
1960 /// let (d, o) =
1961 /// Float::from(3u32).positive_difference_rational_prec(Rational::from_signeds(1, 3), 10);
1962 /// assert_eq!(d.to_string(), "2.6680");
1963 /// assert_eq!(o, Greater);
1964 /// ```
1965 #[inline]
1966 pub fn positive_difference_rational_prec(self, other: Rational, prec: u64) -> (Self, Ordering) {
1967 self.positive_difference_rational_prec_round(other, prec, Nearest)
1968 }
1969
1970 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
1971 /// $+0.0$ otherwise — rounding the result to the nearest value of the specified precision.
1972 /// The [`Float`] is taken by value and the [`Rational`] by reference. An [`Ordering`] is also
1973 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
1974 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
1975 /// this function returns a `NaN` it also returns `Equal`.
1976 ///
1977 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
1978 /// before use, so the correct branch is always chosen and the winning difference is correctly
1979 /// rounded.
1980 ///
1981 /// Special cases:
1982 /// - $f(\text{NaN},y,p)=\text{NaN}$
1983 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
1984 /// [`Rational`]
1985 /// - $f(\infty,y,p)=\infty$
1986 ///
1987 /// $$
1988 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
1989 /// $$
1990 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
1991 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
1992 ///
1993 /// If you want to use a rounding mode other than `Nearest`, consider using
1994 /// [`Float::positive_difference_rational_prec_round`] instead. If you know that your target
1995 /// precision is the [`Float`]'s, consider using [`Float::positive_difference_rational`]
1996 /// instead.
1997 ///
1998 /// # Worst-case complexity
1999 /// $T(n) = O(n \log n \log\log n)$
2000 ///
2001 /// $M(n) = O(n)$
2002 ///
2003 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2004 /// other.significant_bits(), prec)`.
2005 ///
2006 /// # Panics
2007 /// Panics if `prec` is zero.
2008 ///
2009 /// # Examples
2010 /// ```
2011 /// use core::cmp::Ordering::*;
2012 /// use malachite_float::Float;
2013 /// use malachite_q::Rational;
2014 ///
2015 /// let (d, o) = Float::from(3u32)
2016 /// .positive_difference_rational_prec_val_ref(&Rational::from_signeds(1, 3), 10);
2017 /// assert_eq!(d.to_string(), "2.6680");
2018 /// assert_eq!(o, Greater);
2019 /// ```
2020 #[inline]
2021 pub fn positive_difference_rational_prec_val_ref(
2022 self,
2023 other: &Rational,
2024 prec: u64,
2025 ) -> (Self, Ordering) {
2026 self.positive_difference_rational_prec_round_val_ref(other, prec, Nearest)
2027 }
2028
2029 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
2030 /// $+0.0$ otherwise — rounding the result to the nearest value of the specified precision.
2031 /// The [`Float`] is taken by reference and the [`Rational`] by value. An [`Ordering`] is also
2032 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
2033 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
2034 /// this function returns a `NaN` it also returns `Equal`.
2035 ///
2036 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2037 /// before use, so the correct branch is always chosen and the winning difference is correctly
2038 /// rounded.
2039 ///
2040 /// Special cases:
2041 /// - $f(\text{NaN},y,p)=\text{NaN}$
2042 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2043 /// [`Rational`]
2044 /// - $f(\infty,y,p)=\infty$
2045 ///
2046 /// $$
2047 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2048 /// $$
2049 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2050 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
2051 ///
2052 /// If you want to use a rounding mode other than `Nearest`, consider using
2053 /// [`Float::positive_difference_rational_prec_round`] instead. If you know that your target
2054 /// precision is the [`Float`]'s, consider using [`Float::positive_difference_rational`]
2055 /// instead.
2056 ///
2057 /// # Worst-case complexity
2058 /// $T(n) = O(n \log n \log\log n)$
2059 ///
2060 /// $M(n) = O(n)$
2061 ///
2062 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2063 /// other.significant_bits(), prec)`.
2064 ///
2065 /// # Panics
2066 /// Panics if `prec` is zero.
2067 ///
2068 /// # Examples
2069 /// ```
2070 /// use core::cmp::Ordering::*;
2071 /// use malachite_float::Float;
2072 /// use malachite_q::Rational;
2073 ///
2074 /// let (d, o) = Float::from(3u32)
2075 /// .positive_difference_rational_prec_ref_val(Rational::from_signeds(1, 3), 10);
2076 /// assert_eq!(d.to_string(), "2.6680");
2077 /// assert_eq!(o, Greater);
2078 /// ```
2079 #[inline]
2080 pub fn positive_difference_rational_prec_ref_val(
2081 &self,
2082 other: Rational,
2083 prec: u64,
2084 ) -> (Self, Ordering) {
2085 self.positive_difference_rational_prec_round_ref_val(other, prec, Nearest)
2086 }
2087
2088 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
2089 /// $+0.0$ otherwise — rounding the result to the nearest value of the specified precision.
2090 /// The [`Float`] and the [`Rational`] are both taken by reference. An [`Ordering`] is also
2091 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
2092 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
2093 /// this function returns a `NaN` it also returns `Equal`.
2094 ///
2095 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2096 /// before use, so the correct branch is always chosen and the winning difference is correctly
2097 /// rounded.
2098 ///
2099 /// Special cases:
2100 /// - $f(\text{NaN},y,p)=\text{NaN}$
2101 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2102 /// [`Rational`]
2103 /// - $f(\infty,y,p)=\infty$
2104 ///
2105 /// $$
2106 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2107 /// $$
2108 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2109 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
2110 ///
2111 /// If you want to use a rounding mode other than `Nearest`, consider using
2112 /// [`Float::positive_difference_rational_prec_round`] instead. If you know that your target
2113 /// precision is the [`Float`]'s, consider using [`Float::positive_difference_rational`]
2114 /// instead.
2115 ///
2116 /// # Worst-case complexity
2117 /// $T(n) = O(n \log n \log\log n)$
2118 ///
2119 /// $M(n) = O(n)$
2120 ///
2121 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2122 /// other.significant_bits(), prec)`.
2123 ///
2124 /// # Panics
2125 /// Panics if `prec` is zero.
2126 ///
2127 /// # Examples
2128 /// ```
2129 /// use core::cmp::Ordering::*;
2130 /// use malachite_float::Float;
2131 /// use malachite_q::Rational;
2132 ///
2133 /// let (d, o) = Float::from(3u32)
2134 /// .positive_difference_rational_prec_ref_ref(&Rational::from_signeds(1, 3), 10);
2135 /// assert_eq!(d.to_string(), "2.6680");
2136 /// assert_eq!(o, Greater);
2137 /// ```
2138 #[inline]
2139 pub fn positive_difference_rational_prec_ref_ref(
2140 &self,
2141 other: &Rational,
2142 prec: u64,
2143 ) -> (Self, Ordering) {
2144 self.positive_difference_rational_prec_round_ref_ref(other, prec, Nearest)
2145 }
2146
2147 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
2148 /// $+0.0$ otherwise — rounding the result to the [`Float`]'s precision, with the specified
2149 /// rounding mode. The [`Float`] and the [`Rational`] are both taken by value. An [`Ordering`]
2150 /// is also returned, indicating whether the rounded result is less than, equal to, or greater
2151 /// than the exact positive difference. Although `NaN`s are not comparable to any [`Float`],
2152 /// whenever this function returns a `NaN` it also returns `Equal`.
2153 ///
2154 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2155 /// before use, so the correct branch is always chosen and the winning difference is correctly
2156 /// rounded.
2157 ///
2158 /// Special cases:
2159 /// - $f(\text{NaN},y,p)=\text{NaN}$
2160 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2161 /// [`Rational`]
2162 /// - $f(\infty,y,p)=\infty$
2163 ///
2164 /// $$
2165 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2166 /// $$
2167 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2168 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
2169 ///
2170 /// If you want to specify an output precision, consider using
2171 /// [`Float::positive_difference_rational_prec_round`] instead. If you know you'll be using the
2172 /// `Nearest` rounding mode, consider using [`Float::positive_difference_rational`] instead.
2173 ///
2174 /// # Worst-case complexity
2175 /// $T(n) = O(n \log n \log\log n)$
2176 ///
2177 /// $M(n) = O(n)$
2178 ///
2179 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2180 /// other.significant_bits())`.
2181 ///
2182 /// # Panics
2183 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
2184 /// output precision.
2185 ///
2186 /// # Examples
2187 /// ```
2188 /// use core::cmp::Ordering::*;
2189 /// use malachite_base::rounding_modes::RoundingMode::*;
2190 /// use malachite_float::Float;
2191 /// use malachite_q::Rational;
2192 ///
2193 /// let (d, o) = Float::from(3u32)
2194 /// .positive_difference_rational_round(Rational::from_signeds(1, 3), Floor);
2195 /// assert_eq!(d.to_string(), "2.0");
2196 /// assert_eq!(o, Less);
2197 /// ```
2198 #[inline]
2199 pub fn positive_difference_rational_round(
2200 self,
2201 other: Rational,
2202 rm: RoundingMode,
2203 ) -> (Self, Ordering) {
2204 let prec = self.significant_bits();
2205 self.positive_difference_rational_prec_round(other, prec, rm)
2206 }
2207
2208 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
2209 /// $+0.0$ otherwise — rounding the result to the [`Float`]'s precision, with the specified
2210 /// rounding mode. The [`Float`] is taken by value and the [`Rational`] by reference. An
2211 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
2212 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
2213 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2214 ///
2215 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2216 /// before use, so the correct branch is always chosen and the winning difference is correctly
2217 /// rounded.
2218 ///
2219 /// Special cases:
2220 /// - $f(\text{NaN},y,p)=\text{NaN}$
2221 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2222 /// [`Rational`]
2223 /// - $f(\infty,y,p)=\infty$
2224 ///
2225 /// $$
2226 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2227 /// $$
2228 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2229 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
2230 ///
2231 /// If you want to specify an output precision, consider using
2232 /// [`Float::positive_difference_rational_prec_round`] instead. If you know you'll be using the
2233 /// `Nearest` rounding mode, consider using [`Float::positive_difference_rational`] instead.
2234 ///
2235 /// # Worst-case complexity
2236 /// $T(n) = O(n \log n \log\log n)$
2237 ///
2238 /// $M(n) = O(n)$
2239 ///
2240 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2241 /// other.significant_bits())`.
2242 ///
2243 /// # Panics
2244 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
2245 /// output precision.
2246 ///
2247 /// # Examples
2248 /// ```
2249 /// use core::cmp::Ordering::*;
2250 /// use malachite_base::rounding_modes::RoundingMode::*;
2251 /// use malachite_float::Float;
2252 /// use malachite_q::Rational;
2253 ///
2254 /// let (d, o) = Float::from(3u32)
2255 /// .positive_difference_rational_round_val_ref(&Rational::from_signeds(1, 3), Floor);
2256 /// assert_eq!(d.to_string(), "2.0");
2257 /// assert_eq!(o, Less);
2258 /// ```
2259 #[inline]
2260 pub fn positive_difference_rational_round_val_ref(
2261 self,
2262 other: &Rational,
2263 rm: RoundingMode,
2264 ) -> (Self, Ordering) {
2265 let prec = self.significant_bits();
2266 self.positive_difference_rational_prec_round_val_ref(other, prec, rm)
2267 }
2268
2269 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
2270 /// $+0.0$ otherwise — rounding the result to the [`Float`]'s precision, with the specified
2271 /// rounding mode. The [`Float`] is taken by reference and the [`Rational`] by value. An
2272 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
2273 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
2274 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2275 ///
2276 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2277 /// before use, so the correct branch is always chosen and the winning difference is correctly
2278 /// rounded.
2279 ///
2280 /// Special cases:
2281 /// - $f(\text{NaN},y,p)=\text{NaN}$
2282 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2283 /// [`Rational`]
2284 /// - $f(\infty,y,p)=\infty$
2285 ///
2286 /// $$
2287 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2288 /// $$
2289 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2290 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
2291 ///
2292 /// If you want to specify an output precision, consider using
2293 /// [`Float::positive_difference_rational_prec_round`] instead. If you know you'll be using the
2294 /// `Nearest` rounding mode, consider using [`Float::positive_difference_rational`] instead.
2295 ///
2296 /// # Worst-case complexity
2297 /// $T(n) = O(n \log n \log\log n)$
2298 ///
2299 /// $M(n) = O(n)$
2300 ///
2301 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2302 /// other.significant_bits())`.
2303 ///
2304 /// # Panics
2305 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
2306 /// output precision.
2307 ///
2308 /// # Examples
2309 /// ```
2310 /// use core::cmp::Ordering::*;
2311 /// use malachite_base::rounding_modes::RoundingMode::*;
2312 /// use malachite_float::Float;
2313 /// use malachite_q::Rational;
2314 ///
2315 /// let (d, o) = Float::from(3u32)
2316 /// .positive_difference_rational_round_ref_val(Rational::from_signeds(1, 3), Floor);
2317 /// assert_eq!(d.to_string(), "2.0");
2318 /// assert_eq!(o, Less);
2319 /// ```
2320 #[inline]
2321 pub fn positive_difference_rational_round_ref_val(
2322 &self,
2323 other: Rational,
2324 rm: RoundingMode,
2325 ) -> (Self, Ordering) {
2326 let prec = self.significant_bits();
2327 self.positive_difference_rational_prec_round_ref_val(other, prec, rm)
2328 }
2329
2330 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
2331 /// $+0.0$ otherwise — rounding the result to the [`Float`]'s precision, with the specified
2332 /// rounding mode. The [`Float`] and the [`Rational`] are both taken by reference. An
2333 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
2334 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
2335 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2336 ///
2337 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2338 /// before use, so the correct branch is always chosen and the winning difference is correctly
2339 /// rounded.
2340 ///
2341 /// Special cases:
2342 /// - $f(\text{NaN},y,p)=\text{NaN}$
2343 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2344 /// [`Rational`]
2345 /// - $f(\infty,y,p)=\infty$
2346 ///
2347 /// $$
2348 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2349 /// $$
2350 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2351 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
2352 ///
2353 /// If you want to specify an output precision, consider using
2354 /// [`Float::positive_difference_rational_prec_round`] instead. If you know you'll be using the
2355 /// `Nearest` rounding mode, consider using [`Float::positive_difference_rational`] instead.
2356 ///
2357 /// # Worst-case complexity
2358 /// $T(n) = O(n \log n \log\log n)$
2359 ///
2360 /// $M(n) = O(n)$
2361 ///
2362 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2363 /// other.significant_bits())`.
2364 ///
2365 /// # Panics
2366 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
2367 /// output precision.
2368 ///
2369 /// # Examples
2370 /// ```
2371 /// use core::cmp::Ordering::*;
2372 /// use malachite_base::rounding_modes::RoundingMode::*;
2373 /// use malachite_float::Float;
2374 /// use malachite_q::Rational;
2375 ///
2376 /// let (d, o) = Float::from(3u32)
2377 /// .positive_difference_rational_round_ref_ref(&Rational::from_signeds(1, 3), Floor);
2378 /// assert_eq!(d.to_string(), "2.0");
2379 /// assert_eq!(o, Less);
2380 /// ```
2381 #[inline]
2382 pub fn positive_difference_rational_round_ref_ref(
2383 &self,
2384 other: &Rational,
2385 rm: RoundingMode,
2386 ) -> (Self, Ordering) {
2387 let prec = self.significant_bits();
2388 self.positive_difference_rational_prec_round_ref_ref(other, prec, rm)
2389 }
2390
2391 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
2392 /// $+0.0$ otherwise — rounding the result to the nearest value of the [`Float`]'s precision.
2393 /// The [`Float`] and the [`Rational`] are both taken by value. An [`Ordering`] is also
2394 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
2395 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
2396 /// this function returns a `NaN` it also returns `Equal`.
2397 ///
2398 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2399 /// before use, so the correct branch is always chosen and the winning difference is correctly
2400 /// rounded.
2401 ///
2402 /// Special cases:
2403 /// - $f(\text{NaN},y,p)=\text{NaN}$
2404 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2405 /// [`Rational`]
2406 /// - $f(\infty,y,p)=\infty$
2407 ///
2408 /// $$
2409 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2410 /// $$
2411 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2412 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
2413 ///
2414 /// If you want to specify an output precision, consider using
2415 /// [`Float::positive_difference_rational_prec`] instead. If you want to use a rounding mode
2416 /// other than `Nearest`, consider using [`Float::positive_difference_rational_round`] instead.
2417 ///
2418 /// # Worst-case complexity
2419 /// $T(n) = O(n \log n \log\log n)$
2420 ///
2421 /// $M(n) = O(n)$
2422 ///
2423 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2424 /// other.significant_bits())`.
2425 ///
2426 /// # Examples
2427 /// ```
2428 /// use core::cmp::Ordering::*;
2429 /// use malachite_float::Float;
2430 /// use malachite_q::Rational;
2431 ///
2432 /// let (d, o) = Float::from(3u32).positive_difference_rational(Rational::from_signeds(1, 3));
2433 /// assert_eq!(d.to_string(), "3.0");
2434 /// assert_eq!(o, Greater);
2435 /// ```
2436 #[inline]
2437 pub fn positive_difference_rational(self, other: Rational) -> (Self, Ordering) {
2438 self.positive_difference_rational_round(other, Nearest)
2439 }
2440
2441 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
2442 /// $+0.0$ otherwise — rounding the result to the nearest value of the [`Float`]'s precision.
2443 /// The [`Float`] is taken by value and the [`Rational`] by reference. An [`Ordering`] is also
2444 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
2445 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
2446 /// this function returns a `NaN` it also returns `Equal`.
2447 ///
2448 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2449 /// before use, so the correct branch is always chosen and the winning difference is correctly
2450 /// rounded.
2451 ///
2452 /// Special cases:
2453 /// - $f(\text{NaN},y,p)=\text{NaN}$
2454 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2455 /// [`Rational`]
2456 /// - $f(\infty,y,p)=\infty$
2457 ///
2458 /// $$
2459 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2460 /// $$
2461 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2462 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
2463 ///
2464 /// If you want to specify an output precision, consider using
2465 /// [`Float::positive_difference_rational_prec`] instead. If you want to use a rounding mode
2466 /// other than `Nearest`, consider using [`Float::positive_difference_rational_round`] instead.
2467 ///
2468 /// # Worst-case complexity
2469 /// $T(n) = O(n \log n \log\log n)$
2470 ///
2471 /// $M(n) = O(n)$
2472 ///
2473 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2474 /// other.significant_bits())`.
2475 ///
2476 /// # Examples
2477 /// ```
2478 /// use core::cmp::Ordering::*;
2479 /// use malachite_float::Float;
2480 /// use malachite_q::Rational;
2481 ///
2482 /// let (d, o) =
2483 /// Float::from(3u32).positive_difference_rational_val_ref(&Rational::from_signeds(1, 3));
2484 /// assert_eq!(d.to_string(), "3.0");
2485 /// assert_eq!(o, Greater);
2486 /// ```
2487 #[inline]
2488 pub fn positive_difference_rational_val_ref(self, other: &Rational) -> (Self, Ordering) {
2489 self.positive_difference_rational_round_val_ref(other, Nearest)
2490 }
2491
2492 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
2493 /// $+0.0$ otherwise — rounding the result to the nearest value of the [`Float`]'s precision.
2494 /// The [`Float`] is taken by reference and the [`Rational`] by value. An [`Ordering`] is also
2495 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
2496 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
2497 /// this function returns a `NaN` it also returns `Equal`.
2498 ///
2499 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2500 /// before use, so the correct branch is always chosen and the winning difference is correctly
2501 /// rounded.
2502 ///
2503 /// Special cases:
2504 /// - $f(\text{NaN},y,p)=\text{NaN}$
2505 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2506 /// [`Rational`]
2507 /// - $f(\infty,y,p)=\infty$
2508 ///
2509 /// $$
2510 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2511 /// $$
2512 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2513 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
2514 ///
2515 /// If you want to specify an output precision, consider using
2516 /// [`Float::positive_difference_rational_prec`] instead. If you want to use a rounding mode
2517 /// other than `Nearest`, consider using [`Float::positive_difference_rational_round`] instead.
2518 ///
2519 /// # Worst-case complexity
2520 /// $T(n) = O(n \log n \log\log n)$
2521 ///
2522 /// $M(n) = O(n)$
2523 ///
2524 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2525 /// other.significant_bits())`.
2526 ///
2527 /// # Examples
2528 /// ```
2529 /// use core::cmp::Ordering::*;
2530 /// use malachite_float::Float;
2531 /// use malachite_q::Rational;
2532 ///
2533 /// let (d, o) =
2534 /// Float::from(3u32).positive_difference_rational_ref_val(Rational::from_signeds(1, 3));
2535 /// assert_eq!(d.to_string(), "3.0");
2536 /// assert_eq!(o, Greater);
2537 /// ```
2538 #[inline]
2539 pub fn positive_difference_rational_ref_val(&self, other: Rational) -> (Self, Ordering) {
2540 self.positive_difference_rational_round_ref_val(other, Nearest)
2541 }
2542
2543 /// Computes the positive difference of a [`Float`] and a [`Rational`] — $x-y$ if $x>y$, and
2544 /// $+0.0$ otherwise — rounding the result to the nearest value of the [`Float`]'s precision.
2545 /// The [`Float`] and the [`Rational`] are both taken by reference. An [`Ordering`] is also
2546 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
2547 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
2548 /// this function returns a `NaN` it also returns `Equal`.
2549 ///
2550 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2551 /// before use, so the correct branch is always chosen and the winning difference is correctly
2552 /// rounded.
2553 ///
2554 /// Special cases:
2555 /// - $f(\text{NaN},y,p)=\text{NaN}$
2556 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2557 /// [`Rational`]
2558 /// - $f(\infty,y,p)=\infty$
2559 ///
2560 /// $$
2561 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2562 /// $$
2563 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2564 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
2565 ///
2566 /// If you want to specify an output precision, consider using
2567 /// [`Float::positive_difference_rational_prec`] instead. If you want to use a rounding mode
2568 /// other than `Nearest`, consider using [`Float::positive_difference_rational_round`] instead.
2569 ///
2570 /// # Worst-case complexity
2571 /// $T(n) = O(n \log n \log\log n)$
2572 ///
2573 /// $M(n) = O(n)$
2574 ///
2575 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2576 /// other.significant_bits())`.
2577 ///
2578 /// # Examples
2579 /// ```
2580 /// use core::cmp::Ordering::*;
2581 /// use malachite_float::Float;
2582 /// use malachite_q::Rational;
2583 ///
2584 /// let (d, o) =
2585 /// Float::from(3u32).positive_difference_rational_ref_ref(&Rational::from_signeds(1, 3));
2586 /// assert_eq!(d.to_string(), "3.0");
2587 /// assert_eq!(o, Greater);
2588 /// ```
2589 #[inline]
2590 pub fn positive_difference_rational_ref_ref(&self, other: &Rational) -> (Self, Ordering) {
2591 self.positive_difference_rational_round_ref_ref(other, Nearest)
2592 }
2593
2594 /// Computes the positive difference of a [`Float`] and a [`Rational`] in place — $x-y$ if
2595 /// $x>y$, and $+0.0$ otherwise — rounding the result to the specified precision and with the
2596 /// specified rounding mode. The [`Rational`] is taken by value. An [`Ordering`] is also
2597 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
2598 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
2599 /// this function returns a `NaN` it also returns `Equal`.
2600 ///
2601 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2602 /// before use, so the correct branch is always chosen and the winning difference is correctly
2603 /// rounded.
2604 ///
2605 /// Special cases:
2606 /// - $f(\text{NaN},y,p)=\text{NaN}$
2607 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2608 /// [`Rational`]
2609 /// - $f(\infty,y,p)=\infty$
2610 ///
2611 /// $$
2612 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2613 /// $$
2614 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2615 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
2616 ///
2617 /// # Worst-case complexity
2618 /// $T(n) = O(n \log n \log\log n)$
2619 ///
2620 /// $M(n) = O(n)$
2621 ///
2622 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2623 /// other.significant_bits(), prec)`.
2624 ///
2625 /// # Panics
2626 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
2627 /// representable with `prec` bits.
2628 ///
2629 /// # Examples
2630 /// ```
2631 /// use core::cmp::Ordering::*;
2632 /// use malachite_base::rounding_modes::RoundingMode::*;
2633 /// use malachite_float::Float;
2634 /// use malachite_q::Rational;
2635 ///
2636 /// let mut x = Float::from(3u32);
2637 /// assert_eq!(
2638 /// x.positive_difference_rational_prec_round_assign(
2639 /// Rational::from_signeds(1, 3),
2640 /// 10,
2641 /// Floor
2642 /// ),
2643 /// Less
2644 /// );
2645 /// assert_eq!(x.to_string(), "2.6641");
2646 /// ```
2647 #[allow(clippy::needless_pass_by_value)]
2648 pub fn positive_difference_rational_prec_round_assign(
2649 &mut self,
2650 other: Rational,
2651 prec: u64,
2652 rm: RoundingMode,
2653 ) -> Ordering {
2654 assert_ne!(prec, 0);
2655 if matches!((*self).partial_cmp(&other), Some(Greater)) {
2656 self.sub_rational_prec_round_assign(other, prec, rm)
2657 } else if matches!(self, Self(NaN)) {
2658 *self = float_nan!();
2659 Equal
2660 } else {
2661 *self = Self::ZERO;
2662 Equal
2663 }
2664 }
2665
2666 /// Computes the positive difference of a [`Float`] and a [`Rational`] in place — $x-y$ if
2667 /// $x>y$, and $+0.0$ otherwise — rounding the result to the specified precision and with the
2668 /// specified rounding mode. The [`Rational`] is taken by reference. An [`Ordering`] is also
2669 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
2670 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
2671 /// this function returns a `NaN` it also returns `Equal`.
2672 ///
2673 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2674 /// before use, so the correct branch is always chosen and the winning difference is correctly
2675 /// rounded.
2676 ///
2677 /// Special cases:
2678 /// - $f(\text{NaN},y,p)=\text{NaN}$
2679 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2680 /// [`Rational`]
2681 /// - $f(\infty,y,p)=\infty$
2682 ///
2683 /// $$
2684 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2685 /// $$
2686 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2687 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
2688 ///
2689 /// # Worst-case complexity
2690 /// $T(n) = O(n \log n \log\log n)$
2691 ///
2692 /// $M(n) = O(n)$
2693 ///
2694 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2695 /// other.significant_bits(), prec)`.
2696 ///
2697 /// # Panics
2698 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
2699 /// representable with `prec` bits.
2700 ///
2701 /// # Examples
2702 /// ```
2703 /// use core::cmp::Ordering::*;
2704 /// use malachite_base::rounding_modes::RoundingMode::*;
2705 /// use malachite_float::Float;
2706 /// use malachite_q::Rational;
2707 ///
2708 /// let mut x = Float::from(3u32);
2709 /// assert_eq!(
2710 /// x.positive_difference_rational_prec_round_assign_ref(
2711 /// &Rational::from_signeds(1, 3),
2712 /// 10,
2713 /// Floor
2714 /// ),
2715 /// Less
2716 /// );
2717 /// assert_eq!(x.to_string(), "2.6641");
2718 /// ```
2719 pub fn positive_difference_rational_prec_round_assign_ref(
2720 &mut self,
2721 other: &Rational,
2722 prec: u64,
2723 rm: RoundingMode,
2724 ) -> Ordering {
2725 assert_ne!(prec, 0);
2726 if matches!((*self).partial_cmp(other), Some(Greater)) {
2727 self.sub_rational_prec_round_assign_ref(other, prec, rm)
2728 } else if matches!(self, Self(NaN)) {
2729 *self = float_nan!();
2730 Equal
2731 } else {
2732 *self = Self::ZERO;
2733 Equal
2734 }
2735 }
2736
2737 /// Computes the positive difference of a [`Float`] and a [`Rational`] in place — $x-y$ if
2738 /// $x>y$, and $+0.0$ otherwise — rounding the result to the nearest value of the specified
2739 /// precision. The [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating
2740 /// whether the rounded result is less than, equal to, or greater than the exact positive
2741 /// difference. Although `NaN`s are not comparable to any [`Float`], whenever this function
2742 /// returns a `NaN` it also returns `Equal`.
2743 ///
2744 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2745 /// before use, so the correct branch is always chosen and the winning difference is correctly
2746 /// rounded.
2747 ///
2748 /// Special cases:
2749 /// - $f(\text{NaN},y,p)=\text{NaN}$
2750 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2751 /// [`Rational`]
2752 /// - $f(\infty,y,p)=\infty$
2753 ///
2754 /// $$
2755 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2756 /// $$
2757 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2758 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
2759 ///
2760 /// # Worst-case complexity
2761 /// $T(n) = O(n \log n \log\log n)$
2762 ///
2763 /// $M(n) = O(n)$
2764 ///
2765 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2766 /// other.significant_bits(), prec)`.
2767 ///
2768 /// # Panics
2769 /// Panics if `prec` is zero.
2770 ///
2771 /// # Examples
2772 /// ```
2773 /// use core::cmp::Ordering::*;
2774 /// use malachite_float::Float;
2775 /// use malachite_q::Rational;
2776 ///
2777 /// let mut x = Float::from(3u32);
2778 /// assert_eq!(
2779 /// x.positive_difference_rational_prec_assign(Rational::from_signeds(1, 3), 10),
2780 /// Greater
2781 /// );
2782 /// assert_eq!(x.to_string(), "2.6680");
2783 /// ```
2784 #[inline]
2785 pub fn positive_difference_rational_prec_assign(
2786 &mut self,
2787 other: Rational,
2788 prec: u64,
2789 ) -> Ordering {
2790 self.positive_difference_rational_prec_round_assign(other, prec, Nearest)
2791 }
2792
2793 /// Computes the positive difference of a [`Float`] and a [`Rational`] in place — $x-y$ if
2794 /// $x>y$, and $+0.0$ otherwise — rounding the result to the nearest value of the specified
2795 /// precision. The [`Rational`] is taken by reference. An [`Ordering`] is also returned,
2796 /// indicating whether the rounded result is less than, equal to, or greater than the exact
2797 /// positive difference. Although `NaN`s are not comparable to any [`Float`], whenever this
2798 /// function returns a `NaN` it also returns `Equal`.
2799 ///
2800 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2801 /// before use, so the correct branch is always chosen and the winning difference is correctly
2802 /// rounded.
2803 ///
2804 /// Special cases:
2805 /// - $f(\text{NaN},y,p)=\text{NaN}$
2806 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2807 /// [`Rational`]
2808 /// - $f(\infty,y,p)=\infty$
2809 ///
2810 /// $$
2811 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2812 /// $$
2813 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2814 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
2815 ///
2816 /// # Worst-case complexity
2817 /// $T(n) = O(n \log n \log\log n)$
2818 ///
2819 /// $M(n) = O(n)$
2820 ///
2821 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2822 /// other.significant_bits(), prec)`.
2823 ///
2824 /// # Panics
2825 /// Panics if `prec` is zero.
2826 ///
2827 /// # Examples
2828 /// ```
2829 /// use core::cmp::Ordering::*;
2830 /// use malachite_float::Float;
2831 /// use malachite_q::Rational;
2832 ///
2833 /// let mut x = Float::from(3u32);
2834 /// assert_eq!(
2835 /// x.positive_difference_rational_prec_assign_ref(&Rational::from_signeds(1, 3), 10),
2836 /// Greater
2837 /// );
2838 /// assert_eq!(x.to_string(), "2.6680");
2839 /// ```
2840 #[inline]
2841 pub fn positive_difference_rational_prec_assign_ref(
2842 &mut self,
2843 other: &Rational,
2844 prec: u64,
2845 ) -> Ordering {
2846 self.positive_difference_rational_prec_round_assign_ref(other, prec, Nearest)
2847 }
2848
2849 /// Computes the positive difference of a [`Float`] and a [`Rational`] in place — $x-y$ if
2850 /// $x>y$, and $+0.0$ otherwise — rounding the result to the [`Float`]'s precision, with the
2851 /// specified rounding mode. The [`Rational`] is taken by value. An [`Ordering`] is also
2852 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
2853 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
2854 /// this function returns a `NaN` it also returns `Equal`.
2855 ///
2856 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2857 /// before use, so the correct branch is always chosen and the winning difference is correctly
2858 /// rounded.
2859 ///
2860 /// Special cases:
2861 /// - $f(\text{NaN},y,p)=\text{NaN}$
2862 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2863 /// [`Rational`]
2864 /// - $f(\infty,y,p)=\infty$
2865 ///
2866 /// $$
2867 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2868 /// $$
2869 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2870 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
2871 ///
2872 /// # Worst-case complexity
2873 /// $T(n) = O(n \log n \log\log n)$
2874 ///
2875 /// $M(n) = O(n)$
2876 ///
2877 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2878 /// other.significant_bits())`.
2879 ///
2880 /// # Panics
2881 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
2882 /// output precision.
2883 ///
2884 /// # Examples
2885 /// ```
2886 /// use core::cmp::Ordering::*;
2887 /// use malachite_base::rounding_modes::RoundingMode::*;
2888 /// use malachite_float::Float;
2889 /// use malachite_q::Rational;
2890 ///
2891 /// let mut x = Float::from(3u32);
2892 /// assert_eq!(
2893 /// x.positive_difference_rational_round_assign(Rational::from_signeds(1, 3), Floor),
2894 /// Less
2895 /// );
2896 /// assert_eq!(x.to_string(), "2.0");
2897 /// ```
2898 #[inline]
2899 pub fn positive_difference_rational_round_assign(
2900 &mut self,
2901 other: Rational,
2902 rm: RoundingMode,
2903 ) -> Ordering {
2904 let prec = self.significant_bits();
2905 self.positive_difference_rational_prec_round_assign(other, prec, rm)
2906 }
2907
2908 /// Computes the positive difference of a [`Float`] and a [`Rational`] in place — $x-y$ if
2909 /// $x>y$, and $+0.0$ otherwise — rounding the result to the [`Float`]'s precision, with the
2910 /// specified rounding mode. The [`Rational`] is taken by reference. An [`Ordering`] is also
2911 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
2912 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
2913 /// this function returns a `NaN` it also returns `Equal`.
2914 ///
2915 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2916 /// before use, so the correct branch is always chosen and the winning difference is correctly
2917 /// rounded.
2918 ///
2919 /// Special cases:
2920 /// - $f(\text{NaN},y,p)=\text{NaN}$
2921 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2922 /// [`Rational`]
2923 /// - $f(\infty,y,p)=\infty$
2924 ///
2925 /// $$
2926 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2927 /// $$
2928 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2929 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
2930 ///
2931 /// # Worst-case complexity
2932 /// $T(n) = O(n \log n \log\log n)$
2933 ///
2934 /// $M(n) = O(n)$
2935 ///
2936 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2937 /// other.significant_bits())`.
2938 ///
2939 /// # Panics
2940 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
2941 /// output precision.
2942 ///
2943 /// # Examples
2944 /// ```
2945 /// use core::cmp::Ordering::*;
2946 /// use malachite_base::rounding_modes::RoundingMode::*;
2947 /// use malachite_float::Float;
2948 /// use malachite_q::Rational;
2949 ///
2950 /// let mut x = Float::from(3u32);
2951 /// assert_eq!(
2952 /// x.positive_difference_rational_round_assign_ref(&Rational::from_signeds(1, 3), Floor),
2953 /// Less
2954 /// );
2955 /// assert_eq!(x.to_string(), "2.0");
2956 /// ```
2957 #[inline]
2958 pub fn positive_difference_rational_round_assign_ref(
2959 &mut self,
2960 other: &Rational,
2961 rm: RoundingMode,
2962 ) -> Ordering {
2963 let prec = self.significant_bits();
2964 self.positive_difference_rational_prec_round_assign_ref(other, prec, rm)
2965 }
2966
2967 /// Computes the positive difference of a [`Float`] and a [`Rational`] in place — $x-y$ if
2968 /// $x>y$, and $+0.0$ otherwise — rounding the result to the nearest value of the [`Float`]'s
2969 /// precision. The [`Rational`] is taken by value. An [`Ordering`] is also returned, indicating
2970 /// whether the rounded result is less than, equal to, or greater than the exact positive
2971 /// difference. Although `NaN`s are not comparable to any [`Float`], whenever this function
2972 /// returns a `NaN` it also returns `Equal`.
2973 ///
2974 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
2975 /// before use, so the correct branch is always chosen and the winning difference is correctly
2976 /// rounded.
2977 ///
2978 /// Special cases:
2979 /// - $f(\text{NaN},y,p)=\text{NaN}$
2980 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
2981 /// [`Rational`]
2982 /// - $f(\infty,y,p)=\infty$
2983 ///
2984 /// $$
2985 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
2986 /// $$
2987 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
2988 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
2989 ///
2990 /// # Worst-case complexity
2991 /// $T(n) = O(n \log n \log\log n)$
2992 ///
2993 /// $M(n) = O(n)$
2994 ///
2995 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
2996 /// other.significant_bits())`.
2997 ///
2998 /// # Examples
2999 /// ```
3000 /// use core::cmp::Ordering::*;
3001 /// use malachite_float::Float;
3002 /// use malachite_q::Rational;
3003 ///
3004 /// let mut x = Float::from(3u32);
3005 /// assert_eq!(
3006 /// x.positive_difference_rational_assign(Rational::from_signeds(1, 3)),
3007 /// Greater
3008 /// );
3009 /// assert_eq!(x.to_string(), "3.0");
3010 /// ```
3011 #[inline]
3012 pub fn positive_difference_rational_assign(&mut self, other: Rational) -> Ordering {
3013 self.positive_difference_rational_round_assign(other, Nearest)
3014 }
3015
3016 /// Computes the positive difference of a [`Float`] and a [`Rational`] in place — $x-y$ if
3017 /// $x>y$, and $+0.0$ otherwise — rounding the result to the nearest value of the [`Float`]'s
3018 /// precision. The [`Rational`] is taken by reference. An [`Ordering`] is also returned,
3019 /// indicating whether the rounded result is less than, equal to, or greater than the exact
3020 /// positive difference. Although `NaN`s are not comparable to any [`Float`], whenever this
3021 /// function returns a `NaN` it also returns `Equal`.
3022 ///
3023 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3024 /// before use, so the correct branch is always chosen and the winning difference is correctly
3025 /// rounded.
3026 ///
3027 /// Special cases:
3028 /// - $f(\text{NaN},y,p)=\text{NaN}$
3029 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including for a zero [`Float`] of either sign against a zero
3030 /// [`Rational`]
3031 /// - $f(\infty,y,p)=\infty$
3032 ///
3033 /// $$
3034 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3035 /// $$
3036 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3037 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
3038 ///
3039 /// # Worst-case complexity
3040 /// $T(n) = O(n \log n \log\log n)$
3041 ///
3042 /// $M(n) = O(n)$
3043 ///
3044 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.complexity(),
3045 /// other.significant_bits())`.
3046 ///
3047 /// # Examples
3048 /// ```
3049 /// use core::cmp::Ordering::*;
3050 /// use malachite_float::Float;
3051 /// use malachite_q::Rational;
3052 ///
3053 /// let mut x = Float::from(3u32);
3054 /// assert_eq!(
3055 /// x.positive_difference_rational_assign_ref(&Rational::from_signeds(1, 3)),
3056 /// Greater
3057 /// );
3058 /// assert_eq!(x.to_string(), "3.0");
3059 /// ```
3060 #[inline]
3061 pub fn positive_difference_rational_assign_ref(&mut self, other: &Rational) -> Ordering {
3062 self.positive_difference_rational_round_assign_ref(other, Nearest)
3063 }
3064
3065 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
3066 /// $+0.0$ otherwise — rounding the result to the specified precision and with the specified
3067 /// rounding mode. The [`Rational`] and the [`Float`] are both taken by value. An [`Ordering`]
3068 /// is also returned, indicating whether the rounded result is less than, equal to, or greater
3069 /// than the exact positive difference. Although `NaN`s are not comparable to any [`Float`],
3070 /// whenever this function returns a `NaN` it also returns `Equal`.
3071 ///
3072 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3073 /// before use, so the correct branch is always chosen and the winning difference is correctly
3074 /// rounded.
3075 ///
3076 /// Special cases:
3077 /// - $f(x,\text{NaN},p)=\text{NaN}$
3078 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
3079 /// - $f(x,-\infty,p)=\infty$
3080 ///
3081 /// $$
3082 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3083 /// $$
3084 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3085 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
3086 ///
3087 /// If you know you'll be using `Nearest`, consider using
3088 /// [`Float::rational_positive_difference_float_prec`] instead. If you know that your target
3089 /// precision is the [`Float`]'s, consider using
3090 /// [`Float::rational_positive_difference_float_round`] instead. If both of these things are
3091 /// true, consider using [`Float::rational_positive_difference_float`] instead.
3092 ///
3093 /// # Worst-case complexity
3094 /// $T(n) = O(n \log n \log\log n)$
3095 ///
3096 /// $M(n) = O(n)$
3097 ///
3098 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
3099 /// y.complexity(), prec)`.
3100 ///
3101 /// # Panics
3102 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
3103 /// representable with `prec` bits.
3104 ///
3105 /// # Examples
3106 /// ```
3107 /// use core::cmp::Ordering::*;
3108 /// use malachite_base::rounding_modes::RoundingMode::*;
3109 /// use malachite_float::Float;
3110 /// use malachite_q::Rational;
3111 ///
3112 /// let (d, o) = Float::rational_positive_difference_float_prec_round(
3113 /// Rational::from_signeds(22, 7),
3114 /// Float::from(3u32),
3115 /// 10,
3116 /// Floor,
3117 /// );
3118 /// assert_eq!(d.to_string(), "0.14282");
3119 /// assert_eq!(o, Less);
3120 /// ```
3121 #[allow(clippy::needless_pass_by_value)]
3122 pub fn rational_positive_difference_float_prec_round(
3123 x: Rational,
3124 y: Self,
3125 prec: u64,
3126 rm: RoundingMode,
3127 ) -> (Self, Ordering) {
3128 assert_ne!(prec, 0);
3129 if matches!(y.partial_cmp(&x), Some(Less)) {
3130 // x - y = -(y - x), with the rounding mode reversed
3131 let (d, o) = y.sub_rational_prec_round(x, prec, -rm);
3132 (-d, o.reverse())
3133 } else if matches!(y, Self(NaN)) {
3134 (float_nan!(), Equal)
3135 } else {
3136 (Self::ZERO, Equal)
3137 }
3138 }
3139
3140 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
3141 /// $+0.0$ otherwise — rounding the result to the specified precision and with the specified
3142 /// rounding mode. The [`Rational`] is taken by value and the [`Float`] by reference. An
3143 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
3144 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
3145 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3146 ///
3147 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3148 /// before use, so the correct branch is always chosen and the winning difference is correctly
3149 /// rounded.
3150 ///
3151 /// Special cases:
3152 /// - $f(x,\text{NaN},p)=\text{NaN}$
3153 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
3154 /// - $f(x,-\infty,p)=\infty$
3155 ///
3156 /// $$
3157 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3158 /// $$
3159 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3160 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
3161 ///
3162 /// If you know you'll be using `Nearest`, consider using
3163 /// [`Float::rational_positive_difference_float_prec`] instead. If you know that your target
3164 /// precision is the [`Float`]'s, consider using
3165 /// [`Float::rational_positive_difference_float_round`] instead. If both of these things are
3166 /// true, consider using [`Float::rational_positive_difference_float`] instead.
3167 ///
3168 /// # Worst-case complexity
3169 /// $T(n) = O(n \log n \log\log n)$
3170 ///
3171 /// $M(n) = O(n)$
3172 ///
3173 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
3174 /// y.complexity(), prec)`.
3175 ///
3176 /// # Panics
3177 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
3178 /// representable with `prec` bits.
3179 ///
3180 /// # Examples
3181 /// ```
3182 /// use core::cmp::Ordering::*;
3183 /// use malachite_base::rounding_modes::RoundingMode::*;
3184 /// use malachite_float::Float;
3185 /// use malachite_q::Rational;
3186 ///
3187 /// let (d, o) = Float::rational_positive_difference_float_prec_round_val_ref(
3188 /// Rational::from_signeds(22, 7),
3189 /// &Float::from(3u32),
3190 /// 10,
3191 /// Floor,
3192 /// );
3193 /// assert_eq!(d.to_string(), "0.14282");
3194 /// assert_eq!(o, Less);
3195 /// ```
3196 #[allow(clippy::needless_pass_by_value)]
3197 pub fn rational_positive_difference_float_prec_round_val_ref(
3198 x: Rational,
3199 y: &Self,
3200 prec: u64,
3201 rm: RoundingMode,
3202 ) -> (Self, Ordering) {
3203 assert_ne!(prec, 0);
3204 if matches!(y.partial_cmp(&x), Some(Less)) {
3205 // x - y = -(y - x), with the rounding mode reversed
3206 let (d, o) = y.sub_rational_prec_round_ref_val(x, prec, -rm);
3207 (-d, o.reverse())
3208 } else if matches!(y, Self(NaN)) {
3209 (float_nan!(), Equal)
3210 } else {
3211 (Self::ZERO, Equal)
3212 }
3213 }
3214
3215 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
3216 /// $+0.0$ otherwise — rounding the result to the specified precision and with the specified
3217 /// rounding mode. The [`Rational`] is taken by reference and the [`Float`] by value. An
3218 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
3219 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
3220 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3221 ///
3222 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3223 /// before use, so the correct branch is always chosen and the winning difference is correctly
3224 /// rounded.
3225 ///
3226 /// Special cases:
3227 /// - $f(x,\text{NaN},p)=\text{NaN}$
3228 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
3229 /// - $f(x,-\infty,p)=\infty$
3230 ///
3231 /// $$
3232 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3233 /// $$
3234 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3235 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
3236 ///
3237 /// If you know you'll be using `Nearest`, consider using
3238 /// [`Float::rational_positive_difference_float_prec`] instead. If you know that your target
3239 /// precision is the [`Float`]'s, consider using
3240 /// [`Float::rational_positive_difference_float_round`] instead. If both of these things are
3241 /// true, consider using [`Float::rational_positive_difference_float`] instead.
3242 ///
3243 /// # Worst-case complexity
3244 /// $T(n) = O(n \log n \log\log n)$
3245 ///
3246 /// $M(n) = O(n)$
3247 ///
3248 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
3249 /// y.complexity(), prec)`.
3250 ///
3251 /// # Panics
3252 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
3253 /// representable with `prec` bits.
3254 ///
3255 /// # Examples
3256 /// ```
3257 /// use core::cmp::Ordering::*;
3258 /// use malachite_base::rounding_modes::RoundingMode::*;
3259 /// use malachite_float::Float;
3260 /// use malachite_q::Rational;
3261 ///
3262 /// let (d, o) = Float::rational_positive_difference_float_prec_round_ref_val(
3263 /// &Rational::from_signeds(22, 7),
3264 /// Float::from(3u32),
3265 /// 10,
3266 /// Floor,
3267 /// );
3268 /// assert_eq!(d.to_string(), "0.14282");
3269 /// assert_eq!(o, Less);
3270 /// ```
3271 #[allow(clippy::needless_pass_by_value)]
3272 pub fn rational_positive_difference_float_prec_round_ref_val(
3273 x: &Rational,
3274 y: Self,
3275 prec: u64,
3276 rm: RoundingMode,
3277 ) -> (Self, Ordering) {
3278 assert_ne!(prec, 0);
3279 if matches!(y.partial_cmp(x), Some(Less)) {
3280 // x - y = -(y - x), with the rounding mode reversed
3281 let (d, o) = y.sub_rational_prec_round_val_ref(x, prec, -rm);
3282 (-d, o.reverse())
3283 } else if matches!(y, Self(NaN)) {
3284 (float_nan!(), Equal)
3285 } else {
3286 (Self::ZERO, Equal)
3287 }
3288 }
3289
3290 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
3291 /// $+0.0$ otherwise — rounding the result to the specified precision and with the specified
3292 /// rounding mode. The [`Rational`] and the [`Float`] are both taken by reference. An
3293 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
3294 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
3295 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3296 ///
3297 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3298 /// before use, so the correct branch is always chosen and the winning difference is correctly
3299 /// rounded.
3300 ///
3301 /// Special cases:
3302 /// - $f(x,\text{NaN},p)=\text{NaN}$
3303 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
3304 /// - $f(x,-\infty,p)=\infty$
3305 ///
3306 /// $$
3307 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3308 /// $$
3309 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3310 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
3311 ///
3312 /// If you know you'll be using `Nearest`, consider using
3313 /// [`Float::rational_positive_difference_float_prec`] instead. If you know that your target
3314 /// precision is the [`Float`]'s, consider using
3315 /// [`Float::rational_positive_difference_float_round`] instead. If both of these things are
3316 /// true, consider using [`Float::rational_positive_difference_float`] instead.
3317 ///
3318 /// # Worst-case complexity
3319 /// $T(n) = O(n \log n \log\log n)$
3320 ///
3321 /// $M(n) = O(n)$
3322 ///
3323 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
3324 /// y.complexity(), prec)`.
3325 ///
3326 /// # Panics
3327 /// Panics if `prec` is zero, or if `rm` is `Exact` and the positive difference is not exactly
3328 /// representable with `prec` bits.
3329 ///
3330 /// # Examples
3331 /// ```
3332 /// use core::cmp::Ordering::*;
3333 /// use malachite_base::rounding_modes::RoundingMode::*;
3334 /// use malachite_float::Float;
3335 /// use malachite_q::Rational;
3336 ///
3337 /// let (d, o) = Float::rational_positive_difference_float_prec_round_ref_ref(
3338 /// &Rational::from_signeds(22, 7),
3339 /// &Float::from(3u32),
3340 /// 10,
3341 /// Floor,
3342 /// );
3343 /// assert_eq!(d.to_string(), "0.14282");
3344 /// assert_eq!(o, Less);
3345 /// ```
3346 pub fn rational_positive_difference_float_prec_round_ref_ref(
3347 x: &Rational,
3348 y: &Self,
3349 prec: u64,
3350 rm: RoundingMode,
3351 ) -> (Self, Ordering) {
3352 assert_ne!(prec, 0);
3353 if matches!(y.partial_cmp(x), Some(Less)) {
3354 // x - y = -(y - x), with the rounding mode reversed
3355 let (d, o) = y.sub_rational_prec_round_ref_ref(x, prec, -rm);
3356 (-d, o.reverse())
3357 } else if matches!(y, Self(NaN)) {
3358 (float_nan!(), Equal)
3359 } else {
3360 (Self::ZERO, Equal)
3361 }
3362 }
3363
3364 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
3365 /// $+0.0$ otherwise — rounding the result to the nearest value of the specified precision.
3366 /// The [`Rational`] and the [`Float`] are both taken by value. An [`Ordering`] is also
3367 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
3368 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
3369 /// this function returns a `NaN` it also returns `Equal`.
3370 ///
3371 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3372 /// before use, so the correct branch is always chosen and the winning difference is correctly
3373 /// rounded.
3374 ///
3375 /// Special cases:
3376 /// - $f(x,\text{NaN},p)=\text{NaN}$
3377 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
3378 /// - $f(x,-\infty,p)=\infty$
3379 ///
3380 /// $$
3381 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3382 /// $$
3383 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3384 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
3385 ///
3386 /// If you want to use a rounding mode other than `Nearest`, consider using
3387 /// [`Float::rational_positive_difference_float_prec_round`] instead. If you know that your
3388 /// target precision is the [`Float`]'s, consider using
3389 /// [`Float::rational_positive_difference_float`] instead.
3390 ///
3391 /// # Worst-case complexity
3392 /// $T(n) = O(n \log n \log\log n)$
3393 ///
3394 /// $M(n) = O(n)$
3395 ///
3396 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
3397 /// y.complexity(), prec)`.
3398 ///
3399 /// # Panics
3400 /// Panics if `prec` is zero.
3401 ///
3402 /// # Examples
3403 /// ```
3404 /// use core::cmp::Ordering::*;
3405 /// use malachite_float::Float;
3406 /// use malachite_q::Rational;
3407 ///
3408 /// let (d, o) = Float::rational_positive_difference_float_prec(
3409 /// Rational::from_signeds(22, 7),
3410 /// Float::from(3u32),
3411 /// 10,
3412 /// );
3413 /// assert_eq!(d.to_string(), "0.14282");
3414 /// assert_eq!(o, Less);
3415 /// ```
3416 #[inline]
3417 pub fn rational_positive_difference_float_prec(
3418 x: Rational,
3419 y: Self,
3420 prec: u64,
3421 ) -> (Self, Ordering) {
3422 Self::rational_positive_difference_float_prec_round(x, y, prec, Nearest)
3423 }
3424
3425 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
3426 /// $+0.0$ otherwise — rounding the result to the nearest value of the specified precision.
3427 /// The [`Rational`] is taken by value and the [`Float`] by reference. An [`Ordering`] is also
3428 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
3429 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
3430 /// this function returns a `NaN` it also returns `Equal`.
3431 ///
3432 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3433 /// before use, so the correct branch is always chosen and the winning difference is correctly
3434 /// rounded.
3435 ///
3436 /// Special cases:
3437 /// - $f(x,\text{NaN},p)=\text{NaN}$
3438 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
3439 /// - $f(x,-\infty,p)=\infty$
3440 ///
3441 /// $$
3442 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3443 /// $$
3444 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3445 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
3446 ///
3447 /// If you want to use a rounding mode other than `Nearest`, consider using
3448 /// [`Float::rational_positive_difference_float_prec_round`] instead. If you know that your
3449 /// target precision is the [`Float`]'s, consider using
3450 /// [`Float::rational_positive_difference_float`] instead.
3451 ///
3452 /// # Worst-case complexity
3453 /// $T(n) = O(n \log n \log\log n)$
3454 ///
3455 /// $M(n) = O(n)$
3456 ///
3457 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
3458 /// y.complexity(), prec)`.
3459 ///
3460 /// # Panics
3461 /// Panics if `prec` is zero.
3462 ///
3463 /// # Examples
3464 /// ```
3465 /// use core::cmp::Ordering::*;
3466 /// use malachite_float::Float;
3467 /// use malachite_q::Rational;
3468 ///
3469 /// let (d, o) = Float::rational_positive_difference_float_prec_val_ref(
3470 /// Rational::from_signeds(22, 7),
3471 /// &Float::from(3u32),
3472 /// 10,
3473 /// );
3474 /// assert_eq!(d.to_string(), "0.14282");
3475 /// assert_eq!(o, Less);
3476 /// ```
3477 #[inline]
3478 pub fn rational_positive_difference_float_prec_val_ref(
3479 x: Rational,
3480 y: &Self,
3481 prec: u64,
3482 ) -> (Self, Ordering) {
3483 Self::rational_positive_difference_float_prec_round_val_ref(x, y, prec, Nearest)
3484 }
3485
3486 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
3487 /// $+0.0$ otherwise — rounding the result to the nearest value of the specified precision.
3488 /// The [`Rational`] is taken by reference and the [`Float`] by value. An [`Ordering`] is also
3489 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
3490 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
3491 /// this function returns a `NaN` it also returns `Equal`.
3492 ///
3493 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3494 /// before use, so the correct branch is always chosen and the winning difference is correctly
3495 /// rounded.
3496 ///
3497 /// Special cases:
3498 /// - $f(x,\text{NaN},p)=\text{NaN}$
3499 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
3500 /// - $f(x,-\infty,p)=\infty$
3501 ///
3502 /// $$
3503 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3504 /// $$
3505 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3506 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
3507 ///
3508 /// If you want to use a rounding mode other than `Nearest`, consider using
3509 /// [`Float::rational_positive_difference_float_prec_round`] instead. If you know that your
3510 /// target precision is the [`Float`]'s, consider using
3511 /// [`Float::rational_positive_difference_float`] instead.
3512 ///
3513 /// # Worst-case complexity
3514 /// $T(n) = O(n \log n \log\log n)$
3515 ///
3516 /// $M(n) = O(n)$
3517 ///
3518 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
3519 /// y.complexity(), prec)`.
3520 ///
3521 /// # Panics
3522 /// Panics if `prec` is zero.
3523 ///
3524 /// # Examples
3525 /// ```
3526 /// use core::cmp::Ordering::*;
3527 /// use malachite_float::Float;
3528 /// use malachite_q::Rational;
3529 ///
3530 /// let (d, o) = Float::rational_positive_difference_float_prec_ref_val(
3531 /// &Rational::from_signeds(22, 7),
3532 /// Float::from(3u32),
3533 /// 10,
3534 /// );
3535 /// assert_eq!(d.to_string(), "0.14282");
3536 /// assert_eq!(o, Less);
3537 /// ```
3538 #[inline]
3539 pub fn rational_positive_difference_float_prec_ref_val(
3540 x: &Rational,
3541 y: Self,
3542 prec: u64,
3543 ) -> (Self, Ordering) {
3544 Self::rational_positive_difference_float_prec_round_ref_val(x, y, prec, Nearest)
3545 }
3546
3547 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
3548 /// $+0.0$ otherwise — rounding the result to the nearest value of the specified precision.
3549 /// The [`Rational`] and the [`Float`] are both taken by reference. An [`Ordering`] is also
3550 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
3551 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
3552 /// this function returns a `NaN` it also returns `Equal`.
3553 ///
3554 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3555 /// before use, so the correct branch is always chosen and the winning difference is correctly
3556 /// rounded.
3557 ///
3558 /// Special cases:
3559 /// - $f(x,\text{NaN},p)=\text{NaN}$
3560 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
3561 /// - $f(x,-\infty,p)=\infty$
3562 ///
3563 /// $$
3564 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3565 /// $$
3566 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3567 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
3568 ///
3569 /// If you want to use a rounding mode other than `Nearest`, consider using
3570 /// [`Float::rational_positive_difference_float_prec_round`] instead. If you know that your
3571 /// target precision is the [`Float`]'s, consider using
3572 /// [`Float::rational_positive_difference_float`] instead.
3573 ///
3574 /// # Worst-case complexity
3575 /// $T(n) = O(n \log n \log\log n)$
3576 ///
3577 /// $M(n) = O(n)$
3578 ///
3579 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
3580 /// y.complexity(), prec)`.
3581 ///
3582 /// # Panics
3583 /// Panics if `prec` is zero.
3584 ///
3585 /// # Examples
3586 /// ```
3587 /// use core::cmp::Ordering::*;
3588 /// use malachite_float::Float;
3589 /// use malachite_q::Rational;
3590 ///
3591 /// let (d, o) = Float::rational_positive_difference_float_prec_ref_ref(
3592 /// &Rational::from_signeds(22, 7),
3593 /// &Float::from(3u32),
3594 /// 10,
3595 /// );
3596 /// assert_eq!(d.to_string(), "0.14282");
3597 /// assert_eq!(o, Less);
3598 /// ```
3599 #[inline]
3600 pub fn rational_positive_difference_float_prec_ref_ref(
3601 x: &Rational,
3602 y: &Self,
3603 prec: u64,
3604 ) -> (Self, Ordering) {
3605 Self::rational_positive_difference_float_prec_round_ref_ref(x, y, prec, Nearest)
3606 }
3607
3608 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
3609 /// $+0.0$ otherwise — rounding the result to the [`Float`]'s precision, with the specified
3610 /// rounding mode. The [`Rational`] and the [`Float`] are both taken by value. An [`Ordering`]
3611 /// is also returned, indicating whether the rounded result is less than, equal to, or greater
3612 /// than the exact positive difference. Although `NaN`s are not comparable to any [`Float`],
3613 /// whenever this function returns a `NaN` it also returns `Equal`.
3614 ///
3615 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3616 /// before use, so the correct branch is always chosen and the winning difference is correctly
3617 /// rounded.
3618 ///
3619 /// Special cases:
3620 /// - $f(x,\text{NaN},p)=\text{NaN}$
3621 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
3622 /// - $f(x,-\infty,p)=\infty$
3623 ///
3624 /// $$
3625 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3626 /// $$
3627 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3628 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
3629 ///
3630 /// If you want to specify an output precision, consider using
3631 /// [`Float::rational_positive_difference_float_prec_round`] instead. If you know you'll be
3632 /// using the `Nearest` rounding mode, consider using
3633 /// [`Float::rational_positive_difference_float`] instead.
3634 ///
3635 /// # Worst-case complexity
3636 /// $T(n) = O(n \log n \log\log n)$
3637 ///
3638 /// $M(n) = O(n)$
3639 ///
3640 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
3641 /// y.complexity())`.
3642 ///
3643 /// # Panics
3644 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
3645 /// output precision.
3646 ///
3647 /// # Examples
3648 /// ```
3649 /// use core::cmp::Ordering::*;
3650 /// use malachite_base::rounding_modes::RoundingMode::*;
3651 /// use malachite_float::Float;
3652 /// use malachite_q::Rational;
3653 ///
3654 /// let (d, o) = Float::rational_positive_difference_float_round(
3655 /// Rational::from_signeds(22, 7),
3656 /// Float::from(3u32),
3657 /// Floor,
3658 /// );
3659 /// assert_eq!(d.to_string(), "0.12");
3660 /// assert_eq!(o, Less);
3661 /// ```
3662 #[inline]
3663 pub fn rational_positive_difference_float_round(
3664 x: Rational,
3665 y: Self,
3666 rm: RoundingMode,
3667 ) -> (Self, Ordering) {
3668 let prec = y.significant_bits();
3669 Self::rational_positive_difference_float_prec_round(x, y, prec, rm)
3670 }
3671
3672 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
3673 /// $+0.0$ otherwise — rounding the result to the [`Float`]'s precision, with the specified
3674 /// rounding mode. The [`Rational`] is taken by value and the [`Float`] by reference. An
3675 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
3676 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
3677 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3678 ///
3679 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3680 /// before use, so the correct branch is always chosen and the winning difference is correctly
3681 /// rounded.
3682 ///
3683 /// Special cases:
3684 /// - $f(x,\text{NaN},p)=\text{NaN}$
3685 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
3686 /// - $f(x,-\infty,p)=\infty$
3687 ///
3688 /// $$
3689 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3690 /// $$
3691 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3692 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
3693 ///
3694 /// If you want to specify an output precision, consider using
3695 /// [`Float::rational_positive_difference_float_prec_round`] instead. If you know you'll be
3696 /// using the `Nearest` rounding mode, consider using
3697 /// [`Float::rational_positive_difference_float`] instead.
3698 ///
3699 /// # Worst-case complexity
3700 /// $T(n) = O(n \log n \log\log n)$
3701 ///
3702 /// $M(n) = O(n)$
3703 ///
3704 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
3705 /// y.complexity())`.
3706 ///
3707 /// # Panics
3708 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
3709 /// output precision.
3710 ///
3711 /// # Examples
3712 /// ```
3713 /// use core::cmp::Ordering::*;
3714 /// use malachite_base::rounding_modes::RoundingMode::*;
3715 /// use malachite_float::Float;
3716 /// use malachite_q::Rational;
3717 ///
3718 /// let (d, o) = Float::rational_positive_difference_float_round_val_ref(
3719 /// Rational::from_signeds(22, 7),
3720 /// &Float::from(3u32),
3721 /// Floor,
3722 /// );
3723 /// assert_eq!(d.to_string(), "0.12");
3724 /// assert_eq!(o, Less);
3725 /// ```
3726 #[inline]
3727 pub fn rational_positive_difference_float_round_val_ref(
3728 x: Rational,
3729 y: &Self,
3730 rm: RoundingMode,
3731 ) -> (Self, Ordering) {
3732 let prec = y.significant_bits();
3733 Self::rational_positive_difference_float_prec_round_val_ref(x, y, prec, rm)
3734 }
3735
3736 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
3737 /// $+0.0$ otherwise — rounding the result to the [`Float`]'s precision, with the specified
3738 /// rounding mode. The [`Rational`] is taken by reference and the [`Float`] by value. An
3739 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
3740 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
3741 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3742 ///
3743 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3744 /// before use, so the correct branch is always chosen and the winning difference is correctly
3745 /// rounded.
3746 ///
3747 /// Special cases:
3748 /// - $f(x,\text{NaN},p)=\text{NaN}$
3749 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
3750 /// - $f(x,-\infty,p)=\infty$
3751 ///
3752 /// $$
3753 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3754 /// $$
3755 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3756 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
3757 ///
3758 /// If you want to specify an output precision, consider using
3759 /// [`Float::rational_positive_difference_float_prec_round`] instead. If you know you'll be
3760 /// using the `Nearest` rounding mode, consider using
3761 /// [`Float::rational_positive_difference_float`] instead.
3762 ///
3763 /// # Worst-case complexity
3764 /// $T(n) = O(n \log n \log\log n)$
3765 ///
3766 /// $M(n) = O(n)$
3767 ///
3768 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
3769 /// y.complexity())`.
3770 ///
3771 /// # Panics
3772 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
3773 /// output precision.
3774 ///
3775 /// # Examples
3776 /// ```
3777 /// use core::cmp::Ordering::*;
3778 /// use malachite_base::rounding_modes::RoundingMode::*;
3779 /// use malachite_float::Float;
3780 /// use malachite_q::Rational;
3781 ///
3782 /// let (d, o) = Float::rational_positive_difference_float_round_ref_val(
3783 /// &Rational::from_signeds(22, 7),
3784 /// Float::from(3u32),
3785 /// Floor,
3786 /// );
3787 /// assert_eq!(d.to_string(), "0.12");
3788 /// assert_eq!(o, Less);
3789 /// ```
3790 #[inline]
3791 pub fn rational_positive_difference_float_round_ref_val(
3792 x: &Rational,
3793 y: Self,
3794 rm: RoundingMode,
3795 ) -> (Self, Ordering) {
3796 let prec = y.significant_bits();
3797 Self::rational_positive_difference_float_prec_round_ref_val(x, y, prec, rm)
3798 }
3799
3800 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
3801 /// $+0.0$ otherwise — rounding the result to the [`Float`]'s precision, with the specified
3802 /// rounding mode. The [`Rational`] and the [`Float`] are both taken by reference. An
3803 /// [`Ordering`] is also returned, indicating whether the rounded result is less than, equal to,
3804 /// or greater than the exact positive difference. Although `NaN`s are not comparable to any
3805 /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
3806 ///
3807 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3808 /// before use, so the correct branch is always chosen and the winning difference is correctly
3809 /// rounded.
3810 ///
3811 /// Special cases:
3812 /// - $f(x,\text{NaN},p)=\text{NaN}$
3813 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
3814 /// - $f(x,-\infty,p)=\infty$
3815 ///
3816 /// $$
3817 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3818 /// $$
3819 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3820 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p+1}$.
3821 ///
3822 /// If you want to specify an output precision, consider using
3823 /// [`Float::rational_positive_difference_float_prec_round`] instead. If you know you'll be
3824 /// using the `Nearest` rounding mode, consider using
3825 /// [`Float::rational_positive_difference_float`] instead.
3826 ///
3827 /// # Worst-case complexity
3828 /// $T(n) = O(n \log n \log\log n)$
3829 ///
3830 /// $M(n) = O(n)$
3831 ///
3832 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
3833 /// y.complexity())`.
3834 ///
3835 /// # Panics
3836 /// Panics if `rm` is `Exact` and the positive difference is not exactly representable with the
3837 /// output precision.
3838 ///
3839 /// # Examples
3840 /// ```
3841 /// use core::cmp::Ordering::*;
3842 /// use malachite_base::rounding_modes::RoundingMode::*;
3843 /// use malachite_float::Float;
3844 /// use malachite_q::Rational;
3845 ///
3846 /// let (d, o) = Float::rational_positive_difference_float_round_ref_ref(
3847 /// &Rational::from_signeds(22, 7),
3848 /// &Float::from(3u32),
3849 /// Floor,
3850 /// );
3851 /// assert_eq!(d.to_string(), "0.12");
3852 /// assert_eq!(o, Less);
3853 /// ```
3854 #[inline]
3855 pub fn rational_positive_difference_float_round_ref_ref(
3856 x: &Rational,
3857 y: &Self,
3858 rm: RoundingMode,
3859 ) -> (Self, Ordering) {
3860 let prec = y.significant_bits();
3861 Self::rational_positive_difference_float_prec_round_ref_ref(x, y, prec, rm)
3862 }
3863
3864 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
3865 /// $+0.0$ otherwise — rounding the result to the nearest value of the [`Float`]'s precision.
3866 /// The [`Rational`] and the [`Float`] are both taken by value. An [`Ordering`] is also
3867 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
3868 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
3869 /// this function returns a `NaN` it also returns `Equal`.
3870 ///
3871 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3872 /// before use, so the correct branch is always chosen and the winning difference is correctly
3873 /// rounded.
3874 ///
3875 /// Special cases:
3876 /// - $f(x,\text{NaN},p)=\text{NaN}$
3877 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
3878 /// - $f(x,-\infty,p)=\infty$
3879 ///
3880 /// $$
3881 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3882 /// $$
3883 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3884 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
3885 ///
3886 /// If you want to specify an output precision, consider using
3887 /// [`Float::rational_positive_difference_float_prec`] instead. If you want to use a rounding
3888 /// mode other than `Nearest`, consider using
3889 /// [`Float::rational_positive_difference_float_round`] instead.
3890 ///
3891 /// # Worst-case complexity
3892 /// $T(n) = O(n \log n \log\log n)$
3893 ///
3894 /// $M(n) = O(n)$
3895 ///
3896 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
3897 /// y.complexity())`.
3898 ///
3899 /// # Examples
3900 /// ```
3901 /// use core::cmp::Ordering::*;
3902 /// use malachite_float::Float;
3903 /// use malachite_q::Rational;
3904 ///
3905 /// let (d, o) = Float::rational_positive_difference_float(
3906 /// Rational::from_signeds(22, 7),
3907 /// Float::from(3u32),
3908 /// );
3909 /// assert_eq!(d.to_string(), "0.12");
3910 /// assert_eq!(o, Less);
3911 /// ```
3912 #[inline]
3913 pub fn rational_positive_difference_float(x: Rational, y: Self) -> (Self, Ordering) {
3914 Self::rational_positive_difference_float_round(x, y, Nearest)
3915 }
3916
3917 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
3918 /// $+0.0$ otherwise — rounding the result to the nearest value of the [`Float`]'s precision.
3919 /// The [`Rational`] is taken by value and the [`Float`] by reference. An [`Ordering`] is also
3920 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
3921 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
3922 /// this function returns a `NaN` it also returns `Equal`.
3923 ///
3924 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3925 /// before use, so the correct branch is always chosen and the winning difference is correctly
3926 /// rounded.
3927 ///
3928 /// Special cases:
3929 /// - $f(x,\text{NaN},p)=\text{NaN}$
3930 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
3931 /// - $f(x,-\infty,p)=\infty$
3932 ///
3933 /// $$
3934 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3935 /// $$
3936 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3937 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
3938 ///
3939 /// If you want to specify an output precision, consider using
3940 /// [`Float::rational_positive_difference_float_prec`] instead. If you want to use a rounding
3941 /// mode other than `Nearest`, consider using
3942 /// [`Float::rational_positive_difference_float_round`] instead.
3943 ///
3944 /// # Worst-case complexity
3945 /// $T(n) = O(n \log n \log\log n)$
3946 ///
3947 /// $M(n) = O(n)$
3948 ///
3949 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
3950 /// y.complexity())`.
3951 ///
3952 /// # Examples
3953 /// ```
3954 /// use core::cmp::Ordering::*;
3955 /// use malachite_float::Float;
3956 /// use malachite_q::Rational;
3957 ///
3958 /// let (d, o) = Float::rational_positive_difference_float_val_ref(
3959 /// Rational::from_signeds(22, 7),
3960 /// &Float::from(3u32),
3961 /// );
3962 /// assert_eq!(d.to_string(), "0.12");
3963 /// assert_eq!(o, Less);
3964 /// ```
3965 #[inline]
3966 pub fn rational_positive_difference_float_val_ref(x: Rational, y: &Self) -> (Self, Ordering) {
3967 Self::rational_positive_difference_float_round_val_ref(x, y, Nearest)
3968 }
3969
3970 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
3971 /// $+0.0$ otherwise — rounding the result to the nearest value of the [`Float`]'s precision.
3972 /// The [`Rational`] is taken by reference and the [`Float`] by value. An [`Ordering`] is also
3973 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
3974 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
3975 /// this function returns a `NaN` it also returns `Equal`.
3976 ///
3977 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
3978 /// before use, so the correct branch is always chosen and the winning difference is correctly
3979 /// rounded.
3980 ///
3981 /// Special cases:
3982 /// - $f(x,\text{NaN},p)=\text{NaN}$
3983 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
3984 /// - $f(x,-\infty,p)=\infty$
3985 ///
3986 /// $$
3987 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
3988 /// $$
3989 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
3990 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
3991 ///
3992 /// If you want to specify an output precision, consider using
3993 /// [`Float::rational_positive_difference_float_prec`] instead. If you want to use a rounding
3994 /// mode other than `Nearest`, consider using
3995 /// [`Float::rational_positive_difference_float_round`] instead.
3996 ///
3997 /// # Worst-case complexity
3998 /// $T(n) = O(n \log n \log\log n)$
3999 ///
4000 /// $M(n) = O(n)$
4001 ///
4002 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
4003 /// y.complexity())`.
4004 ///
4005 /// # Examples
4006 /// ```
4007 /// use core::cmp::Ordering::*;
4008 /// use malachite_float::Float;
4009 /// use malachite_q::Rational;
4010 ///
4011 /// let (d, o) = Float::rational_positive_difference_float_ref_val(
4012 /// &Rational::from_signeds(22, 7),
4013 /// Float::from(3u32),
4014 /// );
4015 /// assert_eq!(d.to_string(), "0.12");
4016 /// assert_eq!(o, Less);
4017 /// ```
4018 #[inline]
4019 pub fn rational_positive_difference_float_ref_val(x: &Rational, y: Self) -> (Self, Ordering) {
4020 Self::rational_positive_difference_float_round_ref_val(x, y, Nearest)
4021 }
4022
4023 /// Computes the positive difference of a [`Rational`] and a [`Float`] — $x-y$ if $x>y$, and
4024 /// $+0.0$ otherwise — rounding the result to the nearest value of the [`Float`]'s precision.
4025 /// The [`Rational`] and the [`Float`] are both taken by reference. An [`Ordering`] is also
4026 /// returned, indicating whether the rounded result is less than, equal to, or greater than the
4027 /// exact positive difference. Although `NaN`s are not comparable to any [`Float`], whenever
4028 /// this function returns a `NaN` it also returns `Equal`.
4029 ///
4030 /// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
4031 /// before use, so the correct branch is always chosen and the winning difference is correctly
4032 /// rounded.
4033 ///
4034 /// Special cases:
4035 /// - $f(x,\text{NaN},p)=\text{NaN}$
4036 /// - $f(x,y,p)=+0.0$ if $x\leq y$, including against a zero of either sign
4037 /// - $f(x,-\infty,p)=\infty$
4038 ///
4039 /// $$
4040 /// f(x,y,p) = \begin{cases} x-y+\varepsilon & x>y \\\ +0.0 & \text{otherwise,} \end{cases}
4041 /// $$
4042 /// - If $x\leq y$ or the exact difference is representable, $\varepsilon$ is 0.
4043 /// - Otherwise, $|\varepsilon| < 2^{\lfloor\log_2 (x-y)\rfloor-p}$.
4044 ///
4045 /// If you want to specify an output precision, consider using
4046 /// [`Float::rational_positive_difference_float_prec`] instead. If you want to use a rounding
4047 /// mode other than `Nearest`, consider using
4048 /// [`Float::rational_positive_difference_float_round`] instead.
4049 ///
4050 /// # Worst-case complexity
4051 /// $T(n) = O(n \log n \log\log n)$
4052 ///
4053 /// $M(n) = O(n)$
4054 ///
4055 /// where $T$ is time, $M$ is additional memory, and $n$ is `max(x.significant_bits(),
4056 /// y.complexity())`.
4057 ///
4058 /// # Examples
4059 /// ```
4060 /// use core::cmp::Ordering::*;
4061 /// use malachite_float::Float;
4062 /// use malachite_q::Rational;
4063 ///
4064 /// let (d, o) = Float::rational_positive_difference_float_ref_ref(
4065 /// &Rational::from_signeds(22, 7),
4066 /// &Float::from(3u32),
4067 /// );
4068 /// assert_eq!(d.to_string(), "0.12");
4069 /// assert_eq!(o, Less);
4070 /// ```
4071 #[inline]
4072 pub fn rational_positive_difference_float_ref_ref(x: &Rational, y: &Self) -> (Self, Ordering) {
4073 Self::rational_positive_difference_float_round_ref_ref(x, y, Nearest)
4074 }
4075}
4076
4077/// Computes the positive difference of two primitive floats — $x-y$ if $x>y$, and $+0.0$
4078/// otherwise — using emulated [`Float`] arithmetic.
4079///
4080/// This is C's `fdim`, which the standard library does not provide. For finite operands the result
4081/// equals `x - y` when `x > y` (the primitive subtraction is already correctly rounded) and a
4082/// positive zero otherwise; a NaN input gives NaN.
4083///
4084/// # Worst-case complexity
4085/// Constant time and additional memory.
4086///
4087/// # Examples
4088/// ```
4089/// use malachite_base::num::float::NiceFloat;
4090/// use malachite_float::float::arithmetic::positive_difference::*;
4091///
4092/// assert_eq!(
4093/// NiceFloat(primitive_float_positive_difference(3.0, 1.0)),
4094/// NiceFloat(2.0)
4095/// );
4096/// assert_eq!(
4097/// NiceFloat(primitive_float_positive_difference(1.0, 3.0)),
4098/// NiceFloat(0.0)
4099/// );
4100/// ```
4101#[allow(clippy::type_repetition_in_bounds)]
4102#[inline]
4103pub fn primitive_float_positive_difference<T: PrimitiveFloat>(x: T, y: T) -> T
4104where
4105 Float: From<T> + PartialOrd<T>,
4106 for<'a> T: ExactFrom<&'a Float>,
4107{
4108 emulate_float_float_to_float_fn(Float::positive_difference_prec, x, y)
4109}
4110
4111/// Computes the positive difference of a primitive float and a [`Rational`] — $x-y$ if $x>y$, and
4112/// $+0.0$ otherwise — correctly rounding the result to the nearest value.
4113///
4114/// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
4115/// before use, so the correct branch is always chosen and the winning difference is correctly
4116/// rounded.
4117///
4118/// # Worst-case complexity
4119/// $T(n) = O(n \log n \log\log n)$
4120///
4121/// $M(n) = O(n)$
4122///
4123/// where $T$ is time, $M$ is additional memory, and $n$ is `y.significant_bits()`.
4124///
4125/// # Examples
4126/// ```
4127/// use malachite_base::num::float::NiceFloat;
4128/// use malachite_float::float::arithmetic::positive_difference::*;
4129/// use malachite_q::Rational;
4130///
4131/// let d = primitive_float_positive_difference_rational(3.0, &Rational::from_signeds(1, 3));
4132/// assert_eq!(NiceFloat(d), NiceFloat(2.6666666666666665));
4133/// ```
4134#[allow(clippy::type_repetition_in_bounds)]
4135#[inline]
4136pub fn primitive_float_positive_difference_rational<T: PrimitiveFloat>(x: T, y: &Rational) -> T
4137where
4138 Float: From<T> + PartialOrd<T>,
4139 for<'a> T: ExactFrom<&'a Float>,
4140{
4141 emulate_float_to_float_fn(
4142 |x, prec| Float::positive_difference_rational_prec_val_ref(x, y, prec),
4143 x,
4144 )
4145}
4146
4147/// Computes the positive difference of a [`Rational`] and a primitive float — $x-y$ if $x>y$, and
4148/// $+0.0$ otherwise — correctly rounding the result to the nearest value.
4149///
4150/// The comparison and the difference are both exact: the [`Rational`] operand is never rounded
4151/// before use, so the correct branch is always chosen and the winning difference is correctly
4152/// rounded.
4153///
4154/// # Worst-case complexity
4155/// $T(n) = O(n \log n \log\log n)$
4156///
4157/// $M(n) = O(n)$
4158///
4159/// where $T$ is time, $M$ is additional memory, and $n$ is `x.significant_bits()`.
4160///
4161/// # Examples
4162/// ```
4163/// use malachite_base::num::float::NiceFloat;
4164/// use malachite_float::float::arithmetic::positive_difference::*;
4165/// use malachite_q::Rational;
4166///
4167/// let d = primitive_float_rational_positive_difference_float(&Rational::from_signeds(22, 7), 3.0);
4168/// assert_eq!(NiceFloat(d), NiceFloat(0.14285714285714285));
4169/// ```
4170#[allow(clippy::type_repetition_in_bounds)]
4171#[inline]
4172pub fn primitive_float_rational_positive_difference_float<T: PrimitiveFloat>(
4173 x: &Rational,
4174 y: T,
4175) -> T
4176where
4177 Float: From<T> + PartialOrd<T>,
4178 for<'a> T: ExactFrom<&'a Float>,
4179{
4180 emulate_float_to_float_fn(
4181 |y, prec| Float::rational_positive_difference_float_prec_ref_val(x, y, prec),
4182 y,
4183 )
4184}