malachite_float/arithmetic/
mul.rs

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