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