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