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