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