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