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