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