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