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