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