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