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_either_infinity, float_either_zero, float_infinity, float_nan, float_negative_infinity,
12    float_negative_zero, float_zero, Float,
13};
14use core::cmp::{
15    max,
16    Ordering::{self, *},
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: ref mut x_sign,
1770                    exponent: ref mut x_exp,
1771                    precision: ref mut x_prec,
1772                    significand: ref mut 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 {
1898                    o
1899                } else {
1900                    o.reverse()
1901                }
1902            }
1903        }
1904    }
1905
1906    /// Multiplies a [`Float`] by a [`Float`] in place, rounding the result to the specified
1907    /// precision and with the specified rounding mode. The [`Float`] on the right-hand side is
1908    /// taken by reference. An [`Ordering`] is returned, indicating whether the rounded product is
1909    /// less than, equal to, or greater than the exact product. Although `NaN`s are not comparable
1910    /// to any [`Float`], whenever this function sets the [`Float`] to `NaN` it also returns
1911    /// `Equal`.
1912    ///
1913    /// See [`RoundingMode`] for a description of the possible rounding modes.
1914    ///
1915    /// $$
1916    /// x \gets xy+\varepsilon.
1917    /// $$
1918    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
1919    /// - If $xy$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
1920    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$.
1921    /// - If $xy$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
1922    ///   2^{\lfloor\log_2 |xy|\rfloor-p}$.
1923    ///
1924    /// If the output has a precision, it is `prec`.
1925    ///
1926    /// See the [`Float::mul_prec_round`] documentation for information on special cases, overflow,
1927    /// and underflow.
1928    ///
1929    /// If you know you'll be using `Nearest`, consider using [`Float::mul_prec_assign_ref`]
1930    /// instead. If you know that your target precision is the maximum of the precisions of the two
1931    /// inputs, consider using [`Float::mul_round_assign_ref`] instead. If both of these things are
1932    /// true, consider using `*=` instead.
1933    ///
1934    /// # Worst-case complexity
1935    /// $T(n, m) = O(n \log n \log\log n + m)$
1936    ///
1937    /// $M(n, m) = O(n \log n + m)$
1938    ///
1939    /// where $T$ is time, $M$ is additional memory, $n$ is `max(self.significant_bits(),
1940    /// other.significant_bits())`, and $m$ is `prec`.
1941    ///
1942    /// # Panics
1943    /// Panics if `rm` is `Exact` but `prec` is too small for an exact multiplication.
1944    ///
1945    /// # Examples
1946    /// ```
1947    /// use core::f64::consts::{E, PI};
1948    /// use malachite_base::rounding_modes::RoundingMode::*;
1949    /// use malachite_float::Float;
1950    /// use std::cmp::Ordering::*;
1951    ///
1952    /// let mut product = Float::from(PI);
1953    /// assert_eq!(
1954    ///     product.mul_prec_round_assign_ref(&Float::from(E), 5, Floor),
1955    ///     Less
1956    /// );
1957    /// assert_eq!(product.to_string(), "8.5");
1958    ///
1959    /// let mut product = Float::from(PI);
1960    /// assert_eq!(
1961    ///     product.mul_prec_round_assign_ref(&Float::from(E), 5, Ceiling),
1962    ///     Greater
1963    /// );
1964    /// assert_eq!(product.to_string(), "9.0");
1965    ///
1966    /// let mut product = Float::from(PI);
1967    /// assert_eq!(
1968    ///     product.mul_prec_round_assign_ref(&Float::from(E), 5, Nearest),
1969    ///     Less
1970    /// );
1971    /// assert_eq!(product.to_string(), "8.5");
1972    ///
1973    /// let mut product = Float::from(PI);
1974    /// assert_eq!(
1975    ///     product.mul_prec_round_assign_ref(&Float::from(E), 20, Floor),
1976    ///     Less
1977    /// );
1978    /// assert_eq!(product.to_string(), "8.53973");
1979    ///
1980    /// let mut product = Float::from(PI);
1981    /// assert_eq!(
1982    ///     product.mul_prec_round_assign_ref(&Float::from(E), 20, Ceiling),
1983    ///     Greater
1984    /// );
1985    /// assert_eq!(product.to_string(), "8.53975");
1986    ///
1987    /// let mut product = Float::from(PI);
1988    /// assert_eq!(
1989    ///     product.mul_prec_round_assign_ref(&Float::from(E), 20, Nearest),
1990    ///     Less
1991    /// );
1992    /// assert_eq!(product.to_string(), "8.53973");
1993    /// ```
1994    #[inline]
1995    pub fn mul_prec_round_assign_ref(
1996        &mut self,
1997        other: &Float,
1998        prec: u64,
1999        rm: RoundingMode,
2000    ) -> Ordering {
2001        assert_ne!(prec, 0);
2002        match (&mut *self, other) {
2003            (float_nan!(), _)
2004            | (_, float_nan!())
2005            | (float_either_infinity!(), float_either_zero!())
2006            | (float_either_zero!(), float_either_infinity!()) => {
2007                *self = float_nan!();
2008                Equal
2009            }
2010            (
2011                Float(Infinity { sign: x_sign }),
2012                Float(Finite { sign: y_sign, .. } | Infinity { sign: y_sign }),
2013            )
2014            | (Float(Finite { sign: x_sign, .. }), Float(Infinity { sign: y_sign })) => {
2015                *self = Float(Infinity {
2016                    sign: *x_sign == *y_sign,
2017                });
2018                Equal
2019            }
2020            (
2021                Float(Zero { sign: x_sign }),
2022                Float(Finite { sign: y_sign, .. } | Zero { sign: y_sign }),
2023            )
2024            | (Float(Finite { sign: x_sign, .. }), Float(Zero { sign: y_sign })) => {
2025                *self = Float(Zero {
2026                    sign: *x_sign == *y_sign,
2027                });
2028                Equal
2029            }
2030            (
2031                Float(Finite {
2032                    sign: ref mut x_sign,
2033                    exponent: ref mut x_exp,
2034                    precision: ref mut x_prec,
2035                    significand: ref mut x,
2036                }),
2037                Float(Finite {
2038                    sign: y_sign,
2039                    exponent: y_exp,
2040                    precision: y_prec,
2041                    significand: y,
2042                }),
2043            ) => {
2044                let sign = x_sign == y_sign;
2045                let exp_sum = *x_exp + y_exp;
2046                if exp_sum - 1 > Float::MAX_EXPONENT {
2047                    assert!(rm != Exact, "Inexact Float multiplication");
2048                    return match (sign, rm) {
2049                        (true, Ceiling | Up | Nearest) => {
2050                            *self = float_infinity!();
2051                            Greater
2052                        }
2053                        (true, _) => {
2054                            *self = Float::max_finite_value_with_prec(prec);
2055                            Less
2056                        }
2057                        (false, Floor | Up | Nearest) => {
2058                            *self = float_negative_infinity!();
2059                            Less
2060                        }
2061                        (false, _) => {
2062                            *self = -Float::max_finite_value_with_prec(prec);
2063                            Greater
2064                        }
2065                    };
2066                } else if exp_sum < Float::MIN_EXPONENT - 1 {
2067                    assert!(rm != Exact, "Inexact Float multiplication");
2068                    return match (sign, rm) {
2069                        (true, Floor | Down | Nearest) => {
2070                            *self = float_zero!();
2071                            Less
2072                        }
2073                        (true, _) => {
2074                            *self = Float::min_positive_value_prec(prec);
2075                            Greater
2076                        }
2077                        (false, Ceiling | Down | Nearest) => {
2078                            *self = float_negative_zero!();
2079                            Greater
2080                        }
2081                        (false, _) => {
2082                            *self = -Float::min_positive_value_prec(prec);
2083                            Less
2084                        }
2085                    };
2086                }
2087                let (exp_offset, o) = mul_float_significands_in_place_ref(
2088                    x,
2089                    *x_prec,
2090                    y,
2091                    *y_prec,
2092                    prec,
2093                    if sign { rm } else { -rm },
2094                );
2095                *x_exp = x_exp
2096                    .checked_add(*y_exp)
2097                    .unwrap()
2098                    .checked_add(exp_offset)
2099                    .unwrap();
2100                if *x_exp > Float::MAX_EXPONENT {
2101                    assert!(rm != Exact, "Inexact Float multiplication");
2102                    return match (sign, rm) {
2103                        (true, Ceiling | Up | Nearest) => {
2104                            *self = float_infinity!();
2105                            Greater
2106                        }
2107                        (true, _) => {
2108                            *self = Float::max_finite_value_with_prec(prec);
2109                            Less
2110                        }
2111                        (false, Floor | Up | Nearest) => {
2112                            *self = float_negative_infinity!();
2113                            Less
2114                        }
2115                        (false, _) => {
2116                            *self = -Float::max_finite_value_with_prec(prec);
2117                            Greater
2118                        }
2119                    };
2120                } else if *x_exp < Float::MIN_EXPONENT {
2121                    return if rm == Nearest
2122                        && *x_exp == Float::MIN_EXPONENT - 1
2123                        && (o == Less || !x.is_power_of_2())
2124                    {
2125                        if sign {
2126                            {
2127                                *self = Float::min_positive_value_prec(prec);
2128                                Greater
2129                            }
2130                        } else {
2131                            {
2132                                *self = -Float::min_positive_value_prec(prec);
2133                                Less
2134                            }
2135                        }
2136                    } else {
2137                        match (sign, rm) {
2138                            (_, Exact) => panic!("Inexact float multiplication"),
2139                            (true, Ceiling | Up) => {
2140                                *self = Float::min_positive_value_prec(prec);
2141                                Greater
2142                            }
2143                            (true, _) => {
2144                                *self = float_zero!();
2145                                Less
2146                            }
2147                            (false, Floor | Up) => {
2148                                *self = -Float::min_positive_value_prec(prec);
2149                                Less
2150                            }
2151                            (false, _) => {
2152                                *self = float_negative_zero!();
2153                                Greater
2154                            }
2155                        }
2156                    };
2157                }
2158                *x_sign = sign;
2159                *x_prec = prec;
2160                if sign {
2161                    o
2162                } else {
2163                    o.reverse()
2164                }
2165            }
2166        }
2167    }
2168
2169    /// Multiplies a [`Float`] by a [`Float`] in place, rounding the result to the nearest value of
2170    /// the specified precision. The [`Float`] on the right-hand side is taken by value. An
2171    /// [`Ordering`] is returned, indicating whether the rounded product is less than, equal to, or
2172    /// greater than the exact product. Although `NaN`s are not comparable to any [`Float`],
2173    /// whenever this function sets the [`Float`] to `NaN` it also returns `Equal`.
2174    ///
2175    /// If the product is equidistant from two [`Float`]s with the specified precision, the
2176    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2177    /// description of the `Nearest` rounding mode.
2178    ///
2179    /// $$
2180    /// x \gets xy+\varepsilon.
2181    /// $$
2182    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2183    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$.
2184    ///
2185    /// If the output has a precision, it is `prec`.
2186    ///
2187    /// See the [`Float::mul_prec`] documentation for information on special cases, overflow, and
2188    /// underflow.
2189    ///
2190    /// If you want to use a rounding mode other than `Nearest`, consider using
2191    /// [`Float::mul_prec_round_assign`] instead. If you know that your target precision is the
2192    /// maximum of the precisions of the two inputs, consider using `*=` instead.
2193    ///
2194    /// # Worst-case complexity
2195    /// $T(n, m) = O(n \log n \log\log n + m)$
2196    ///
2197    /// $M(n, m) = O(n \log n + m)$
2198    ///
2199    /// where $T$ is time, $M$ is additional memory, $n$ is `max(self.significant_bits(),
2200    /// other.significant_bits())`, and $m$ is `prec`.
2201    ///
2202    /// # Examples
2203    /// ```
2204    /// use core::f64::consts::{E, PI};
2205    /// use malachite_float::Float;
2206    /// use std::cmp::Ordering::*;
2207    ///
2208    /// let mut x = Float::from(PI);
2209    /// assert_eq!(x.mul_prec_assign(Float::from(E), 5), Less);
2210    /// assert_eq!(x.to_string(), "8.5");
2211    ///
2212    /// let mut x = Float::from(PI);
2213    /// assert_eq!(x.mul_prec_assign(Float::from(E), 20), Less);
2214    /// assert_eq!(x.to_string(), "8.53973");
2215    /// ```
2216    #[inline]
2217    pub fn mul_prec_assign(&mut self, other: Float, prec: u64) -> Ordering {
2218        self.mul_prec_round_assign(other, prec, Nearest)
2219    }
2220
2221    /// Multiplies a [`Float`] by a [`Float`] in place, rounding the result to the nearest value of
2222    /// the specified precision. The [`Float`] on the right-hand side is taken by reference. An
2223    /// [`Ordering`] is returned, indicating whether the rounded product is less than, equal to, or
2224    /// greater than the exact product. Although `NaN`s are not comparable to any [`Float`],
2225    /// whenever this function sets the [`Float`] to `NaN` it also returns `Equal`.
2226    ///
2227    /// If the product is equidistant from two [`Float`]s with the specified precision, the
2228    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2229    /// description of the `Nearest` rounding mode.
2230    ///
2231    /// $$
2232    /// x \gets xy+\varepsilon.
2233    /// $$
2234    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2235    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$.
2236    ///
2237    /// If the output has a precision, it is `prec`.
2238    ///
2239    /// See the [`Float::mul_prec`] documentation for information on special cases, overflow, and
2240    /// underflow.
2241    ///
2242    /// If you want to use a rounding mode other than `Nearest`, consider using
2243    /// [`Float::mul_prec_round_assign_ref`] instead. If you know that your target precision is the
2244    /// maximum of the precisions of the two inputs, consider using `*=` instead.
2245    ///
2246    /// # Worst-case complexity
2247    /// $T(n, m) = O(n \log n \log\log n + m)$
2248    ///
2249    /// $M(n, m) = O(n \log n + m)$
2250    ///
2251    /// where $T$ is time, $M$ is additional memory, $n$ is `max(self.significant_bits(),
2252    /// other.significant_bits())`, and $m$ is `prec`.
2253    ///
2254    /// # Examples
2255    /// ```
2256    /// use core::f64::consts::{E, PI};
2257    /// use malachite_float::Float;
2258    /// use std::cmp::Ordering::*;
2259    ///
2260    /// let mut x = Float::from(PI);
2261    /// assert_eq!(x.mul_prec_assign_ref(&Float::from(E), 5), Less);
2262    /// assert_eq!(x.to_string(), "8.5");
2263    ///
2264    /// let mut x = Float::from(PI);
2265    /// assert_eq!(x.mul_prec_assign_ref(&Float::from(E), 20), Less);
2266    /// assert_eq!(x.to_string(), "8.53973");
2267    /// ```
2268    #[inline]
2269    pub fn mul_prec_assign_ref(&mut self, other: &Float, prec: u64) -> Ordering {
2270        self.mul_prec_round_assign_ref(other, prec, Nearest)
2271    }
2272
2273    /// Multiplies a [`Float`] by a [`Float`] in place, rounding the result with the specified
2274    /// rounding mode. The [`Float`] on the right-hand side is taken by value. An [`Ordering`] is
2275    /// returned, indicating whether the rounded product is less than, equal to, or greater than the
2276    /// exact product. Although `NaN`s are not comparable to any [`Float`], whenever this function
2277    /// sets the [`Float`] to `NaN` it also returns `Equal`.
2278    ///
2279    /// The precision of the output is the maximum of the precision of the inputs. See
2280    /// [`RoundingMode`] for a description of the possible rounding modes.
2281    ///
2282    /// $$
2283    /// x \gets xy+\varepsilon.
2284    /// $$
2285    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2286    /// - If $xy$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2287    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
2288    /// - If $xy$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
2289    ///   2^{\lfloor\log_2 |xy|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
2290    ///
2291    /// If the output has a precision, it is the maximum of the precisions of the inputs.
2292    ///
2293    /// See the [`Float::mul_round`] documentation for information on special cases, overflow, and
2294    /// underflow.
2295    ///
2296    /// If you want to specify an output precision, consider using [`Float::mul_prec_round_assign`]
2297    /// instead. If you know you'll be using the `Nearest` rounding mode, consider using `*=`
2298    /// instead.
2299    ///
2300    /// # Worst-case complexity
2301    /// $T(n) = O(n \log n \log\log n)$
2302    ///
2303    /// $M(n) = O(n \log n)$
2304    ///
2305    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
2306    /// other.significant_bits())`.
2307    ///
2308    /// # Panics
2309    /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
2310    /// represent the output.
2311    ///
2312    /// # Examples
2313    /// ```
2314    /// use core::f64::consts::{E, PI};
2315    /// use malachite_base::rounding_modes::RoundingMode::*;
2316    /// use malachite_float::Float;
2317    /// use std::cmp::Ordering::*;
2318    ///
2319    /// let mut x = Float::from(PI);
2320    /// assert_eq!(x.mul_round_assign(Float::from(E), Floor), Less);
2321    /// assert_eq!(x.to_string(), "8.539734222673566");
2322    ///
2323    /// let mut x = Float::from(PI);
2324    /// assert_eq!(x.mul_round_assign(Float::from(E), Ceiling), Greater);
2325    /// assert_eq!(x.to_string(), "8.539734222673568");
2326    ///
2327    /// let mut x = Float::from(PI);
2328    /// assert_eq!(x.mul_round_assign(Float::from(E), Nearest), Less);
2329    /// assert_eq!(x.to_string(), "8.539734222673566");
2330    /// ```
2331    #[inline]
2332    pub fn mul_round_assign(&mut self, other: Float, rm: RoundingMode) -> Ordering {
2333        let prec = max(self.significant_bits(), other.significant_bits());
2334        self.mul_prec_round_assign(other, prec, rm)
2335    }
2336
2337    /// Multiplies a [`Float`] by a [`Float`] in place, rounding the result with the specified
2338    /// rounding mode. The [`Float`] on the right-hand side is taken by reference. An [`Ordering`]
2339    /// is returned, indicating whether the rounded product is less than, equal to, or greater than
2340    /// the exact product. Although `NaN`s are not comparable to any [`Float`], whenever this
2341    /// function sets the [`Float`] to `NaN` it also returns `Equal`.
2342    ///
2343    /// The precision of the output is the maximum of the precision of the inputs. See
2344    /// [`RoundingMode`] for a description of the possible rounding modes.
2345    ///
2346    /// $$
2347    /// x \gets xy+\varepsilon.
2348    /// $$
2349    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2350    /// - If $xy$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2351    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$, where $p$ is the maximum precision of the inputs.
2352    /// - If $xy$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
2353    ///   2^{\lfloor\log_2 |xy|\rfloor-p}$, where $p$ is the maximum precision of the inputs.
2354    ///
2355    /// If the output has a precision, it is the maximum of the precisions of the inputs.
2356    ///
2357    /// See the [`Float::mul_round`] documentation for information on special cases, overflow, and
2358    /// underflow.
2359    ///
2360    /// If you want to specify an output precision, consider using
2361    /// [`Float::mul_prec_round_assign_ref`] instead. If you know you'll be using the `Nearest`
2362    /// rounding mode, consider using `*=` instead.
2363    ///
2364    /// # Worst-case complexity
2365    /// $T(n) = O(n \log n \log\log n)$
2366    ///
2367    /// $M(n) = O(n \log n)$
2368    ///
2369    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
2370    /// other.significant_bits())`.
2371    ///
2372    /// # Panics
2373    /// Panics if `rm` is `Exact` but the maximum precision of the inputs is not high enough to
2374    /// represent the output.
2375    ///
2376    /// # Examples
2377    /// ```
2378    /// use core::f64::consts::{E, PI};
2379    /// use malachite_base::rounding_modes::RoundingMode::*;
2380    /// use malachite_float::Float;
2381    /// use std::cmp::Ordering::*;
2382    ///
2383    /// let mut x = Float::from(PI);
2384    /// assert_eq!(x.mul_round_assign_ref(&Float::from(E), Floor), Less);
2385    /// assert_eq!(x.to_string(), "8.539734222673566");
2386    ///
2387    /// let mut x = Float::from(PI);
2388    /// assert_eq!(x.mul_round_assign_ref(&Float::from(E), Ceiling), Greater);
2389    /// assert_eq!(x.to_string(), "8.539734222673568");
2390    ///
2391    /// let mut x = Float::from(PI);
2392    /// assert_eq!(x.mul_round_assign_ref(&Float::from(E), Nearest), Less);
2393    /// assert_eq!(x.to_string(), "8.539734222673566");
2394    /// ```
2395    #[inline]
2396    pub fn mul_round_assign_ref(&mut self, other: &Float, rm: RoundingMode) -> Ordering {
2397        let prec = max(self.significant_bits(), other.significant_bits());
2398        self.mul_prec_round_assign_ref(other, prec, rm)
2399    }
2400
2401    /// Multiplies a [`Float`] by a [`Rational`], rounding the result to the specified precision and
2402    /// with the specified rounding mode. The [`Float`] and the [`Rational`] are both taken by
2403    /// value. An [`Ordering`] is also returned, indicating whether the rounded product is less
2404    /// than, equal to, or greater than the exact product. Although `NaN`s are not comparable to any
2405    /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2406    ///
2407    /// See [`RoundingMode`] for a description of the possible rounding modes.
2408    ///
2409    /// $$
2410    /// f(x,y,p,m) = xy+\varepsilon.
2411    /// $$
2412    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2413    /// - If $xy$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2414    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$.
2415    /// - If $xy$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
2416    ///   2^{\lfloor\log_2 |xy|\rfloor-p}$.
2417    ///
2418    /// If the output has a precision, it is `prec`.
2419    ///
2420    /// Special cases:
2421    /// - $f(\text{NaN},x,p,m)=f(\pm\infty,0,p,m)=\text{NaN}$
2422    /// - $f(\infty,x,p,m)=\infty$ if $x>0$
2423    /// - $f(\infty,x,p,m)=-\infty$ if $x<0$
2424    /// - $f(-\infty,x,p,m)=-\infty$ if $x>0$
2425    /// - $f(-\infty,x,p,m)=\infty$ if $x<0$
2426    /// - $f(0.0,x,p,m)=0.0$ if $x\geq0$
2427    /// - $f(0.0,x,p,m)=-0.0$ if $x<0$
2428    /// - $f(-0.0,x,p,m)=-0.0$ if $x\geq0$
2429    /// - $f(-0.0,x,p,m)=0.0$ if $x<0$
2430    ///
2431    /// If you know you'll be using `Nearest`, consider using [`Float::mul_rational_prec`] instead.
2432    /// If you know that your target precision is the precision of the [`Float`] input, consider
2433    /// using [`Float::mul_rational_round`] instead. If both of these things are true, consider
2434    /// using `*` instead.
2435    ///
2436    /// # Worst-case complexity
2437    /// $T(n) = O(n \log n \log\log n)$
2438    ///
2439    /// $M(n) = O(n \log n)$
2440    ///
2441    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
2442    /// other.significant_bits(), prec)`.
2443    ///
2444    /// # Panics
2445    /// Panics if `rm` is `Exact` but `prec` is too small for an exact multiplication.
2446    ///
2447    /// # Examples
2448    /// ```
2449    /// use core::f64::consts::PI;
2450    /// use malachite_base::rounding_modes::RoundingMode::*;
2451    /// use malachite_float::Float;
2452    /// use malachite_q::Rational;
2453    /// use std::cmp::Ordering::*;
2454    ///
2455    /// let (product, o) =
2456    ///     Float::from(PI).mul_rational_prec_round(Rational::from_unsigneds(1u8, 3), 5, Floor);
2457    /// assert_eq!(product.to_string(), "1.0");
2458    /// assert_eq!(o, Less);
2459    ///
2460    /// let (product, o) =
2461    ///     Float::from(PI).mul_rational_prec_round(Rational::from_unsigneds(1u8, 3), 5, Ceiling);
2462    /// assert_eq!(product.to_string(), "1.06");
2463    /// assert_eq!(o, Greater);
2464    ///
2465    /// let (product, o) =
2466    ///     Float::from(PI).mul_rational_prec_round(Rational::from_unsigneds(1u8, 3), 5, Nearest);
2467    /// assert_eq!(product.to_string(), "1.06");
2468    /// assert_eq!(o, Greater);
2469    ///
2470    /// let (product, o) =
2471    ///     Float::from(PI).mul_rational_prec_round(Rational::from_unsigneds(1u8, 3), 20, Floor);
2472    /// assert_eq!(product.to_string(), "1.047197");
2473    /// assert_eq!(o, Less);
2474    ///
2475    /// let (product, o) =
2476    ///     Float::from(PI).mul_rational_prec_round(Rational::from_unsigneds(1u8, 3), 20, Ceiling);
2477    /// assert_eq!(product.to_string(), "1.047199");
2478    /// assert_eq!(o, Greater);
2479    ///
2480    /// let (product, o) =
2481    ///     Float::from(PI).mul_rational_prec_round(Rational::from_unsigneds(1u8, 3), 20, Nearest);
2482    /// assert_eq!(product.to_string(), "1.047197");
2483    /// assert_eq!(o, Less);
2484    /// ```
2485    #[inline]
2486    pub fn mul_rational_prec_round(
2487        mut self,
2488        other: Rational,
2489        prec: u64,
2490        rm: RoundingMode,
2491    ) -> (Float, Ordering) {
2492        let o = self.mul_rational_prec_round_assign(other, prec, rm);
2493        (self, o)
2494    }
2495
2496    /// Multiplies a [`Float`] by a [`Rational`], rounding the result to the specified precision and
2497    /// with the specified rounding mode. The [`Float`] is taken by value and the [`Rational`] by
2498    /// reference. An [`Ordering`] is also returned, indicating whether the rounded product is less
2499    /// than, equal to, or greater than the exact product. Although `NaN`s are not comparable to any
2500    /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2501    ///
2502    /// See [`RoundingMode`] for a description of the possible rounding modes.
2503    ///
2504    /// $$
2505    /// f(x,y,p,m) = xy+\varepsilon.
2506    /// $$
2507    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2508    /// - If $xy$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2509    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$.
2510    /// - If $xy$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
2511    ///   2^{\lfloor\log_2 |xy|\rfloor-p}$.
2512    ///
2513    /// If the output has a precision, it is `prec`.
2514    ///
2515    /// Special cases:
2516    /// - $f(\text{NaN},x,p,m)=f(\pm\infty,0,p,m)=\text{NaN}$
2517    /// - $f(\infty,x,p,m)=\infty$ if $x>0$
2518    /// - $f(\infty,x,p,m)=-\infty$ if $x<0$
2519    /// - $f(-\infty,x,p,m)=-\infty$ if $x>0$
2520    /// - $f(-\infty,x,p,m)=\infty$ if $x<0$
2521    /// - $f(0.0,x,p,m)=0.0$ if $x\geq0$
2522    /// - $f(0.0,x,p,m)=-0.0$ if $x<0$
2523    /// - $f(-0.0,x,p,m)=-0.0$ if $x\geq0$
2524    /// - $f(-0.0,x,p,m)=0.0$ if $x<0$
2525    ///
2526    /// If you know you'll be using `Nearest`, consider using [`Float::mul_rational_prec_val_ref`]
2527    /// instead. If you know that your target precision is the precision of the [`Float`] input,
2528    /// consider using [`Float::mul_rational_round_val_ref`] instead. If both of these things are
2529    /// true, consider using `*` instead.
2530    ///
2531    /// # Worst-case complexity
2532    /// $T(n) = O(n \log n \log\log n)$
2533    ///
2534    /// $M(n) = O(n \log n)$
2535    ///
2536    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
2537    /// other.significant_bits(), prec)`.
2538    ///
2539    /// # Panics
2540    /// Panics if `rm` is `Exact` but `prec` is too small for an exact multiplication.
2541    ///
2542    /// # Examples
2543    /// ```
2544    /// use core::f64::consts::PI;
2545    /// use malachite_base::rounding_modes::RoundingMode::*;
2546    /// use malachite_float::Float;
2547    /// use malachite_q::Rational;
2548    /// use std::cmp::Ordering::*;
2549    ///
2550    /// let (product, o) = Float::from(PI).mul_rational_prec_round_val_ref(
2551    ///     &Rational::from_unsigneds(1u8, 3),
2552    ///     5,
2553    ///     Floor,
2554    /// );
2555    /// assert_eq!(product.to_string(), "1.0");
2556    /// assert_eq!(o, Less);
2557    ///
2558    /// let (product, o) = Float::from(PI).mul_rational_prec_round_val_ref(
2559    ///     &Rational::from_unsigneds(1u8, 3),
2560    ///     5,
2561    ///     Ceiling,
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    ///     5,
2569    ///     Nearest,
2570    /// );
2571    /// assert_eq!(product.to_string(), "1.06");
2572    /// assert_eq!(o, Greater);
2573    ///
2574    /// let (product, o) = Float::from(PI).mul_rational_prec_round_val_ref(
2575    ///     &Rational::from_unsigneds(1u8, 3),
2576    ///     20,
2577    ///     Floor,
2578    /// );
2579    /// assert_eq!(product.to_string(), "1.047197");
2580    /// assert_eq!(o, Less);
2581    ///
2582    /// let (product, o) = Float::from(PI).mul_rational_prec_round_val_ref(
2583    ///     &Rational::from_unsigneds(1u8, 3),
2584    ///     20,
2585    ///     Ceiling,
2586    /// );
2587    /// assert_eq!(product.to_string(), "1.047199");
2588    /// assert_eq!(o, Greater);
2589    ///
2590    /// let (product, o) = Float::from(PI).mul_rational_prec_round_val_ref(
2591    ///     &Rational::from_unsigneds(1u8, 3),
2592    ///     20,
2593    ///     Nearest,
2594    /// );
2595    /// assert_eq!(product.to_string(), "1.047197");
2596    /// assert_eq!(o, Less);
2597    /// ```
2598    #[inline]
2599    pub fn mul_rational_prec_round_val_ref(
2600        mut self,
2601        other: &Rational,
2602        prec: u64,
2603        rm: RoundingMode,
2604    ) -> (Float, Ordering) {
2605        let o = self.mul_rational_prec_round_assign_ref(other, prec, rm);
2606        (self, o)
2607    }
2608
2609    /// Multiplies a [`Float`] by a [`Rational`], rounding the result to the specified precision and
2610    /// with the specified rounding mode. The [`Float`] is taken by reference and the [`Rational`]
2611    /// by value. An [`Ordering`] is also returned, indicating whether the rounded product is less
2612    /// than, equal to, or greater than the exact product. Although `NaN`s are not comparable to any
2613    /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2614    ///
2615    /// See [`RoundingMode`] for a description of the possible rounding modes.
2616    ///
2617    /// $$
2618    /// f(x,y,p,m) = xy+\varepsilon.
2619    /// $$
2620    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2621    /// - If $xy$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2622    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$.
2623    /// - If $xy$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
2624    ///   2^{\lfloor\log_2 |xy|\rfloor-p}$.
2625    ///
2626    /// If the output has a precision, it is `prec`.
2627    ///
2628    /// Special cases:
2629    /// - $f(\text{NaN},x,p,m)=f(\pm\infty,0,p,m)=\text{NaN}$
2630    /// - $f(\infty,x,p,m)=\infty$ if $x>0$
2631    /// - $f(\infty,x,p,m)=-\infty$ if $x<0$
2632    /// - $f(-\infty,x,p,m)=-\infty$ if $x>0$
2633    /// - $f(-\infty,x,p,m)=\infty$ if $x<0$
2634    /// - $f(0.0,x,p,m)=0.0$ if $x\geq0$
2635    /// - $f(0.0,x,p,m)=-0.0$ if $x<0$
2636    /// - $f(-0.0,x,p,m)=-0.0$ if $x\geq0$
2637    /// - $f(-0.0,x,p,m)=0.0$ if $x<0$
2638    ///
2639    /// If you know you'll be using `Nearest`, consider using [`Float::mul_rational_prec_ref_val`]
2640    /// instead. If you know that your target precision is the precision of the [`Float`] input,
2641    /// consider using [`Float::mul_rational_round_ref_val`] instead. If both of these things are
2642    /// true, consider using `*` instead.
2643    ///
2644    /// # Worst-case complexity
2645    /// $T(n) = O(n \log n \log\log n)$
2646    ///
2647    /// $M(n) = O(n \log n)$
2648    ///
2649    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
2650    /// other.significant_bits(), prec)`.
2651    ///
2652    /// # Panics
2653    /// Panics if `rm` is `Exact` but `prec` is too small for an exact multiplication.
2654    ///
2655    /// # Examples
2656    /// ```
2657    /// use core::f64::consts::PI;
2658    /// use malachite_base::rounding_modes::RoundingMode::*;
2659    /// use malachite_float::Float;
2660    /// use malachite_q::Rational;
2661    /// use std::cmp::Ordering::*;
2662    ///
2663    /// let (product, o) = Float::from(PI).mul_rational_prec_round_ref_val(
2664    ///     Rational::from_unsigneds(1u8, 3),
2665    ///     5,
2666    ///     Floor,
2667    /// );
2668    /// assert_eq!(product.to_string(), "1.0");
2669    /// assert_eq!(o, Less);
2670    ///
2671    /// let (product, o) = Float::from(PI).mul_rational_prec_round_ref_val(
2672    ///     Rational::from_unsigneds(1u8, 3),
2673    ///     5,
2674    ///     Ceiling,
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    ///     5,
2682    ///     Nearest,
2683    /// );
2684    /// assert_eq!(product.to_string(), "1.06");
2685    /// assert_eq!(o, Greater);
2686    ///
2687    /// let (product, o) = Float::from(PI).mul_rational_prec_round_ref_val(
2688    ///     Rational::from_unsigneds(1u8, 3),
2689    ///     20,
2690    ///     Floor,
2691    /// );
2692    /// assert_eq!(product.to_string(), "1.047197");
2693    /// assert_eq!(o, Less);
2694    ///
2695    /// let (product, o) = Float::from(PI).mul_rational_prec_round_ref_val(
2696    ///     Rational::from_unsigneds(1u8, 3),
2697    ///     20,
2698    ///     Ceiling,
2699    /// );
2700    /// assert_eq!(product.to_string(), "1.047199");
2701    /// assert_eq!(o, Greater);
2702    ///
2703    /// let (product, o) = Float::from(PI).mul_rational_prec_round_ref_val(
2704    ///     Rational::from_unsigneds(1u8, 3),
2705    ///     20,
2706    ///     Nearest,
2707    /// );
2708    /// assert_eq!(product.to_string(), "1.047197");
2709    /// assert_eq!(o, Less);
2710    /// ```
2711    #[inline]
2712    pub fn mul_rational_prec_round_ref_val(
2713        &self,
2714        other: Rational,
2715        prec: u64,
2716        rm: RoundingMode,
2717    ) -> (Float, Ordering) {
2718        if max(self.complexity(), other.significant_bits()) < MUL_RATIONAL_THRESHOLD {
2719            mul_rational_prec_round_naive_ref_val(self, other, prec, rm)
2720        } else {
2721            mul_rational_prec_round_direct_ref_val(self, other, prec, rm)
2722        }
2723    }
2724
2725    /// Multiplies a [`Float`] by a [`Rational`], rounding the result to the specified precision and
2726    /// with the specified rounding mode. The [`Float`] and the [`Rational`] are both taken by
2727    /// reference. An [`Ordering`] is also returned, indicating whether the rounded product is less
2728    /// than, equal to, or greater than the exact product. Although `NaN`s are not comparable to any
2729    /// [`Float`], whenever this function returns a `NaN` it also returns `Equal`.
2730    ///
2731    /// See [`RoundingMode`] for a description of the possible rounding modes.
2732    ///
2733    /// $$
2734    /// f(x,y,p,m) = xy+\varepsilon.
2735    /// $$
2736    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2737    /// - If $xy$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
2738    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$.
2739    /// - If $xy$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
2740    ///   2^{\lfloor\log_2 |xy|\rfloor-p}$.
2741    ///
2742    /// If the output has a precision, it is `prec`.
2743    ///
2744    /// Special cases:
2745    /// - $f(\text{NaN},x,p,m)=f(\pm\infty,0,p,m)=\text{NaN}$
2746    /// - $f(\infty,x,p,m)=\infty$ if $x>0$
2747    /// - $f(\infty,x,p,m)=-\infty$ if $x<0$
2748    /// - $f(-\infty,x,p,m)=-\infty$ if $x>0$
2749    /// - $f(-\infty,x,p,m)=\infty$ if $x<0$
2750    /// - $f(0.0,x,p,m)=0.0$ if $x\geq0$
2751    /// - $f(0.0,x,p,m)=-0.0$ if $x<0$
2752    /// - $f(-0.0,x,p,m)=-0.0$ if $x\geq0$
2753    /// - $f(-0.0,x,p,m)=0.0$ if $x<0$
2754    ///
2755    /// If you know you'll be using `Nearest`, consider using [`Float::mul_rational_prec_ref_ref`]
2756    /// instead. If you know that your target precision is the precision of the [`Float`] input,
2757    /// consider using [`Float::mul_rational_round_ref_ref`] instead. If both of these things are
2758    /// true, consider using `*` instead.
2759    ///
2760    /// # Worst-case complexity
2761    /// $T(n) = O(n \log n \log\log n)$
2762    ///
2763    /// $M(n) = O(n \log n)$
2764    ///
2765    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
2766    /// other.significant_bits(), prec)`.
2767    ///
2768    /// # Panics
2769    /// Panics if `rm` is `Exact` but `prec` is too small for an exact multiplication.
2770    ///
2771    /// # Examples
2772    /// ```
2773    /// use core::f64::consts::PI;
2774    /// use malachite_base::rounding_modes::RoundingMode::*;
2775    /// use malachite_float::Float;
2776    /// use malachite_q::Rational;
2777    /// use std::cmp::Ordering::*;
2778    ///
2779    /// let (product, o) = Float::from(PI).mul_rational_prec_round_ref_ref(
2780    ///     &Rational::from_unsigneds(1u8, 3),
2781    ///     5,
2782    ///     Floor,
2783    /// );
2784    /// assert_eq!(product.to_string(), "1.0");
2785    /// assert_eq!(o, Less);
2786    ///
2787    /// let (product, o) = Float::from(PI).mul_rational_prec_round_ref_ref(
2788    ///     &Rational::from_unsigneds(1u8, 3),
2789    ///     5,
2790    ///     Ceiling,
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    ///     5,
2798    ///     Nearest,
2799    /// );
2800    /// assert_eq!(product.to_string(), "1.06");
2801    /// assert_eq!(o, Greater);
2802    ///
2803    /// let (product, o) = Float::from(PI).mul_rational_prec_round_ref_ref(
2804    ///     &Rational::from_unsigneds(1u8, 3),
2805    ///     20,
2806    ///     Floor,
2807    /// );
2808    /// assert_eq!(product.to_string(), "1.047197");
2809    /// assert_eq!(o, Less);
2810    ///
2811    /// let (product, o) = Float::from(PI).mul_rational_prec_round_ref_ref(
2812    ///     &Rational::from_unsigneds(1u8, 3),
2813    ///     20,
2814    ///     Ceiling,
2815    /// );
2816    /// assert_eq!(product.to_string(), "1.047199");
2817    /// assert_eq!(o, Greater);
2818    ///
2819    /// let (product, o) = Float::from(PI).mul_rational_prec_round_ref_ref(
2820    ///     &Rational::from_unsigneds(1u8, 3),
2821    ///     20,
2822    ///     Nearest,
2823    /// );
2824    /// assert_eq!(product.to_string(), "1.047197");
2825    /// assert_eq!(o, Less);
2826    /// ```
2827    #[inline]
2828    pub fn mul_rational_prec_round_ref_ref(
2829        &self,
2830        other: &Rational,
2831        prec: u64,
2832        rm: RoundingMode,
2833    ) -> (Float, Ordering) {
2834        if max(self.complexity(), other.significant_bits()) < MUL_RATIONAL_THRESHOLD {
2835            mul_rational_prec_round_naive_ref_ref(self, other, prec, rm)
2836        } else {
2837            mul_rational_prec_round_direct_ref_ref(self, other, prec, rm)
2838        }
2839    }
2840
2841    /// Multiplies a [`Float`] by a [`Rational`], rounding the result to the nearest value of the
2842    /// specified precision. The [`Float`] and the [`Rational`] are both are taken by value. An
2843    /// [`Ordering`] is also returned, indicating whether the rounded product is less than, equal
2844    /// to, or greater than the exact product. Although `NaN`s are not comparable to any [`Float`],
2845    /// whenever this function returns a `NaN` it also returns `Equal`.
2846    ///
2847    /// If the product is equidistant from two [`Float`]s with the specified precision, the
2848    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2849    /// description of the `Nearest` rounding mode.
2850    ///
2851    /// $$
2852    /// f(x,y,p) = xy+\varepsilon.
2853    /// $$
2854    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2855    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$.
2856    ///
2857    /// If the output has a precision, it is `prec`.
2858    ///
2859    /// Special cases:
2860    /// - $f(\text{NaN},x,p)=f(\pm\infty,0,p)=\text{NaN}$
2861    /// - $f(\infty,x,p)=\infty$ if $x>0$
2862    /// - $f(\infty,x,p)=-\infty$ if $x<0$
2863    /// - $f(-\infty,x,p)=-\infty$ if $x>0$
2864    /// - $f(-\infty,x,p)=\infty$ if $x<0$
2865    /// - $f(0.0,x,p)=0.0$ if $x\geq0$
2866    /// - $f(0.0,x,p)=-0.0$ if $x<0$
2867    /// - $f(-0.0,x,p)=-0.0$ if $x\geq0$
2868    /// - $f(-0.0,x,p)=0.0$ if $x<0$
2869    ///
2870    /// If you want to use a rounding mode other than `Nearest`, consider using
2871    /// [`Float::mul_rational_prec_round`] instead. If you know that your target precision is the
2872    /// precision of the [`Float`] input, consider using `*` instead.
2873    ///
2874    /// # Worst-case complexity
2875    /// $T(n) = O(n \log n \log\log n)$
2876    ///
2877    /// $M(n) = O(n \log n)$
2878    ///
2879    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
2880    /// other.significant_bits(), prec)`.
2881    ///
2882    /// # Examples
2883    /// ```
2884    /// use core::f64::consts::PI;
2885    /// use malachite_base::num::conversion::traits::ExactFrom;
2886    /// use malachite_float::Float;
2887    /// use malachite_q::Rational;
2888    /// use std::cmp::Ordering::*;
2889    ///
2890    /// let (product, o) = Float::from(PI).mul_rational_prec(Rational::exact_from(1.5), 5);
2891    /// assert_eq!(product.to_string(), "4.8");
2892    /// assert_eq!(o, Greater);
2893    ///
2894    /// let (product, o) = Float::from(PI).mul_rational_prec(Rational::exact_from(1.5), 20);
2895    /// assert_eq!(product.to_string(), "4.712387");
2896    /// assert_eq!(o, Less);
2897    /// ```
2898    #[inline]
2899    pub fn mul_rational_prec(self, other: Rational, prec: u64) -> (Float, Ordering) {
2900        self.mul_rational_prec_round(other, prec, Nearest)
2901    }
2902
2903    /// Multiplies a [`Float`] by a [`Rational`], rounding the result to the nearest value of the
2904    /// specified precision. The [`Float`] is taken by value and the [`Rational`] by reference. An
2905    /// [`Ordering`] is also returned, indicating whether the rounded product is less than, equal
2906    /// to, or greater than the exact product. Although `NaN`s are not comparable to any [`Float`],
2907    /// whenever this function returns a `NaN` it also returns `Equal`.
2908    ///
2909    /// If the product is equidistant from two [`Float`]s with the specified precision, the
2910    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2911    /// description of the `Nearest` rounding mode.
2912    ///
2913    /// $$
2914    /// f(x,y,p) = xy+\varepsilon.
2915    /// $$
2916    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2917    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$.
2918    ///
2919    /// If the output has a precision, it is `prec`.
2920    ///
2921    /// Special cases:
2922    /// - $f(\text{NaN},x,p)=f(\pm\infty,0,p)=\text{NaN}$
2923    /// - $f(\infty,x,p)=\infty$ if $x>0$
2924    /// - $f(\infty,x,p)=-\infty$ if $x<0$
2925    /// - $f(-\infty,x,p)=-\infty$ if $x>0$
2926    /// - $f(-\infty,x,p)=\infty$ if $x<0$
2927    /// - $f(0.0,x,p)=0.0$ if $x\geq0$
2928    /// - $f(0.0,x,p)=-0.0$ if $x<0$
2929    /// - $f(-0.0,x,p)=-0.0$ if $x\geq0$
2930    /// - $f(-0.0,x,p)=0.0$ if $x<0$
2931    ///
2932    /// If you want to use a rounding mode other than `Nearest`, consider using
2933    /// [`Float::mul_rational_prec_round_val_ref`] instead. If you know that your target precision
2934    /// is the precision of the [`Float`] input, consider using `*` instead.
2935    ///
2936    /// # Worst-case complexity
2937    /// $T(n) = O(n \log n \log\log n)$
2938    ///
2939    /// $M(n) = O(n \log n)$
2940    ///
2941    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
2942    /// other.significant_bits(), prec)`.
2943    ///
2944    /// # Examples
2945    /// ```
2946    /// use core::f64::consts::PI;
2947    /// use malachite_base::num::conversion::traits::ExactFrom;
2948    /// use malachite_float::Float;
2949    /// use malachite_q::Rational;
2950    /// use std::cmp::Ordering::*;
2951    ///
2952    /// let (product, o) = Float::from(PI).mul_rational_prec_val_ref(&Rational::exact_from(1.5), 5);
2953    /// assert_eq!(product.to_string(), "4.8");
2954    /// assert_eq!(o, Greater);
2955    ///
2956    /// let (product, o) =
2957    ///     Float::from(PI).mul_rational_prec_val_ref(&Rational::exact_from(1.5), 20);
2958    /// assert_eq!(product.to_string(), "4.712387");
2959    /// assert_eq!(o, Less);
2960    /// ```
2961    #[inline]
2962    pub fn mul_rational_prec_val_ref(self, other: &Rational, prec: u64) -> (Float, Ordering) {
2963        self.mul_rational_prec_round_val_ref(other, prec, Nearest)
2964    }
2965
2966    /// Multiplies a [`Float`] by a [`Rational`], rounding the result to the nearest value of the
2967    /// specified precision. The [`Float`] is taken by reference and the [`Rational`] by value. An
2968    /// [`Ordering`] is also returned, indicating whether the rounded product is less than, equal
2969    /// to, or greater than the exact product. Although `NaN`s are not comparable to any [`Float`],
2970    /// whenever this function returns a `NaN` it also returns `Equal`.
2971    ///
2972    /// If the product is equidistant from two [`Float`]s with the specified precision, the
2973    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
2974    /// description of the `Nearest` rounding mode.
2975    ///
2976    /// $$
2977    /// f(x,y,p) = xy+\varepsilon.
2978    /// $$
2979    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
2980    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$.
2981    ///
2982    /// If the output has a precision, it is `prec`.
2983    ///
2984    /// Special cases:
2985    /// - $f(\text{NaN},x,p)=f(\pm\infty,0,p)=\text{NaN}$
2986    /// - $f(\infty,x,p)=\infty$ if $x>0$
2987    /// - $f(\infty,x,p)=-\infty$ if $x<0$
2988    /// - $f(-\infty,x,p)=-\infty$ if $x>0$
2989    /// - $f(-\infty,x,p)=\infty$ if $x<0$
2990    /// - $f(0.0,x,p)=0.0$ if $x\geq0$
2991    /// - $f(0.0,x,p)=-0.0$ if $x<0$
2992    /// - $f(-0.0,x,p)=-0.0$ if $x\geq0$
2993    /// - $f(-0.0,x,p)=0.0$ if $x<0$
2994    ///
2995    /// If you want to use a rounding mode other than `Nearest`, consider using
2996    /// [`Float::mul_rational_prec_round_ref_val`] instead. If you know that your target precision
2997    /// is the precision of the [`Float`] input, consider using `*` instead.
2998    ///
2999    /// # Worst-case complexity
3000    /// $T(n) = O(n \log n \log\log n)$
3001    ///
3002    /// $M(n) = O(n \log n)$
3003    ///
3004    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
3005    /// other.significant_bits(), prec)`.
3006    ///
3007    /// # Examples
3008    /// ```
3009    /// use core::f64::consts::PI;
3010    /// use malachite_base::num::conversion::traits::ExactFrom;
3011    /// use malachite_float::Float;
3012    /// use malachite_q::Rational;
3013    /// use std::cmp::Ordering::*;
3014    ///
3015    /// let (product, o) = Float::from(PI).mul_rational_prec_ref_val(Rational::exact_from(1.5), 5);
3016    /// assert_eq!(product.to_string(), "4.8");
3017    /// assert_eq!(o, Greater);
3018    ///
3019    /// let (product, o) = Float::from(PI).mul_rational_prec_ref_val(Rational::exact_from(1.5), 20);
3020    /// assert_eq!(product.to_string(), "4.712387");
3021    /// assert_eq!(o, Less);
3022    /// ```
3023    #[inline]
3024    pub fn mul_rational_prec_ref_val(&self, other: Rational, prec: u64) -> (Float, Ordering) {
3025        self.mul_rational_prec_round_ref_val(other, prec, Nearest)
3026    }
3027
3028    /// Multiplies a [`Float`] by a [`Rational`], rounding the result to the nearest value of the
3029    /// specified precision. The [`Float`] and the [`Rational`] are both are taken by reference. An
3030    /// [`Ordering`] is also returned, indicating whether the rounded product is less than, equal
3031    /// to, or greater than the exact product. Although `NaN`s are not comparable to any [`Float`],
3032    /// whenever this function returns a `NaN` it also returns `Equal`.
3033    ///
3034    /// If the product is equidistant from two [`Float`]s with the specified precision, the
3035    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
3036    /// description of the `Nearest` rounding mode.
3037    ///
3038    /// $$
3039    /// f(x,y,p) = xy+\varepsilon.
3040    /// $$
3041    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3042    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$.
3043    ///
3044    /// If the output has a precision, it is `prec`.
3045    ///
3046    /// Special cases:
3047    /// - $f(\text{NaN},x,p)=f(\pm\infty,0,p)=\text{NaN}$
3048    /// - $f(\infty,x,p)=\infty$ if $x>0$
3049    /// - $f(\infty,x,p)=-\infty$ if $x<0$
3050    /// - $f(-\infty,x,p)=-\infty$ if $x>0$
3051    /// - $f(-\infty,x,p)=\infty$ if $x<0$
3052    /// - $f(0.0,x,p)=0.0$ if $x\geq0$
3053    /// - $f(0.0,x,p)=-0.0$ if $x<0$
3054    /// - $f(-0.0,x,p)=-0.0$ if $x\geq0$
3055    /// - $f(-0.0,x,p)=0.0$ if $x<0$
3056    ///
3057    /// If you want to use a rounding mode other than `Nearest`, consider using
3058    /// [`Float::mul_rational_prec_round_ref_ref`] instead. If you know that your target precision
3059    /// is the precision of the [`Float`] input, consider using `*` instead.
3060    ///
3061    /// # Worst-case complexity
3062    /// $T(n) = O(n \log n \log\log n)$
3063    ///
3064    /// $M(n) = O(n \log n)$
3065    ///
3066    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
3067    /// other.significant_bits(), prec)`.
3068    ///
3069    /// # Examples
3070    /// ```
3071    /// use core::f64::consts::PI;
3072    /// use malachite_base::num::conversion::traits::ExactFrom;
3073    /// use malachite_float::Float;
3074    /// use malachite_q::Rational;
3075    /// use std::cmp::Ordering::*;
3076    ///
3077    /// let (product, o) = Float::from(PI).mul_rational_prec_ref_ref(&Rational::exact_from(1.5), 5);
3078    /// assert_eq!(product.to_string(), "4.8");
3079    /// assert_eq!(o, Greater);
3080    ///
3081    /// let (product, o) =
3082    ///     Float::from(PI).mul_rational_prec_ref_ref(&Rational::exact_from(1.5), 20);
3083    /// assert_eq!(product.to_string(), "4.712387");
3084    /// assert_eq!(o, Less);
3085    /// ```
3086    #[inline]
3087    pub fn mul_rational_prec_ref_ref(&self, other: &Rational, prec: u64) -> (Float, Ordering) {
3088        self.mul_rational_prec_round_ref_ref(other, prec, Nearest)
3089    }
3090
3091    /// Multiplies a [`Float`] by a [`Rational`], rounding the result with the specified rounding
3092    /// mode. The [`Float`] and the [`Rational`] are both are taken by value. An [`Ordering`] is
3093    /// also returned, indicating whether the rounded product is less than, equal to, or greater
3094    /// than the exact product. Although `NaN`s are not comparable to any [`Float`], whenever this
3095    /// function returns a `NaN` it also returns `Equal`.
3096    ///
3097    /// The precision of the output is the precision of the [`Float`] input. See [`RoundingMode`]
3098    /// for a description of the possible rounding modes.
3099    ///
3100    /// $$
3101    /// f(x,y,m) = xy+\varepsilon.
3102    /// $$
3103    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3104    /// - If $xy$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3105    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$, where $p$ is the precision of the input [`Float`].
3106    /// - If $xy$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
3107    ///   2^{\lfloor\log_2 |xy|\rfloor-p}$, where $p$ is the precision of the input [`Float`].
3108    ///
3109    /// If the output has a precision, it is the precision of the [`Float`] input.
3110    ///
3111    /// Special cases:
3112    /// - $f(\text{NaN},x,m)=f(\pm\infty,0,m)=\text{NaN}$
3113    /// - $f(\infty,x,m)=\infty$ if $x>0$
3114    /// - $f(\infty,x,m)=-\infty$ if $x<0$
3115    /// - $f(-\infty,x,m)=-\infty$ if $x>0$
3116    /// - $f(-\infty,x,m)=\infty$ if $x<0$
3117    /// - $f(0.0,x,m)=0.0$ if $x\geq0$
3118    /// - $f(0.0,x,m)=-0.0$ if $x<0$
3119    /// - $f(-0.0,x,m)=-0.0$ if $x\geq0$
3120    /// - $f(-0.0,x,m)=0.0$ if $x<0$
3121    ///
3122    /// If you want to specify an output precision, consider using
3123    /// [`Float::mul_rational_prec_round`] instead. If you know you'll be using the `Nearest`
3124    /// rounding mode, consider using `*` instead.
3125    ///
3126    /// # Worst-case complexity
3127    /// $T(n) = O(n \log n \log\log n)$
3128    ///
3129    /// $M(n) = O(n \log n)$
3130    ///
3131    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
3132    /// other.significant_bits())`.
3133    ///
3134    /// # Panics
3135    /// Panics if `rm` is `Exact` but the precision of the [`Float`] input is not high enough to
3136    /// represent the output.
3137    ///
3138    /// # Examples
3139    /// ```
3140    /// use core::f64::consts::PI;
3141    /// use malachite_base::rounding_modes::RoundingMode::*;
3142    /// use malachite_float::Float;
3143    /// use malachite_q::Rational;
3144    /// use std::cmp::Ordering::*;
3145    ///
3146    /// let (product, o) =
3147    ///     Float::from(PI).mul_rational_round(Rational::from_unsigneds(1u8, 3), Floor);
3148    /// assert_eq!(product.to_string(), "1.047197551196597");
3149    /// assert_eq!(o, Less);
3150    ///
3151    /// let (product, o) =
3152    ///     Float::from(PI).mul_rational_round(Rational::from_unsigneds(1u8, 3), Ceiling);
3153    /// assert_eq!(product.to_string(), "1.047197551196598");
3154    /// assert_eq!(o, Greater);
3155    ///
3156    /// let (product, o) =
3157    ///     Float::from(PI).mul_rational_round(Rational::from_unsigneds(1u8, 3), Nearest);
3158    /// assert_eq!(product.to_string(), "1.047197551196598");
3159    /// assert_eq!(o, Greater);
3160    /// ```
3161    #[inline]
3162    pub fn mul_rational_round(self, other: Rational, rm: RoundingMode) -> (Float, Ordering) {
3163        let prec = self.significant_bits();
3164        self.mul_rational_prec_round(other, prec, rm)
3165    }
3166
3167    /// Multiplies a [`Float`] by a [`Rational`], rounding the result with the specified rounding
3168    /// mode. The [`Float`] is taken by value and the [`Rational`] by reference. An [`Ordering`] is
3169    /// also returned, indicating whether the rounded product is less than, equal to, or greater
3170    /// than the exact product. Although `NaN`s are not comparable to any [`Float`], whenever this
3171    /// function returns a `NaN` it also returns `Equal`.
3172    ///
3173    /// The precision of the output is the precision of the [`Float`] input. See [`RoundingMode`]
3174    /// for a description of the possible rounding modes.
3175    ///
3176    /// $$
3177    /// f(x,y,m) = xy+\varepsilon.
3178    /// $$
3179    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3180    /// - If $xy$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3181    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$, where $p$ is the precision of the input [`Float`].
3182    /// - If $xy$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
3183    ///   2^{\lfloor\log_2 |xy|\rfloor-p}$, where $p$ is the precision of the input [`Float`].
3184    ///
3185    /// If the output has a precision, it is the precision of the [`Float`] input.
3186    ///
3187    /// Special cases:
3188    /// - $f(\text{NaN},x,m)=f(\pm\infty,0,m)=\text{NaN}$
3189    /// - $f(\infty,x,m)=\infty$ if $x>0$
3190    /// - $f(\infty,x,m)=-\infty$ if $x<0$
3191    /// - $f(-\infty,x,m)=-\infty$ if $x>0$
3192    /// - $f(-\infty,x,m)=\infty$ if $x<0$
3193    /// - $f(0.0,x,m)=0.0$ if $x\geq0$
3194    /// - $f(0.0,x,m)=-0.0$ if $x<0$
3195    /// - $f(-0.0,x,m)=-0.0$ if $x\geq0$
3196    /// - $f(-0.0,x,m)=0.0$ if $x<0$
3197    ///
3198    /// If you want to specify an output precision, consider using
3199    /// [`Float::mul_rational_prec_round_val_ref`] instead. If you know you'll be using the
3200    /// `Nearest` rounding mode, consider using `*` instead.
3201    ///
3202    /// # Worst-case complexity
3203    /// $T(n) = O(n \log n \log\log n)$
3204    ///
3205    /// $M(n) = O(n \log n)$
3206    ///
3207    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
3208    /// other.significant_bits())`.
3209    ///
3210    /// # Panics
3211    /// Panics if `rm` is `Exact` but the precision of the [`Float`] input is not high enough to
3212    /// represent the output.
3213    ///
3214    /// # Examples
3215    /// ```
3216    /// use core::f64::consts::PI;
3217    /// use malachite_base::rounding_modes::RoundingMode::*;
3218    /// use malachite_float::Float;
3219    /// use malachite_q::Rational;
3220    /// use std::cmp::Ordering::*;
3221    ///
3222    /// let (product, o) =
3223    ///     Float::from(PI).mul_rational_round_val_ref(&Rational::from_unsigneds(1u8, 3), Floor);
3224    /// assert_eq!(product.to_string(), "1.047197551196597");
3225    /// assert_eq!(o, Less);
3226    ///
3227    /// let (product, o) =
3228    ///     Float::from(PI).mul_rational_round_val_ref(&Rational::from_unsigneds(1u8, 3), Ceiling);
3229    /// assert_eq!(product.to_string(), "1.047197551196598");
3230    /// assert_eq!(o, Greater);
3231    ///
3232    /// let (product, o) =
3233    ///     Float::from(PI).mul_rational_round_val_ref(&Rational::from_unsigneds(1u8, 3), Nearest);
3234    /// assert_eq!(product.to_string(), "1.047197551196598");
3235    /// assert_eq!(o, Greater);
3236    /// ```
3237    #[inline]
3238    pub fn mul_rational_round_val_ref(
3239        self,
3240        other: &Rational,
3241        rm: RoundingMode,
3242    ) -> (Float, Ordering) {
3243        let prec = self.significant_bits();
3244        self.mul_rational_prec_round_val_ref(other, prec, rm)
3245    }
3246
3247    /// Multiplies a [`Float`] by a [`Rational`], rounding the result with the specified rounding
3248    /// mode. The [`Float`] is taken by reference and the [`Rational`] by value. An [`Ordering`] is
3249    /// also returned, indicating whether the rounded product is less than, equal to, or greater
3250    /// than the exact product. Although `NaN`s are not comparable to any [`Float`], whenever this
3251    /// function returns a `NaN` it also returns `Equal`.
3252    ///
3253    /// The precision of the output is the precision of the [`Float`] input. See [`RoundingMode`]
3254    /// for a description of the possible rounding modes.
3255    ///
3256    /// $$
3257    /// f(x,y,m) = xy+\varepsilon.
3258    /// $$
3259    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3260    /// - If $xy$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3261    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$, where $p$ is the precision of the input [`Float`].
3262    /// - If $xy$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
3263    ///   2^{\lfloor\log_2 |xy|\rfloor-p}$, where $p$ is the precision of the input [`Float`].
3264    ///
3265    /// If the output has a precision, it is the precision of the [`Float`] input.
3266    ///
3267    /// Special cases:
3268    /// - $f(\text{NaN},x,m)=f(\pm\infty,0,m)=\text{NaN}$
3269    /// - $f(\infty,x,m)=\infty$ if $x>0$
3270    /// - $f(\infty,x,m)=-\infty$ if $x<0$
3271    /// - $f(-\infty,x,m)=-\infty$ if $x>0$
3272    /// - $f(-\infty,x,m)=\infty$ if $x<0$
3273    /// - $f(0.0,x,m)=0.0$ if $x\geq0$
3274    /// - $f(0.0,x,m)=-0.0$ if $x<0$
3275    /// - $f(-0.0,x,m)=-0.0$ if $x\geq0$
3276    /// - $f(-0.0,x,m)=0.0$ if $x<0$
3277    ///
3278    /// If you want to specify an output precision, consider using
3279    /// [`Float::mul_rational_prec_round_ref_val`] instead. If you know you'll be using the
3280    /// `Nearest` rounding mode, consider using `*` instead.
3281    ///
3282    /// # Worst-case complexity
3283    /// $T(n) = O(n \log n \log\log n)$
3284    ///
3285    /// $M(n) = O(n \log n)$
3286    ///
3287    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
3288    /// other.significant_bits())`.
3289    ///
3290    /// # Panics
3291    /// Panics if `rm` is `Exact` but the precision of the [`Float`] input is not high enough to
3292    /// represent the output.
3293    ///
3294    /// # Examples
3295    /// ```
3296    /// use core::f64::consts::PI;
3297    /// use malachite_base::rounding_modes::RoundingMode::*;
3298    /// use malachite_float::Float;
3299    /// use malachite_q::Rational;
3300    /// use std::cmp::Ordering::*;
3301    ///
3302    /// let (product, o) =
3303    ///     Float::from(PI).mul_rational_round_ref_val(Rational::from_unsigneds(1u8, 3), Floor);
3304    /// assert_eq!(product.to_string(), "1.047197551196597");
3305    /// assert_eq!(o, Less);
3306    ///
3307    /// let (product, o) =
3308    ///     Float::from(PI).mul_rational_round_ref_val(Rational::from_unsigneds(1u8, 3), Ceiling);
3309    /// assert_eq!(product.to_string(), "1.047197551196598");
3310    /// assert_eq!(o, Greater);
3311    ///
3312    /// let (product, o) =
3313    ///     Float::from(PI).mul_rational_round_ref_val(Rational::from_unsigneds(1u8, 3), Nearest);
3314    /// assert_eq!(product.to_string(), "1.047197551196598");
3315    /// assert_eq!(o, Greater);
3316    /// ```
3317    #[inline]
3318    pub fn mul_rational_round_ref_val(
3319        &self,
3320        other: Rational,
3321        rm: RoundingMode,
3322    ) -> (Float, Ordering) {
3323        let prec = self.significant_bits();
3324        self.mul_rational_prec_round_ref_val(other, prec, rm)
3325    }
3326
3327    /// Multiplies a [`Float`] by a [`Rational`], rounding the result with the specified rounding
3328    /// mode. The [`Float`] and the [`Rational`] are both are taken by reference. An [`Ordering`] is
3329    /// also returned, indicating whether the rounded product is less than, equal to, or greater
3330    /// than the exact product. Although `NaN`s are not comparable to any [`Float`], whenever this
3331    /// function returns a `NaN` it also returns `Equal`.
3332    ///
3333    /// The precision of the output is the precision of the [`Float`] input. See [`RoundingMode`]
3334    /// for a description of the possible rounding modes.
3335    ///
3336    /// $$
3337    /// f(x,y,m) = xy+\varepsilon.
3338    /// $$
3339    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3340    /// - If $xy$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3341    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$, where $p$ is the precision of the input [`Float`].
3342    /// - If $xy$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
3343    ///   2^{\lfloor\log_2 |xy|\rfloor-p}$, where $p$ is the precision of the input [`Float`].
3344    ///
3345    /// If the output has a precision, it is the precision of the [`Float`] input.
3346    ///
3347    /// Special cases:
3348    /// - $f(\text{NaN},x,m)=f(\pm\infty,0,m)=\text{NaN}$
3349    /// - $f(\infty,x,m)=\infty$ if $x>0$
3350    /// - $f(\infty,x,m)=-\infty$ if $x<0$
3351    /// - $f(-\infty,x,m)=-\infty$ if $x>0$
3352    /// - $f(-\infty,x,m)=\infty$ if $x<0$
3353    /// - $f(0.0,x,m)=0.0$ if $x\geq0$
3354    /// - $f(0.0,x,m)=-0.0$ if $x<0$
3355    /// - $f(-0.0,x,m)=-0.0$ if $x\geq0$
3356    /// - $f(-0.0,x,m)=0.0$ if $x<0$
3357    ///
3358    /// If you want to specify an output precision, consider using
3359    /// [`Float::mul_rational_prec_round_ref_ref`] instead. If you know you'll be using the
3360    /// `Nearest` rounding mode, consider using `*` instead.
3361    ///
3362    /// # Worst-case complexity
3363    /// $T(n) = O(n \log n \log\log n)$
3364    ///
3365    /// $M(n) = O(n \log n)$
3366    ///
3367    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
3368    /// other.significant_bits())`.
3369    ///
3370    /// # Panics
3371    /// Panics if `rm` is `Exact` but the precision of the [`Float`] input is not high enough to
3372    /// represent the output.
3373    ///
3374    /// # Examples
3375    /// ```
3376    /// use core::f64::consts::PI;
3377    /// use malachite_base::rounding_modes::RoundingMode::*;
3378    /// use malachite_float::Float;
3379    /// use malachite_q::Rational;
3380    /// use std::cmp::Ordering::*;
3381    ///
3382    /// let (product, o) =
3383    ///     Float::from(PI).mul_rational_round_ref_ref(&Rational::from_unsigneds(1u8, 3), Floor);
3384    /// assert_eq!(product.to_string(), "1.047197551196597");
3385    /// assert_eq!(o, Less);
3386    ///
3387    /// let (product, o) =
3388    ///     Float::from(PI).mul_rational_round_ref_ref(&Rational::from_unsigneds(1u8, 3), Ceiling);
3389    /// assert_eq!(product.to_string(), "1.047197551196598");
3390    /// assert_eq!(o, Greater);
3391    ///
3392    /// let (product, o) =
3393    ///     Float::from(PI).mul_rational_round_ref_ref(&Rational::from_unsigneds(1u8, 3), Nearest);
3394    /// assert_eq!(product.to_string(), "1.047197551196598");
3395    /// assert_eq!(o, Greater);
3396    /// ```
3397    #[inline]
3398    pub fn mul_rational_round_ref_ref(
3399        &self,
3400        other: &Rational,
3401        rm: RoundingMode,
3402    ) -> (Float, Ordering) {
3403        let prec = self.significant_bits();
3404        self.mul_rational_prec_round_ref_ref(other, prec, rm)
3405    }
3406
3407    /// Multiplies a [`Float`] by a [`Rational`] in place, rounding the result to the specified
3408    /// precision and with the specified rounding mode. The [`Rational`] is taken by value. An
3409    /// [`Ordering`] is returned, indicating whether the rounded product is less than, equal to, or
3410    /// greater than the exact product. Although `NaN`s are not comparable to any [`Float`],
3411    /// whenever this function sets the [`Float`] to `NaN` it also returns `Equal`.
3412    ///
3413    /// See [`RoundingMode`] for a description of the possible rounding modes.
3414    ///
3415    /// $$
3416    /// x \gets xy+\varepsilon.
3417    /// $$
3418    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3419    /// - If $xy$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3420    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$.
3421    /// - If $xy$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
3422    ///   2^{\lfloor\log_2 |xy|\rfloor-p}$.
3423    ///
3424    /// If the output has a precision, it is `prec`.
3425    ///
3426    /// See the [`Float::mul_rational_prec_round`] documentation for information on special cases.
3427    ///
3428    /// If you know you'll be using `Nearest`, consider using [`Float::mul_rational_prec_assign`]
3429    /// instead. If you know that your target precision is the precision of the [`Float`] input,
3430    /// consider using [`Float::mul_rational_round_assign`] instead. If both of these things are
3431    /// true, consider using `*=` instead.
3432    ///
3433    /// # Worst-case complexity
3434    /// $T(n) = O(n \log n \log\log n)$
3435    ///
3436    /// $M(n) = O(n \log n)$
3437    ///
3438    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
3439    /// other.significant_bits(), prec)`.
3440    ///
3441    /// # Panics
3442    /// Panics if `rm` is `Exact` but `prec` is too small for an exact multiplication.
3443    ///
3444    /// # Examples
3445    /// ```
3446    /// use core::f64::consts::PI;
3447    /// use malachite_base::rounding_modes::RoundingMode::*;
3448    /// use malachite_float::Float;
3449    /// use malachite_q::Rational;
3450    /// use std::cmp::Ordering::*;
3451    ///
3452    /// let mut x = Float::from(PI);
3453    /// assert_eq!(
3454    ///     x.mul_rational_prec_round_assign(Rational::from_unsigneds(1u8, 3), 5, Floor),
3455    ///     Less
3456    /// );
3457    /// assert_eq!(x.to_string(), "1.0");
3458    ///
3459    /// let mut x = Float::from(PI);
3460    /// assert_eq!(
3461    ///     x.mul_rational_prec_round_assign(Rational::from_unsigneds(1u8, 3), 5, Ceiling),
3462    ///     Greater
3463    /// );
3464    /// assert_eq!(x.to_string(), "1.06");
3465    ///
3466    /// let mut x = Float::from(PI);
3467    /// assert_eq!(
3468    ///     x.mul_rational_prec_round_assign(Rational::from_unsigneds(1u8, 3), 5, Nearest),
3469    ///     Greater
3470    /// );
3471    /// assert_eq!(x.to_string(), "1.06");
3472    ///
3473    /// let mut x = Float::from(PI);
3474    /// assert_eq!(
3475    ///     x.mul_rational_prec_round_assign(Rational::from_unsigneds(1u8, 3), 20, Floor),
3476    ///     Less
3477    /// );
3478    /// assert_eq!(x.to_string(), "1.047197");
3479    ///
3480    /// let mut x = Float::from(PI);
3481    /// assert_eq!(
3482    ///     x.mul_rational_prec_round_assign(Rational::from_unsigneds(1u8, 3), 20, Ceiling),
3483    ///     Greater
3484    /// );
3485    /// assert_eq!(x.to_string(), "1.047199");
3486    ///
3487    /// let mut x = Float::from(PI);
3488    /// assert_eq!(
3489    ///     x.mul_rational_prec_round_assign(Rational::from_unsigneds(1u8, 3), 20, Nearest),
3490    ///     Less
3491    /// );
3492    /// assert_eq!(x.to_string(), "1.047197");
3493    /// ```
3494    #[inline]
3495    pub fn mul_rational_prec_round_assign(
3496        &mut self,
3497        other: Rational,
3498        prec: u64,
3499        rm: RoundingMode,
3500    ) -> Ordering {
3501        if max(self.complexity(), other.significant_bits()) < MUL_RATIONAL_THRESHOLD {
3502            mul_rational_prec_round_assign_naive(self, other, prec, rm)
3503        } else {
3504            mul_rational_prec_round_assign_direct(self, other, prec, rm)
3505        }
3506    }
3507
3508    /// Multiplies a [`Float`] by a [`Rational`] in place, rounding the result to the specified
3509    /// precision and with the specified rounding mode. The [`Rational`] is taken by reference. An
3510    /// [`Ordering`] is returned, indicating whether the rounded product is less than, equal to, or
3511    /// greater than the exact product. Although `NaN`s are not comparable to any [`Float`],
3512    /// whenever this function sets the [`Float`] to `NaN` it also returns `Equal`.
3513    ///
3514    /// See [`RoundingMode`] for a description of the possible rounding modes.
3515    ///
3516    /// $$
3517    /// x \gets xy+\varepsilon.
3518    /// $$
3519    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3520    /// - If $xy$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3521    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$.
3522    /// - If $xy$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
3523    ///   2^{\lfloor\log_2 |xy|\rfloor-p}$.
3524    ///
3525    /// If the output has a precision, it is `prec`.
3526    ///
3527    /// See the [`Float::mul_rational_prec_round`] documentation for information on special cases.
3528    ///
3529    /// If you know you'll be using `Nearest`, consider using
3530    /// [`Float::mul_rational_prec_assign_ref`] instead. If you know that your target precision is
3531    /// the precision of the [`Float`] input, consider using
3532    /// [`Float::mul_rational_round_assign_ref`] instead. If both of these things are true, consider
3533    /// using `*=` instead.
3534    ///
3535    /// # Worst-case complexity
3536    /// $T(n) = O(n \log n \log\log n)$
3537    ///
3538    /// $M(n) = O(n \log n)$
3539    ///
3540    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
3541    /// other.significant_bits(), prec)`.
3542    ///
3543    /// # Panics
3544    /// Panics if `rm` is `Exact` but `prec` is too small for an exact multiplication.
3545    ///
3546    /// # Examples
3547    /// ```
3548    /// use core::f64::consts::PI;
3549    /// use malachite_base::rounding_modes::RoundingMode::*;
3550    /// use malachite_float::Float;
3551    /// use malachite_q::Rational;
3552    /// use std::cmp::Ordering::*;
3553    ///
3554    /// let mut x = Float::from(PI);
3555    /// assert_eq!(
3556    ///     x.mul_rational_prec_round_assign_ref(&Rational::from_unsigneds(1u8, 3), 5, Floor),
3557    ///     Less
3558    /// );
3559    /// assert_eq!(x.to_string(), "1.0");
3560    ///
3561    /// let mut x = Float::from(PI);
3562    /// assert_eq!(
3563    ///     x.mul_rational_prec_round_assign_ref(&Rational::from_unsigneds(1u8, 3), 5, Ceiling),
3564    ///     Greater
3565    /// );
3566    /// assert_eq!(x.to_string(), "1.06");
3567    ///
3568    /// let mut x = Float::from(PI);
3569    /// assert_eq!(
3570    ///     x.mul_rational_prec_round_assign_ref(&Rational::from_unsigneds(1u8, 3), 5, Nearest),
3571    ///     Greater
3572    /// );
3573    /// assert_eq!(x.to_string(), "1.06");
3574    ///
3575    /// let mut x = Float::from(PI);
3576    /// assert_eq!(
3577    ///     x.mul_rational_prec_round_assign_ref(&Rational::from_unsigneds(1u8, 3), 20, Floor),
3578    ///     Less
3579    /// );
3580    /// assert_eq!(x.to_string(), "1.047197");
3581    ///
3582    /// let mut x = Float::from(PI);
3583    /// assert_eq!(
3584    ///     x.mul_rational_prec_round_assign_ref(&Rational::from_unsigneds(1u8, 3), 20, Ceiling),
3585    ///     Greater
3586    /// );
3587    /// assert_eq!(x.to_string(), "1.047199");
3588    ///
3589    /// let mut x = Float::from(PI);
3590    /// assert_eq!(
3591    ///     x.mul_rational_prec_round_assign_ref(&Rational::from_unsigneds(1u8, 3), 20, Nearest),
3592    ///     Less
3593    /// );
3594    /// assert_eq!(x.to_string(), "1.047197");
3595    /// ```
3596    #[inline]
3597    pub fn mul_rational_prec_round_assign_ref(
3598        &mut self,
3599        other: &Rational,
3600        prec: u64,
3601        rm: RoundingMode,
3602    ) -> Ordering {
3603        if max(self.complexity(), other.significant_bits()) < MUL_RATIONAL_THRESHOLD {
3604            mul_rational_prec_round_assign_naive_ref(self, other, prec, rm)
3605        } else {
3606            mul_rational_prec_round_assign_direct_ref(self, other, prec, rm)
3607        }
3608    }
3609
3610    /// Multiplies a [`Float`] by a [`Rational`] in place, rounding the result to the nearest value
3611    /// of the specified precision. The [`Rational`] is taken by value. An [`Ordering`] is returned,
3612    /// indicating whether the rounded product is less than, equal to, or greater than the exact
3613    /// product. Although `NaN`s are not comparable to any [`Float`], whenever this function sets
3614    /// the [`Float`] to `NaN` it also returns `Equal`.
3615    ///
3616    /// If the product is equidistant from two [`Float`]s with the specified precision, the
3617    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
3618    /// description of the `Nearest` rounding mode.
3619    ///
3620    /// $$
3621    /// x \gets xy+\varepsilon.
3622    /// $$
3623    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3624    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$.
3625    ///
3626    /// If the output has a precision, it is `prec`.
3627    ///
3628    /// See the [`Float::mul_rational_prec`] documentation for information on special cases.
3629    ///
3630    /// If you want to use a rounding mode other than `Nearest`, consider using
3631    /// [`Float::mul_rational_prec_round_assign`] instead. If you know that your target precision is
3632    /// the maximum of the precisions of the two inputs, consider using `*=` instead.
3633    ///
3634    /// # Worst-case complexity
3635    /// $T(n) = O(n \log n \log\log n)$
3636    ///
3637    /// $M(n) = O(n \log n)$
3638    ///
3639    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
3640    /// other.significant_bits(), prec)`.
3641    ///
3642    /// # Examples
3643    /// ```
3644    /// use core::f64::consts::PI;
3645    /// use malachite_base::num::conversion::traits::ExactFrom;
3646    /// use malachite_float::Float;
3647    /// use malachite_q::Rational;
3648    /// use std::cmp::Ordering::*;
3649    ///
3650    /// let mut x = Float::from(PI);
3651    /// assert_eq!(
3652    ///     x.mul_rational_prec_assign(Rational::exact_from(1.5), 5),
3653    ///     Greater
3654    /// );
3655    /// assert_eq!(x.to_string(), "4.8");
3656    ///
3657    /// let mut x = Float::from(PI);
3658    /// assert_eq!(
3659    ///     x.mul_rational_prec_assign(Rational::exact_from(1.5), 20),
3660    ///     Less
3661    /// );
3662    /// assert_eq!(x.to_string(), "4.712387");
3663    /// ```
3664    #[inline]
3665    pub fn mul_rational_prec_assign(&mut self, other: Rational, prec: u64) -> Ordering {
3666        self.mul_rational_prec_round_assign(other, prec, Nearest)
3667    }
3668
3669    /// Multiplies a [`Float`] by a [`Rational`] in place, rounding the result to the nearest value
3670    /// of the specified precision. The [`Rational`] is taken by reference. An [`Ordering`] is
3671    /// returned, indicating whether the rounded product is less than, equal to, or greater than the
3672    /// exact product. Although `NaN`s are not comparable to any [`Float`], whenever this function
3673    /// sets the [`Float`] to `NaN` it also returns `Equal`.
3674    ///
3675    /// If the product is equidistant from two [`Float`]s with the specified precision, the
3676    /// [`Float`] with fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a
3677    /// description of the `Nearest` rounding mode.
3678    ///
3679    /// $$
3680    /// x \gets xy+\varepsilon.
3681    /// $$
3682    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3683    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$.
3684    ///
3685    /// If the output has a precision, it is `prec`.
3686    ///
3687    /// See the [`Float::mul_rational_prec`] documentation for information on special cases.
3688    ///
3689    /// If you want to use a rounding mode other than `Nearest`, consider using
3690    /// [`Float::mul_rational_prec_round_assign`] instead. If you know that your target precision is
3691    /// the maximum of the precisions of the two inputs, consider using `*=` instead.
3692    ///
3693    /// # Worst-case complexity
3694    /// $T(n) = O(n \log n \log\log n)$
3695    ///
3696    /// $M(n) = O(n \log n)$
3697    ///
3698    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
3699    /// other.significant_bits(), prec)`.
3700    ///
3701    /// # Examples
3702    /// ```
3703    /// use core::f64::consts::PI;
3704    /// use malachite_base::num::conversion::traits::ExactFrom;
3705    /// use malachite_float::Float;
3706    /// use malachite_q::Rational;
3707    /// use std::cmp::Ordering::*;
3708    ///
3709    /// let mut x = Float::from(PI);
3710    /// assert_eq!(
3711    ///     x.mul_rational_prec_assign_ref(&Rational::exact_from(1.5), 5),
3712    ///     Greater
3713    /// );
3714    /// assert_eq!(x.to_string(), "4.8");
3715    ///
3716    /// let mut x = Float::from(PI);
3717    /// assert_eq!(
3718    ///     x.mul_rational_prec_assign_ref(&Rational::exact_from(1.5), 20),
3719    ///     Less
3720    /// );
3721    /// assert_eq!(x.to_string(), "4.712387");
3722    /// ```
3723    #[inline]
3724    pub fn mul_rational_prec_assign_ref(&mut self, other: &Rational, prec: u64) -> Ordering {
3725        self.mul_rational_prec_round_assign_ref(other, prec, Nearest)
3726    }
3727
3728    /// Multiplies a [`Float`] by a [`Rational`] in place, rounding the result with the specified
3729    /// rounding mode. The [`Rational`] is taken by value. An [`Ordering`] is returned, indicating
3730    /// whether the rounded product is less than, equal to, or greater than the exact product.
3731    /// Although `NaN`s are not comparable to any [`Float`], whenever this function sets the
3732    /// [`Float`] to `NaN` it also returns `Equal`.
3733    ///
3734    /// The precision of the output is the precision of the input [`Float`]. See [`RoundingMode`]
3735    /// for a description of the possible rounding modes.
3736    ///
3737    /// $$
3738    /// x \gets xy+\varepsilon.
3739    /// $$
3740    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3741    /// - If $xy$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3742    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$, where $p$ is the precision of the input [`Float`].
3743    /// - If $xy$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
3744    ///   2^{\lfloor\log_2 |xy|\rfloor-p}$, where $p$ is the precision of the input [`Float`].
3745    ///
3746    /// If the output has a precision, it is the precision of the input [`Float`].
3747    ///
3748    /// See the [`Float::mul_rational_round`] documentation for information on special cases.
3749    ///
3750    /// If you want to specify an output precision, consider using
3751    /// [`Float::mul_rational_prec_round_assign`] instead. If you know you'll be using the `Nearest`
3752    /// rounding mode, consider using `*=` instead.
3753    ///
3754    /// # Worst-case complexity
3755    /// $T(n) = O(n \log n \log\log n)$
3756    ///
3757    /// $M(n) = O(n \log n)$
3758    ///
3759    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
3760    /// other.significant_bits())`.
3761    ///
3762    /// # Panics
3763    /// Panics if `rm` is `Exact` but the precision of the input [`Float`] is not high enough to
3764    /// represent the output.
3765    ///
3766    /// # Examples
3767    /// ```
3768    /// use core::f64::consts::PI;
3769    /// use malachite_base::rounding_modes::RoundingMode::*;
3770    /// use malachite_float::Float;
3771    /// use malachite_q::Rational;
3772    /// use std::cmp::Ordering::*;
3773    ///
3774    /// let mut x = Float::from(PI);
3775    /// assert_eq!(
3776    ///     x.mul_rational_round_assign(Rational::from_unsigneds(1u8, 3), Floor),
3777    ///     Less
3778    /// );
3779    /// assert_eq!(x.to_string(), "1.047197551196597");
3780    ///
3781    /// let mut x = Float::from(PI);
3782    /// assert_eq!(
3783    ///     x.mul_rational_round_assign(Rational::from_unsigneds(1u8, 3), Ceiling),
3784    ///     Greater
3785    /// );
3786    /// assert_eq!(x.to_string(), "1.047197551196598");
3787    ///
3788    /// let mut x = Float::from(PI);
3789    /// assert_eq!(
3790    ///     x.mul_rational_round_assign(Rational::from_unsigneds(1u8, 3), Nearest),
3791    ///     Greater
3792    /// );
3793    /// assert_eq!(x.to_string(), "1.047197551196598");
3794    /// ```
3795    #[inline]
3796    pub fn mul_rational_round_assign(&mut self, other: Rational, rm: RoundingMode) -> Ordering {
3797        let prec = self.significant_bits();
3798        self.mul_rational_prec_round_assign(other, prec, rm)
3799    }
3800
3801    /// Multiplies a [`Float`] by a [`Rational`] in place, rounding the result with the specified
3802    /// rounding mode. The [`Rational`] is taken by reference. An [`Ordering`] is returned,
3803    /// indicating whether the rounded product is less than, equal to, or greater than the exact
3804    /// product. Although `NaN`s are not comparable to any [`Float`], whenever this function sets
3805    /// the [`Float`] to `NaN` it also returns `Equal`.
3806    ///
3807    /// The precision of the output is the precision of the input [`Float`]. See [`RoundingMode`]
3808    /// for a description of the possible rounding modes.
3809    ///
3810    /// $$
3811    /// x \gets xy+\varepsilon.
3812    /// $$
3813    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3814    /// - If $xy$ is finite and nonzero, and $m$ is not `Nearest`, then $|\varepsilon| <
3815    ///   2^{\lfloor\log_2 |xy|\rfloor-p+1}$, where $p$ is the precision of the input [`Float`].
3816    /// - If $xy$ is finite and nonzero, and $m$ is `Nearest`, then $|\varepsilon| <
3817    ///   2^{\lfloor\log_2 |xy|\rfloor-p}$, where $p$ is the precision of the input [`Float`].
3818    ///
3819    /// If the output has a precision, it is the precision of the input [`Float`].
3820    ///
3821    /// See the [`Float::mul_rational_round`] documentation for information on special cases.
3822    ///
3823    /// If you want to specify an output precision, consider using
3824    /// [`Float::mul_rational_prec_round_assign`] instead. If you know you'll be using the `Nearest`
3825    /// rounding mode, consider using `*=` instead.
3826    ///
3827    /// # Worst-case complexity
3828    /// $T(n) = O(n \log n \log\log n)$
3829    ///
3830    /// $M(n) = O(n \log n)$
3831    ///
3832    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
3833    /// other.significant_bits())`.
3834    ///
3835    /// # Panics
3836    /// Panics if `rm` is `Exact` but the precision of the input [`Float`] is not high enough to
3837    /// represent the output.
3838    ///
3839    /// # Examples
3840    /// ```
3841    /// use core::f64::consts::PI;
3842    /// use malachite_base::rounding_modes::RoundingMode::*;
3843    /// use malachite_float::Float;
3844    /// use malachite_q::Rational;
3845    /// use std::cmp::Ordering::*;
3846    ///
3847    /// let mut x = Float::from(PI);
3848    /// assert_eq!(
3849    ///     x.mul_rational_round_assign_ref(&Rational::from_unsigneds(1u8, 3), Floor),
3850    ///     Less
3851    /// );
3852    /// assert_eq!(x.to_string(), "1.047197551196597");
3853    ///
3854    /// let mut x = Float::from(PI);
3855    /// assert_eq!(
3856    ///     x.mul_rational_round_assign_ref(&Rational::from_unsigneds(1u8, 3), Ceiling),
3857    ///     Greater
3858    /// );
3859    /// assert_eq!(x.to_string(), "1.047197551196598");
3860    ///
3861    /// let mut x = Float::from(PI);
3862    /// assert_eq!(
3863    ///     x.mul_rational_round_assign_ref(&Rational::from_unsigneds(1u8, 3), Nearest),
3864    ///     Greater
3865    /// );
3866    /// assert_eq!(x.to_string(), "1.047197551196598");
3867    /// ```
3868    #[inline]
3869    pub fn mul_rational_round_assign_ref(
3870        &mut self,
3871        other: &Rational,
3872        rm: RoundingMode,
3873    ) -> Ordering {
3874        let prec = self.significant_bits();
3875        self.mul_rational_prec_round_assign_ref(other, prec, rm)
3876    }
3877}
3878
3879impl Mul<Float> for Float {
3880    type Output = Float;
3881
3882    /// Multiplies two [`Float`]s, taking both by value.
3883    ///
3884    /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
3885    /// product is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
3886    /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
3887    /// `Nearest` rounding mode.
3888    ///
3889    /// $$
3890    /// f(x,y) = xy+\varepsilon.
3891    /// $$
3892    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3893    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
3894    ///   where $p$ is the maximum precision of the inputs.
3895    ///
3896    /// Special cases:
3897    /// - $f(\text{NaN},x)=f(x,\text{NaN})=f(\pm\infty,\pm0.0)=f(\pm0.0,\pm\infty) = \text{NaN}$
3898    /// - $f(\infty,x)=f(x,\infty)=\infty$ if $x>0.0$
3899    /// - $f(\infty,x)=f(x,\infty)=-\infty$ if $x<0.0$
3900    /// - $f(-\infty,x)=f(x,-\infty)=-\infty$ if $x>0.0$
3901    /// - $f(-\infty,x)=f(x,-\infty)=\infty$ if $x<0.0$
3902    /// - $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$
3903    /// - $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$
3904    /// - $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$
3905    /// - $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$
3906    ///
3907    /// Overflow and underflow:
3908    /// - If $f(x,y)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
3909    /// - If $f(x,y)\geq 2^{2^{30}-1}$, $-\infty$ is returned instead.
3910    /// - If $0<f(x,y)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
3911    /// - If $2^{-2^{30}-1}<f(x,y)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
3912    /// - If $-2^{-2^{30}-1}\leq f(x,y)<0$, $-0.0$ is returned instead.
3913    /// - If $-2^{-2^{30}}<f(x,y)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
3914    ///
3915    /// If you want to use a rounding mode other than `Nearest`, consider using [`Float::mul_prec`]
3916    /// instead. If you want to specify the output precision, consider using [`Float::mul_round`].
3917    /// If you want both of these things, consider using [`Float::mul_prec_round`].
3918    ///
3919    /// # Worst-case complexity
3920    /// $T(n) = O(n \log n \log\log n)$
3921    ///
3922    /// $M(n) = O(n \log n)$
3923    ///
3924    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
3925    /// other.significant_bits())`.
3926    ///
3927    /// # Examples
3928    /// ```
3929    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
3930    /// use malachite_float::Float;
3931    ///
3932    /// assert!((Float::from(1.5) * Float::NAN).is_nan());
3933    /// assert_eq!(Float::from(1.5) * Float::INFINITY, Float::INFINITY);
3934    /// assert_eq!(
3935    ///     Float::from(1.5) * Float::NEGATIVE_INFINITY,
3936    ///     Float::NEGATIVE_INFINITY
3937    /// );
3938    /// assert_eq!(
3939    ///     Float::from(-1.5) * Float::INFINITY,
3940    ///     Float::NEGATIVE_INFINITY
3941    /// );
3942    /// assert_eq!(
3943    ///     Float::from(-1.5) * Float::NEGATIVE_INFINITY,
3944    ///     Float::INFINITY
3945    /// );
3946    /// assert!((Float::INFINITY * Float::ZERO).is_nan());
3947    ///
3948    /// assert_eq!(Float::from(1.5) * Float::from(2.5), 4.0);
3949    /// assert_eq!(Float::from(1.5) * Float::from(-2.5), -4.0);
3950    /// assert_eq!(Float::from(-1.5) * Float::from(2.5), -4.0);
3951    /// assert_eq!(Float::from(-1.5) * Float::from(-2.5), 4.0);
3952    /// ```
3953    #[inline]
3954    fn mul(self, other: Float) -> Float {
3955        let prec = max(self.significant_bits(), other.significant_bits());
3956        self.mul_prec_round(other, prec, Nearest).0
3957    }
3958}
3959
3960impl Mul<&Float> for Float {
3961    type Output = Float;
3962
3963    /// Multiplies two [`Float`]s, taking the first by value and the second by reference.
3964    ///
3965    /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
3966    /// product is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
3967    /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
3968    /// `Nearest` rounding mode.
3969    ///
3970    /// $$
3971    /// f(x,y) = xy+\varepsilon.
3972    /// $$
3973    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
3974    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
3975    ///   where $p$ is the maximum precision of the inputs.
3976    ///
3977    /// Special cases:
3978    /// - $f(\text{NaN},x)=f(x,\text{NaN})=f(\pm\infty,\pm0.0)=f(\pm0.0,\pm\infty) = \text{NaN}$
3979    /// - $f(\infty,x)=f(x,\infty)=\infty$ if $x>0.0$
3980    /// - $f(\infty,x)=f(x,\infty)=-\infty$ if $x<0.0$
3981    /// - $f(-\infty,x)=f(x,-\infty)=-\infty$ if $x>0.0$
3982    /// - $f(-\infty,x)=f(x,-\infty)=\infty$ if $x<0.0$
3983    /// - $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$
3984    /// - $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$
3985    /// - $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$
3986    /// - $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$
3987    ///
3988    /// Overflow and underflow:
3989    /// - If $f(x,y)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
3990    /// - If $f(x,y)\geq 2^{2^{30}-1}$, $-\infty$ is returned instead.
3991    /// - If $0<f(x,y)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
3992    /// - If $2^{-2^{30}-1}<f(x,y)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
3993    /// - If $-2^{-2^{30}-1}\leq f(x,y)<0$, $-0.0$ is returned instead.
3994    /// - If $-2^{-2^{30}}<f(x,y)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
3995    ///
3996    /// If you want to use a rounding mode other than `Nearest`, consider using
3997    /// [`Float::mul_prec_val_ref`] instead. If you want to specify the output precision, consider
3998    /// using [`Float::mul_round_val_ref`]. If you want both of these things, consider using
3999    /// [`Float::mul_prec_round_val_ref`].
4000    ///
4001    /// # Worst-case complexity
4002    /// $T(n) = O(n \log n \log\log n)$
4003    ///
4004    /// $M(n) = O(n \log n)$
4005    ///
4006    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
4007    /// other.significant_bits())`.
4008    ///
4009    /// # Examples
4010    /// ```
4011    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
4012    /// use malachite_float::Float;
4013    ///
4014    /// assert!((Float::from(1.5) * &Float::NAN).is_nan());
4015    /// assert_eq!(Float::from(1.5) * &Float::INFINITY, Float::INFINITY);
4016    /// assert_eq!(
4017    ///     Float::from(1.5) * &Float::NEGATIVE_INFINITY,
4018    ///     Float::NEGATIVE_INFINITY
4019    /// );
4020    /// assert_eq!(
4021    ///     Float::from(-1.5) * &Float::INFINITY,
4022    ///     Float::NEGATIVE_INFINITY
4023    /// );
4024    /// assert_eq!(
4025    ///     Float::from(-1.5) * &Float::NEGATIVE_INFINITY,
4026    ///     Float::INFINITY
4027    /// );
4028    /// assert!((Float::INFINITY * &Float::ZERO).is_nan());
4029    ///
4030    /// assert_eq!(Float::from(1.5) * &Float::from(2.5), 4.0);
4031    /// assert_eq!(Float::from(1.5) * &Float::from(-2.5), -4.0);
4032    /// assert_eq!(Float::from(-1.5) * &Float::from(2.5), -4.0);
4033    /// assert_eq!(Float::from(-1.5) * &Float::from(-2.5), 4.0);
4034    /// ```
4035    #[inline]
4036    fn mul(self, other: &Float) -> Float {
4037        let prec = max(self.significant_bits(), other.significant_bits());
4038        self.mul_prec_round_val_ref(other, prec, Nearest).0
4039    }
4040}
4041
4042impl Mul<Float> for &Float {
4043    type Output = Float;
4044
4045    /// Multiplies two [`Float`]s, taking the first by reference and the second by value.
4046    ///
4047    /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
4048    /// product is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
4049    /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
4050    /// `Nearest` rounding mode.
4051    ///
4052    /// $$
4053    /// f(x,y) = xy+\varepsilon.
4054    /// $$
4055    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4056    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
4057    ///   where $p$ is the maximum precision of the inputs.
4058    ///
4059    /// Special cases:
4060    /// - $f(\text{NaN},x)=f(x,\text{NaN})=f(\pm\infty,\pm0.0)=f(\pm0.0,\pm\infty) = \text{NaN}$
4061    /// - $f(\infty,x)=f(x,\infty)=\infty$ if $x>0.0$
4062    /// - $f(\infty,x)=f(x,\infty)=-\infty$ if $x<0.0$
4063    /// - $f(-\infty,x)=f(x,-\infty)=-\infty$ if $x>0.0$
4064    /// - $f(-\infty,x)=f(x,-\infty)=\infty$ if $x<0.0$
4065    /// - $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$
4066    /// - $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$
4067    /// - $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$
4068    /// - $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$
4069    ///
4070    /// Overflow and underflow:
4071    /// - If $f(x,y)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
4072    /// - If $f(x,y)\geq 2^{2^{30}-1}$, $-\infty$ is returned instead.
4073    /// - If $0<f(x,y)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
4074    /// - If $2^{-2^{30}-1}<f(x,y)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
4075    /// - If $-2^{-2^{30}-1}\leq f(x,y)<0$, $-0.0$ is returned instead.
4076    /// - If $-2^{-2^{30}}<f(x,y)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
4077    ///
4078    /// If you want to use a rounding mode other than `Nearest`, consider using
4079    /// [`Float::mul_prec_ref_val`] instead. If you want to specify the output precision, consider
4080    /// using [`Float::mul_round_ref_val`]. If you want both of these things, consider using
4081    /// [`Float::mul_prec_round_ref_val`].
4082    ///
4083    /// # Worst-case complexity
4084    /// $T(n) = O(n \log n \log\log n)$
4085    ///
4086    /// $M(n) = O(n \log n)$
4087    ///
4088    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
4089    /// other.significant_bits())`.
4090    ///
4091    /// # Examples
4092    /// ```
4093    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
4094    /// use malachite_float::Float;
4095    ///
4096    /// assert!((&Float::from(1.5) * Float::NAN).is_nan());
4097    /// assert_eq!(&Float::from(1.5) * Float::INFINITY, Float::INFINITY);
4098    /// assert_eq!(
4099    ///     &Float::from(1.5) * Float::NEGATIVE_INFINITY,
4100    ///     Float::NEGATIVE_INFINITY
4101    /// );
4102    /// assert_eq!(
4103    ///     &Float::from(-1.5) * Float::INFINITY,
4104    ///     Float::NEGATIVE_INFINITY
4105    /// );
4106    /// assert_eq!(
4107    ///     &Float::from(-1.5) * Float::NEGATIVE_INFINITY,
4108    ///     Float::INFINITY
4109    /// );
4110    /// assert!((&Float::INFINITY * Float::ZERO).is_nan());
4111    ///
4112    /// assert_eq!(&Float::from(1.5) * Float::from(2.5), 4.0);
4113    /// assert_eq!(&Float::from(1.5) * Float::from(-2.5), -4.0);
4114    /// assert_eq!(&Float::from(-1.5) * Float::from(2.5), -4.0);
4115    /// assert_eq!(&Float::from(-1.5) * Float::from(-2.5), 4.0);
4116    /// ```
4117    #[inline]
4118    fn mul(self, other: Float) -> Float {
4119        let prec = max(self.significant_bits(), other.significant_bits());
4120        self.mul_prec_round_ref_val(other, prec, Nearest).0
4121    }
4122}
4123
4124impl Mul<&Float> for &Float {
4125    type Output = Float;
4126
4127    /// Multiplies two [`Float`]s, taking both by reference.
4128    ///
4129    /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
4130    /// product is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
4131    /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
4132    /// `Nearest` rounding mode.
4133    ///
4134    /// $$
4135    /// f(x,y) = xy+\varepsilon.
4136    /// $$
4137    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4138    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
4139    ///   where $p$ is the maximum precision of the inputs.
4140    ///
4141    /// Special cases:
4142    /// - $f(\text{NaN},x)=f(x,\text{NaN})=f(\pm\infty,\pm0.0)=f(\pm0.0,\pm\infty) = \text{NaN}$
4143    /// - $f(\infty,x)=f(x,\infty)=\infty$ if $x>0.0$
4144    /// - $f(\infty,x)=f(x,\infty)=-\infty$ if $x<0.0$
4145    /// - $f(-\infty,x)=f(x,-\infty)=-\infty$ if $x>0.0$
4146    /// - $f(-\infty,x)=f(x,-\infty)=\infty$ if $x<0.0$
4147    /// - $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$
4148    /// - $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$
4149    /// - $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$
4150    /// - $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$
4151    ///
4152    /// Overflow and underflow:
4153    /// - If $f(x,y)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
4154    /// - If $f(x,y)\geq 2^{2^{30}-1}$, $-\infty$ is returned instead.
4155    /// - If $0<f(x,y)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
4156    /// - If $2^{-2^{30}-1}<f(x,y)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
4157    /// - If $-2^{-2^{30}-1}\leq f(x,y)<0$, $-0.0$ is returned instead.
4158    /// - If $-2^{-2^{30}}<f(x,y)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
4159    ///
4160    /// If you want to use a rounding mode other than `Nearest`, consider using
4161    /// [`Float::mul_prec_ref_ref`] instead. If you want to specify the output precision, consider
4162    /// using [`Float::mul_round_ref_ref`]. If you want both of these things, consider using
4163    /// [`Float::mul_prec_round_ref_ref`].
4164    ///
4165    /// # Worst-case complexity
4166    /// $T(n) = O(n \log n \log\log n)$
4167    ///
4168    /// $M(n) = O(n \log n)$
4169    ///
4170    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
4171    /// other.significant_bits())`.
4172    ///
4173    /// # Examples
4174    /// ```
4175    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
4176    /// use malachite_float::Float;
4177    ///
4178    /// assert!((&Float::from(1.5) * &Float::NAN).is_nan());
4179    /// assert_eq!(&Float::from(1.5) * &Float::INFINITY, Float::INFINITY);
4180    /// assert_eq!(
4181    ///     &Float::from(1.5) * &Float::NEGATIVE_INFINITY,
4182    ///     Float::NEGATIVE_INFINITY
4183    /// );
4184    /// assert_eq!(
4185    ///     &Float::from(-1.5) * &Float::INFINITY,
4186    ///     Float::NEGATIVE_INFINITY
4187    /// );
4188    /// assert_eq!(
4189    ///     &Float::from(-1.5) * &Float::NEGATIVE_INFINITY,
4190    ///     Float::INFINITY
4191    /// );
4192    /// assert!((&Float::INFINITY * &Float::ZERO).is_nan());
4193    ///
4194    /// assert_eq!(&Float::from(1.5) * &Float::from(2.5), 4.0);
4195    /// assert_eq!(&Float::from(1.5) * &Float::from(-2.5), -4.0);
4196    /// assert_eq!(&Float::from(-1.5) * &Float::from(2.5), -4.0);
4197    /// assert_eq!(&Float::from(-1.5) * &Float::from(-2.5), 4.0);
4198    /// ```
4199    #[inline]
4200    fn mul(self, other: &Float) -> Float {
4201        let prec = max(self.significant_bits(), other.significant_bits());
4202        self.mul_prec_round_ref_ref(other, prec, Nearest).0
4203    }
4204}
4205
4206impl MulAssign<Float> for Float {
4207    /// Multiplies a [`Float`] by a [`Float`] in place, taking the [`Float`] on the right-hand side
4208    /// by value.
4209    ///
4210    /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
4211    /// product is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
4212    /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
4213    /// `Nearest` rounding mode.
4214    ///
4215    /// $$
4216    /// x\gets = xy+\varepsilon.
4217    /// $$
4218    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4219    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
4220    ///   where $p$ is the maximum precision of the inputs.
4221    ///
4222    /// See the `*` documentation for information on special cases, overflow, and underflow.
4223    ///
4224    /// If you want to use a rounding mode other than `Nearest`, consider using
4225    /// [`Float::mul_prec_assign`] instead. If you want to specify the output precision, consider
4226    /// using [`Float::mul_round_assign`]. If you want both of these things, consider using
4227    /// [`Float::mul_prec_round_assign`].
4228    ///
4229    /// # Worst-case complexity
4230    /// $T(n) = O(n \log n \log\log n)$
4231    ///
4232    /// $M(n) = O(n \log n)$
4233    ///
4234    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
4235    /// other.significant_bits())`.
4236    ///
4237    /// # Examples
4238    /// ```
4239    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
4240    /// use malachite_float::Float;
4241    ///
4242    /// let mut x = Float::from(1.5);
4243    /// x *= Float::NAN;
4244    /// assert!(x.is_nan());
4245    ///
4246    /// let mut x = Float::from(1.5);
4247    /// x *= Float::INFINITY;
4248    /// assert_eq!(x, Float::INFINITY);
4249    ///
4250    /// let mut x = Float::from(1.5);
4251    /// x *= Float::NEGATIVE_INFINITY;
4252    /// assert_eq!(x, Float::NEGATIVE_INFINITY);
4253    ///
4254    /// let mut x = Float::from(-1.5);
4255    /// x *= Float::INFINITY;
4256    /// assert_eq!(x, Float::NEGATIVE_INFINITY);
4257    ///
4258    /// let mut x = Float::from(-1.5);
4259    /// x *= Float::NEGATIVE_INFINITY;
4260    /// assert_eq!(x, Float::INFINITY);
4261    ///
4262    /// let mut x = Float::INFINITY;
4263    /// x *= Float::ZERO;
4264    /// assert!(x.is_nan());
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    /// let mut x = Float::from(-1.5);
4275    /// x *= Float::from(2.5);
4276    /// assert_eq!(x, -4.0);
4277    ///
4278    /// let mut x = Float::from(-1.5);
4279    /// x *= Float::from(-2.5);
4280    /// assert_eq!(x, 4.0);
4281    /// ```
4282    #[inline]
4283    fn mul_assign(&mut self, other: Float) {
4284        let prec = max(self.significant_bits(), other.significant_bits());
4285        self.mul_prec_round_assign(other, prec, Nearest);
4286    }
4287}
4288
4289impl MulAssign<&Float> for Float {
4290    /// Multiplies a [`Float`] by a [`Float`] in place, taking the [`Float`] on the right-hand side
4291    /// by reference.
4292    ///
4293    /// If the output has a precision, it is the maximum of the precisions of the inputs. If the
4294    /// product is equidistant from two [`Float`]s with the specified precision, the [`Float`] with
4295    /// fewer 1s in its binary expansion is chosen. See [`RoundingMode`] for a description of the
4296    /// `Nearest` rounding mode.
4297    ///
4298    /// $$
4299    /// x\gets = xy+\varepsilon.
4300    /// $$
4301    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4302    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
4303    ///   where $p$ is the maximum precision of the inputs.
4304    ///
4305    /// See the `*` documentation for information on special cases, overflow, and underflow.
4306    ///
4307    /// If you want to use a rounding mode other than `Nearest`, consider using
4308    /// [`Float::mul_prec_assign`] instead. If you want to specify the output precision, consider
4309    /// using [`Float::mul_round_assign`]. If you want both of these things, consider using
4310    /// [`Float::mul_prec_round_assign`].
4311    ///
4312    /// # Worst-case complexity
4313    /// $T(n) = O(n \log n \log\log n)$
4314    ///
4315    /// $M(n) = O(n \log n)$
4316    ///
4317    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
4318    /// other.significant_bits())`.
4319    ///
4320    /// # Examples
4321    /// ```
4322    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity, Zero};
4323    /// use malachite_float::Float;
4324    ///
4325    /// let mut x = Float::from(1.5);
4326    /// x *= &Float::NAN;
4327    /// assert!(x.is_nan());
4328    ///
4329    /// let mut x = Float::from(1.5);
4330    /// x *= &Float::INFINITY;
4331    /// assert_eq!(x, Float::INFINITY);
4332    ///
4333    /// let mut x = Float::from(1.5);
4334    /// x *= &Float::NEGATIVE_INFINITY;
4335    /// assert_eq!(x, Float::NEGATIVE_INFINITY);
4336    ///
4337    /// let mut x = Float::from(-1.5);
4338    /// x *= &Float::INFINITY;
4339    /// assert_eq!(x, Float::NEGATIVE_INFINITY);
4340    ///
4341    /// let mut x = Float::from(-1.5);
4342    /// x *= &Float::NEGATIVE_INFINITY;
4343    /// assert_eq!(x, Float::INFINITY);
4344    ///
4345    /// let mut x = Float::INFINITY;
4346    /// x *= &Float::ZERO;
4347    /// assert!(x.is_nan());
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    /// let mut x = Float::from(-1.5);
4358    /// x *= &Float::from(2.5);
4359    /// assert_eq!(x, -4.0);
4360    ///
4361    /// let mut x = Float::from(-1.5);
4362    /// x *= &Float::from(-2.5);
4363    /// assert_eq!(x, 4.0);
4364    /// ```
4365    #[inline]
4366    fn mul_assign(&mut self, other: &Float) {
4367        let prec = max(self.significant_bits(), other.significant_bits());
4368        self.mul_prec_round_assign_ref(other, prec, Nearest);
4369    }
4370}
4371
4372impl Mul<Rational> for Float {
4373    type Output = Float;
4374
4375    /// Multiplies a [`Float`] by a [`Rational`], taking both by value.
4376    ///
4377    /// If the output has a precision, it is the precision of the input [`Float`]. If the product is
4378    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
4379    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4380    /// rounding mode.
4381    ///
4382    /// $$
4383    /// f(x,y) = xy+\varepsilon.
4384    /// $$
4385    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4386    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
4387    ///   where $p$ is the precision of the input [`Float`].
4388    ///
4389    /// Special cases:
4390    /// - $f(\text{NaN},x)=f(\pm\infty,0)=\text{NaN}$
4391    /// - $f(\infty,x)=\infty$ if $x>0$
4392    /// - $f(\infty,x)=-\infty$ if $x<0$
4393    /// - $f(-\infty,x)=-\infty$ if $x>0$
4394    /// - $f(-\infty,x)=\infty$ if $x<0$
4395    /// - $f(0.0,x)=0.0$ if $x\geq0$
4396    /// - $f(0.0,x)=-0.0$ if $x<0$
4397    /// - $f(-0.0,x)=-0.0$ if $x\geq0$
4398    /// - $f(-0.0,x)=0.0$ if $x<0$
4399    ///
4400    /// If you want to use a rounding mode other than `Nearest`, consider using
4401    /// [`Float::mul_rational_prec`] instead. If you want to specify the output precision, consider
4402    /// using [`Float::mul_rational_round`]. If you want both of these things, consider using
4403    /// [`Float::mul_rational_prec_round`].
4404    ///
4405    /// # Worst-case complexity
4406    /// $T(n) = O(n \log n \log\log n)$
4407    ///
4408    /// $M(n) = O(n \log n)$
4409    ///
4410    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
4411    /// other.significant_bits())`.
4412    ///
4413    /// # Examples
4414    /// ```
4415    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
4416    /// use malachite_base::num::conversion::traits::ExactFrom;
4417    /// use malachite_float::Float;
4418    /// use malachite_q::Rational;
4419    ///
4420    /// assert!((Float::NAN * Rational::exact_from(1.5)).is_nan());
4421    /// assert_eq!(Float::INFINITY * Rational::exact_from(1.5), Float::INFINITY);
4422    /// assert_eq!(
4423    ///     Float::NEGATIVE_INFINITY * Rational::exact_from(1.5),
4424    ///     Float::NEGATIVE_INFINITY
4425    /// );
4426    /// assert_eq!(
4427    ///     Float::INFINITY * Rational::exact_from(-1.5),
4428    ///     Float::NEGATIVE_INFINITY
4429    /// );
4430    /// assert_eq!(
4431    ///     Float::NEGATIVE_INFINITY * Rational::exact_from(-1.5),
4432    ///     Float::INFINITY
4433    /// );
4434    ///
4435    /// assert_eq!(Float::from(2.5) * Rational::exact_from(1.5), 4.0);
4436    /// assert_eq!(Float::from(2.5) * Rational::exact_from(-1.5), -4.0);
4437    /// assert_eq!(Float::from(-2.5) * Rational::exact_from(1.5), -4.0);
4438    /// assert_eq!(Float::from(-2.5) * Rational::exact_from(-1.5), 4.0);
4439    /// ```
4440    #[inline]
4441    fn mul(self, other: Rational) -> Float {
4442        let prec = self.significant_bits();
4443        self.mul_rational_prec_round(other, prec, Nearest).0
4444    }
4445}
4446
4447impl Mul<&Rational> for Float {
4448    type Output = Float;
4449
4450    /// Multiplies a [`Float`] by a [`Rational`], taking the first by value and the second by
4451    /// reference.
4452    ///
4453    /// If the output has a precision, it is the precision of the input [`Float`]. If the product is
4454    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
4455    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4456    /// rounding mode.
4457    ///
4458    /// $$
4459    /// f(x,y) = xy+\varepsilon.
4460    /// $$
4461    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4462    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
4463    ///   where $p$ is the precision of the input [`Float`].
4464    ///
4465    /// Special cases:
4466    /// - $f(\text{NaN},x)=f(\pm\infty,0)=\text{NaN}$
4467    /// - $f(\infty,x)=\infty$ if $x>0$
4468    /// - $f(\infty,x)=-\infty$ if $x<0$
4469    /// - $f(-\infty,x)=-\infty$ if $x>0$
4470    /// - $f(-\infty,x)=\infty$ if $x<0$
4471    /// - $f(0.0,x)=0.0$ if $x\geq0$
4472    /// - $f(0.0,x)=-0.0$ if $x<0$
4473    /// - $f(-0.0,x)=-0.0$ if $x\geq0$
4474    /// - $f(-0.0,x)=0.0$ if $x<0$
4475    ///
4476    /// If you want to use a rounding mode other than `Nearest`, consider using
4477    /// [`Float::mul_rational_prec_val_ref`] instead. If you want to specify the output precision,
4478    /// consider using [`Float::mul_rational_round_val_ref`]. If you want both of these things,
4479    /// consider using [`Float::mul_rational_prec_round_val_ref`].
4480    ///
4481    /// # Worst-case complexity
4482    /// $T(n) = O(n \log n \log\log n)$
4483    ///
4484    /// $M(n) = O(n \log n)$
4485    ///
4486    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
4487    /// other.significant_bits())`.
4488    ///
4489    /// # Examples
4490    /// ```
4491    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
4492    /// use malachite_base::num::conversion::traits::ExactFrom;
4493    /// use malachite_float::Float;
4494    /// use malachite_q::Rational;
4495    ///
4496    /// assert!((Float::NAN * &Rational::exact_from(1.5)).is_nan());
4497    /// assert_eq!(
4498    ///     Float::INFINITY * &Rational::exact_from(1.5),
4499    ///     Float::INFINITY
4500    /// );
4501    /// assert_eq!(
4502    ///     Float::NEGATIVE_INFINITY * &Rational::exact_from(1.5),
4503    ///     Float::NEGATIVE_INFINITY
4504    /// );
4505    /// assert_eq!(
4506    ///     Float::INFINITY * &Rational::exact_from(-1.5),
4507    ///     Float::NEGATIVE_INFINITY
4508    /// );
4509    /// assert_eq!(
4510    ///     Float::NEGATIVE_INFINITY * &Rational::exact_from(-1.5),
4511    ///     Float::INFINITY
4512    /// );
4513    ///
4514    /// assert_eq!(Float::from(2.5) * &Rational::exact_from(1.5), 4.0);
4515    /// assert_eq!(Float::from(2.5) * &Rational::exact_from(-1.5), -4.0);
4516    /// assert_eq!(Float::from(-2.5) * &Rational::exact_from(1.5), -4.0);
4517    /// assert_eq!(Float::from(-2.5) * &Rational::exact_from(-1.5), 4.0);
4518    /// ```
4519    #[inline]
4520    fn mul(self, other: &Rational) -> Float {
4521        let prec = self.significant_bits();
4522        self.mul_rational_prec_round_val_ref(other, prec, Nearest).0
4523    }
4524}
4525
4526impl Mul<Rational> for &Float {
4527    type Output = Float;
4528
4529    /// Multiplies a [`Float`] by a [`Rational`], taking the first by reference and the second by
4530    /// value.
4531    ///
4532    /// If the output has a precision, it is the precision of the input [`Float`]. If the product is
4533    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
4534    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4535    /// rounding mode.
4536    ///
4537    /// $$
4538    /// f(x,y) = xy+\varepsilon.
4539    /// $$
4540    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4541    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
4542    ///   where $p$ is the precision of the input [`Float`].
4543    ///
4544    /// Special cases:
4545    /// - $f(\text{NaN},x)=f(\pm\infty,0)=\text{NaN}$
4546    /// - $f(\infty,x)=\infty$ if $x>0$
4547    /// - $f(\infty,x)=-\infty$ if $x<0$
4548    /// - $f(-\infty,x)=-\infty$ if $x>0$
4549    /// - $f(-\infty,x)=\infty$ if $x<0$
4550    /// - $f(0.0,x)=0.0$ if $x\geq0$
4551    /// - $f(0.0,x)=-0.0$ if $x<0$
4552    /// - $f(-0.0,x)=-0.0$ if $x\geq0$
4553    /// - $f(-0.0,x)=0.0$ if $x<0$
4554    ///
4555    /// If you want to use a rounding mode other than `Nearest`, consider using
4556    /// [`Float::mul_rational_prec_ref_val`] instead. If you want to specify the output precision,
4557    /// consider using [`Float::mul_rational_round_ref_val`]. If you want both of these things,
4558    /// consider using [`Float::mul_rational_prec_round_ref_val`].
4559    ///
4560    /// # Worst-case complexity
4561    /// $T(n) = O(n \log n \log\log n)$
4562    ///
4563    /// $M(n) = O(n \log n)$
4564    ///
4565    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
4566    /// other.significant_bits())`.
4567    ///
4568    /// # Examples
4569    /// ```
4570    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
4571    /// use malachite_base::num::conversion::traits::ExactFrom;
4572    /// use malachite_float::Float;
4573    /// use malachite_q::Rational;
4574    ///
4575    /// assert!((&Float::NAN * Rational::exact_from(1.5)).is_nan());
4576    /// assert_eq!(
4577    ///     &Float::INFINITY * Rational::exact_from(1.5),
4578    ///     Float::INFINITY
4579    /// );
4580    /// assert_eq!(
4581    ///     &Float::NEGATIVE_INFINITY * Rational::exact_from(1.5),
4582    ///     Float::NEGATIVE_INFINITY
4583    /// );
4584    /// assert_eq!(
4585    ///     &Float::INFINITY * Rational::exact_from(-1.5),
4586    ///     Float::NEGATIVE_INFINITY
4587    /// );
4588    /// assert_eq!(
4589    ///     &Float::NEGATIVE_INFINITY * Rational::exact_from(-1.5),
4590    ///     Float::INFINITY
4591    /// );
4592    ///
4593    /// assert_eq!(&Float::from(2.5) * Rational::exact_from(1.5), 4.0);
4594    /// assert_eq!(&Float::from(2.5) * Rational::exact_from(-1.5), -4.0);
4595    /// assert_eq!(&Float::from(-2.5) * Rational::exact_from(1.5), -4.0);
4596    /// assert_eq!(&Float::from(-2.5) * Rational::exact_from(-1.5), 4.0);
4597    /// ```
4598    #[inline]
4599    fn mul(self, other: Rational) -> Float {
4600        let prec = self.significant_bits();
4601        self.mul_rational_prec_round_ref_val(other, prec, Nearest).0
4602    }
4603}
4604
4605impl Mul<&Rational> for &Float {
4606    type Output = Float;
4607
4608    /// Multiplies a [`Float`] by a [`Rational`], taking both by reference.
4609    ///
4610    /// If the output has a precision, it is the precision of the input [`Float`]. If the product is
4611    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
4612    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4613    /// rounding mode.
4614    ///
4615    /// $$
4616    /// f(x,y) = xy+\varepsilon.
4617    /// $$
4618    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4619    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
4620    ///   where $p$ is the precision of the input [`Float`].
4621    ///
4622    /// Special cases:
4623    /// - $f(\text{NaN},x)=f(\pm\infty,0)=\text{NaN}$
4624    /// - $f(\infty,x)=\infty$ if $x>0$
4625    /// - $f(\infty,x)=-\infty$ if $x<0$
4626    /// - $f(-\infty,x)=-\infty$ if $x>0$
4627    /// - $f(-\infty,x)=\infty$ if $x<0$
4628    /// - $f(0.0,x)=0.0$ if $x\geq0$
4629    /// - $f(0.0,x)=-0.0$ if $x<0$
4630    /// - $f(-0.0,x)=-0.0$ if $x\geq0$
4631    /// - $f(-0.0,x)=0.0$ if $x<0$
4632    ///
4633    /// If you want to use a rounding mode other than `Nearest`, consider using
4634    /// [`Float::mul_rational_prec_ref_ref`] instead. If you want to specify the output precision,
4635    /// consider using [`Float::mul_rational_round_ref_ref`]. If you want both of these things,
4636    /// consider using [`Float::mul_rational_prec_round_ref_ref`].
4637    ///
4638    /// # Worst-case complexity
4639    /// $T(n) = O(n \log n \log\log n)$
4640    ///
4641    /// $M(n) = O(n \log n)$
4642    ///
4643    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
4644    /// other.significant_bits())`.
4645    ///
4646    /// # Examples
4647    /// ```
4648    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
4649    /// use malachite_base::num::conversion::traits::ExactFrom;
4650    /// use malachite_float::Float;
4651    /// use malachite_q::Rational;
4652    ///
4653    /// assert!((&Float::NAN * &Rational::exact_from(1.5)).is_nan());
4654    /// assert_eq!(
4655    ///     &Float::INFINITY * &Rational::exact_from(1.5),
4656    ///     Float::INFINITY
4657    /// );
4658    /// assert_eq!(
4659    ///     &Float::NEGATIVE_INFINITY * &Rational::exact_from(1.5),
4660    ///     Float::NEGATIVE_INFINITY
4661    /// );
4662    /// assert_eq!(
4663    ///     &Float::INFINITY * &Rational::exact_from(-1.5),
4664    ///     Float::NEGATIVE_INFINITY
4665    /// );
4666    /// assert_eq!(
4667    ///     &Float::NEGATIVE_INFINITY * &Rational::exact_from(-1.5),
4668    ///     Float::INFINITY
4669    /// );
4670    ///
4671    /// assert_eq!(&Float::from(2.5) * &Rational::exact_from(1.5), 4.0);
4672    /// assert_eq!(&Float::from(2.5) * &Rational::exact_from(-1.5), -4.0);
4673    /// assert_eq!(&Float::from(-2.5) * &Rational::exact_from(1.5), -4.0);
4674    /// assert_eq!(&Float::from(-2.5) * &Rational::exact_from(-1.5), 4.0);
4675    /// ```
4676    #[inline]
4677    fn mul(self, other: &Rational) -> Float {
4678        let prec = self.significant_bits();
4679        self.mul_rational_prec_round_ref_ref(other, prec, Nearest).0
4680    }
4681}
4682
4683impl MulAssign<Rational> for Float {
4684    /// Multiplies a [`Float`] by a [`Rational`] in place, taking the [`Rational`] by value.
4685    ///
4686    /// If the output has a precision, it is the precision of the input [`Float`]. If the product is
4687    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
4688    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4689    /// rounding mode.
4690    ///
4691    /// $$
4692    /// x\gets = xy+\varepsilon.
4693    /// $$
4694    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4695    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
4696    ///   where $p$ is the precision of the input [`Float`].
4697    ///
4698    /// See the `*` documentation for information on special cases.
4699    ///
4700    /// If you want to use a rounding mode other than `Nearest`, consider using
4701    /// [`Float::mul_rational_prec_assign`] instead. If you want to specify the output precision,
4702    /// consider using [`Float::mul_rational_round_assign`]. If you want both of these things,
4703    /// consider using [`Float::mul_rational_prec_round_assign`].
4704    ///
4705    /// # Worst-case complexity
4706    /// $T(n) = O(n \log n \log\log n)$
4707    ///
4708    /// $M(n) = O(n \log n)$
4709    ///
4710    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
4711    /// other.significant_bits())`.
4712    ///
4713    /// # Examples
4714    /// ```
4715    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
4716    /// use malachite_base::num::conversion::traits::ExactFrom;
4717    /// use malachite_float::Float;
4718    /// use malachite_q::Rational;
4719    ///
4720    /// let mut x = Float::NAN;
4721    /// x *= Rational::exact_from(1.5);
4722    /// assert!(x.is_nan());
4723    ///
4724    /// let mut x = Float::INFINITY;
4725    /// x *= Rational::exact_from(1.5);
4726    /// assert_eq!(x, Float::INFINITY);
4727    ///
4728    /// let mut x = Float::NEGATIVE_INFINITY;
4729    /// x *= Rational::exact_from(1.5);
4730    /// assert_eq!(x, Float::NEGATIVE_INFINITY);
4731    ///
4732    /// let mut x = Float::INFINITY;
4733    /// x *= Rational::exact_from(-1.5);
4734    /// assert_eq!(x, Float::NEGATIVE_INFINITY);
4735    ///
4736    /// let mut x = Float::NEGATIVE_INFINITY;
4737    /// x *= Rational::exact_from(-1.5);
4738    /// assert_eq!(x, Float::INFINITY);
4739    ///
4740    /// let mut x = Float::from(2.5);
4741    /// x *= Rational::exact_from(1.5);
4742    /// assert_eq!(x, 4.0);
4743    /// ```
4744    #[inline]
4745    fn mul_assign(&mut self, other: Rational) {
4746        let prec = self.significant_bits();
4747        self.mul_rational_prec_round_assign(other, prec, Nearest);
4748    }
4749}
4750
4751impl MulAssign<&Rational> for Float {
4752    /// Multiplies a [`Float`] by a [`Rational`] in place, taking the [`Rational`] by reference.
4753    ///
4754    /// If the output has a precision, it is the precision of the input [`Float`]. If the product is
4755    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
4756    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4757    /// rounding mode.
4758    ///
4759    /// $$
4760    /// x\gets = xy+\varepsilon.
4761    /// $$
4762    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4763    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
4764    ///   where $p$ is the precision of the input [`Float`].
4765    ///
4766    /// See the `*` documentation for information on special cases.
4767    ///
4768    /// If you want to use a rounding mode other than `Nearest`, consider using
4769    /// [`Float::mul_rational_prec_assign_ref`] instead. If you want to specify the output
4770    /// precision, consider using [`Float::mul_rational_round_assign_ref`]. If you want both of
4771    /// these things, consider using [`Float::mul_rational_prec_round_assign_ref`].
4772    ///
4773    /// # Worst-case complexity
4774    /// $T(n) = O(n \log n \log\log n)$
4775    ///
4776    /// $M(n) = O(n \log n)$
4777    ///
4778    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
4779    /// other.significant_bits())`.
4780    ///
4781    /// # Examples
4782    /// ```
4783    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
4784    /// use malachite_base::num::conversion::traits::ExactFrom;
4785    /// use malachite_float::Float;
4786    /// use malachite_q::Rational;
4787    ///
4788    /// let mut x = Float::NAN;
4789    /// x *= &Rational::exact_from(1.5);
4790    /// assert!(x.is_nan());
4791    ///
4792    /// let mut x = Float::INFINITY;
4793    /// x *= &Rational::exact_from(1.5);
4794    /// assert_eq!(x, Float::INFINITY);
4795    ///
4796    /// let mut x = Float::NEGATIVE_INFINITY;
4797    /// x *= &Rational::exact_from(1.5);
4798    /// assert_eq!(x, Float::NEGATIVE_INFINITY);
4799    ///
4800    /// let mut x = Float::INFINITY;
4801    /// x *= &Rational::exact_from(-1.5);
4802    /// assert_eq!(x, Float::NEGATIVE_INFINITY);
4803    ///
4804    /// let mut x = Float::NEGATIVE_INFINITY;
4805    /// x *= &Rational::exact_from(-1.5);
4806    /// assert_eq!(x, Float::INFINITY);
4807    ///
4808    /// let mut x = Float::from(2.5);
4809    /// x *= &Rational::exact_from(1.5);
4810    /// assert_eq!(x, 4.0);
4811    /// ```
4812    #[inline]
4813    fn mul_assign(&mut self, other: &Rational) {
4814        let prec = self.significant_bits();
4815        self.mul_rational_prec_round_assign_ref(other, prec, Nearest);
4816    }
4817}
4818
4819impl Mul<Float> for Rational {
4820    type Output = Float;
4821
4822    /// Multiplies a [`Rational`] by a [`Float`], taking both by value.
4823    ///
4824    /// If the output has a precision, it is the precision of the input [`Float`]. If the product is
4825    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
4826    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4827    /// rounding mode.
4828    ///
4829    /// $$
4830    /// f(x,y) = xy+\varepsilon.
4831    /// $$
4832    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4833    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
4834    ///   where $p$ is the precision of the input [`Float`].
4835    ///
4836    /// Special cases:
4837    /// - $f(x,\text{NaN})=f(0,\pm\infty)=\text{NaN}$
4838    /// - $f(x,\infty)=\infty$ if $x>0$
4839    /// - $f(x,\infty)=-\infty$ if $x<0$
4840    /// - $f(x,-\infty)=-\infty$ if $x>0$
4841    /// - $f(x,-\infty)=\infty$ if $x<0$
4842    /// - $f(x,0.0)=0.0$ if $x\geq0$
4843    /// - $f(x,0.0)=-0.0$ if $x<0$
4844    /// - $f(x,-0.0)=-0.0$ if $x\geq0$
4845    /// - $f(x,-0.0)=0.0$ if $x<0$
4846    ///
4847    /// # Worst-case complexity
4848    /// $T(n) = O(n \log n \log\log n)$
4849    ///
4850    /// $M(n) = O(n \log n)$
4851    ///
4852    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
4853    /// other.significant_bits())`.
4854    ///
4855    /// # Examples
4856    /// ```
4857    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
4858    /// use malachite_base::num::conversion::traits::ExactFrom;
4859    /// use malachite_float::Float;
4860    /// use malachite_q::Rational;
4861    ///
4862    /// assert!((Rational::exact_from(1.5) * Float::NAN).is_nan());
4863    /// assert_eq!(Rational::exact_from(1.5) * Float::INFINITY, Float::INFINITY);
4864    /// assert_eq!(
4865    ///     Rational::exact_from(1.5) * Float::NEGATIVE_INFINITY,
4866    ///     Float::NEGATIVE_INFINITY
4867    /// );
4868    /// assert_eq!(
4869    ///     Rational::exact_from(-1.5) * Float::INFINITY,
4870    ///     Float::NEGATIVE_INFINITY
4871    /// );
4872    /// assert_eq!(
4873    ///     Rational::exact_from(-1.5) * Float::NEGATIVE_INFINITY,
4874    ///     Float::INFINITY
4875    /// );
4876    ///
4877    /// assert_eq!(Rational::exact_from(1.5) * Float::from(2.5), 4.0);
4878    /// assert_eq!(Rational::exact_from(-1.5) * Float::from(2.5), -4.0);
4879    /// assert_eq!(Rational::exact_from(1.5) * Float::from(-2.5), -4.0);
4880    /// assert_eq!(Rational::exact_from(-1.5) * Float::from(-2.5), 4.0);
4881    /// ```
4882    #[inline]
4883    fn mul(self, other: Float) -> Float {
4884        let prec = other.significant_bits();
4885        other.mul_rational_prec_round(self, prec, Nearest).0
4886    }
4887}
4888
4889impl Mul<&Float> for Rational {
4890    type Output = Float;
4891
4892    /// Multiplies a [`Rational`] by a [`Float`], taking the [`Rational`] by value and the [`Float`]
4893    /// by reference.
4894    ///
4895    /// If the output has a precision, it is the precision of the input [`Float`]. If the product is
4896    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
4897    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4898    /// rounding mode.
4899    ///
4900    /// $$
4901    /// f(x,y) = xy+\varepsilon.
4902    /// $$
4903    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4904    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
4905    ///   where $p$ is the precision of the input [`Float`].
4906    ///
4907    /// Special cases:
4908    /// - $f(x,\text{NaN})=f(0,\pm\infty)=\text{NaN}$
4909    /// - $f(x,\infty)=\infty$ if $x>0$
4910    /// - $f(x,\infty)=-\infty$ if $x<0$
4911    /// - $f(x,-\infty)=-\infty$ if $x>0$
4912    /// - $f(x,-\infty)=\infty$ if $x<0$
4913    /// - $f(x,0.0)=0.0$ if $x\geq0$
4914    /// - $f(x,0.0)=-0.0$ if $x<0$
4915    /// - $f(x,-0.0)=-0.0$ if $x\geq0$
4916    /// - $f(x,-0.0)=0.0$ if $x<0$
4917    ///
4918    /// # Worst-case complexity
4919    /// $T(n) = O(n \log n \log\log n)$
4920    ///
4921    /// $M(n) = O(n \log n)$
4922    ///
4923    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
4924    /// other.significant_bits())`.
4925    ///
4926    /// # Examples
4927    /// ```
4928    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
4929    /// use malachite_base::num::conversion::traits::ExactFrom;
4930    /// use malachite_float::Float;
4931    /// use malachite_q::Rational;
4932    ///
4933    /// assert!((Rational::exact_from(1.5) * &Float::NAN).is_nan());
4934    /// assert_eq!(
4935    ///     Rational::exact_from(1.5) * &Float::INFINITY,
4936    ///     Float::INFINITY
4937    /// );
4938    /// assert_eq!(
4939    ///     Rational::exact_from(1.5) * &Float::NEGATIVE_INFINITY,
4940    ///     Float::NEGATIVE_INFINITY
4941    /// );
4942    /// assert_eq!(
4943    ///     Rational::exact_from(-1.5) * &Float::INFINITY,
4944    ///     Float::NEGATIVE_INFINITY
4945    /// );
4946    /// assert_eq!(
4947    ///     Rational::exact_from(-1.5) * &Float::NEGATIVE_INFINITY,
4948    ///     Float::INFINITY
4949    /// );
4950    ///
4951    /// assert_eq!(Rational::exact_from(1.5) * &Float::from(2.5), 4.0);
4952    /// assert_eq!(Rational::exact_from(-1.5) * &Float::from(2.5), -4.0);
4953    /// assert_eq!(Rational::exact_from(1.5) * &Float::from(-2.5), -4.0);
4954    /// assert_eq!(Rational::exact_from(-1.5) * &Float::from(-2.5), 4.0);
4955    /// ```
4956    #[inline]
4957    fn mul(self, other: &Float) -> Float {
4958        let prec = other.significant_bits();
4959        other.mul_rational_prec_round_ref_val(self, prec, Nearest).0
4960    }
4961}
4962
4963impl Mul<Float> for &Rational {
4964    type Output = Float;
4965
4966    /// Multiplies a [`Rational`] by a [`Float`], taking the [`Rational`] by reference and the
4967    /// [`Float`] by value.
4968    ///
4969    /// If the output has a precision, it is the precision of the input [`Float`]. If the product is
4970    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
4971    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
4972    /// rounding mode.
4973    ///
4974    /// $$
4975    /// f(x,y) = xy+\varepsilon.
4976    /// $$
4977    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
4978    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
4979    ///   where $p$ is the precision of the input [`Float`].
4980    ///
4981    /// Special cases:
4982    /// - $f(x,\text{NaN})=f(0,\pm\infty)=\text{NaN}$
4983    /// - $f(x,\infty)=\infty$ if $x>0$
4984    /// - $f(x,\infty)=-\infty$ if $x<0$
4985    /// - $f(x,-\infty)=-\infty$ if $x>0$
4986    /// - $f(x,-\infty)=\infty$ if $x<0$
4987    /// - $f(x,0.0)=0.0$ if $x\geq0$
4988    /// - $f(x,0.0)=-0.0$ if $x<0$
4989    /// - $f(x,-0.0)=-0.0$ if $x\geq0$
4990    /// - $f(x,-0.0)=0.0$ if $x<0$
4991    ///
4992    /// # Worst-case complexity
4993    /// $T(n) = O(n \log n \log\log n)$
4994    ///
4995    /// $M(n) = O(n \log n)$
4996    ///
4997    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
4998    /// other.significant_bits())`.
4999    ///
5000    /// # Examples
5001    /// ```
5002    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
5003    /// use malachite_base::num::conversion::traits::ExactFrom;
5004    /// use malachite_float::Float;
5005    /// use malachite_q::Rational;
5006    ///
5007    /// assert!((&Rational::exact_from(1.5) * Float::NAN).is_nan());
5008    /// assert_eq!(
5009    ///     &Rational::exact_from(1.5) * Float::INFINITY,
5010    ///     Float::INFINITY
5011    /// );
5012    /// assert_eq!(
5013    ///     &Rational::exact_from(1.5) * Float::NEGATIVE_INFINITY,
5014    ///     Float::NEGATIVE_INFINITY
5015    /// );
5016    /// assert_eq!(
5017    ///     &Rational::exact_from(-1.5) * Float::INFINITY,
5018    ///     Float::NEGATIVE_INFINITY
5019    /// );
5020    /// assert_eq!(
5021    ///     &Rational::exact_from(-1.5) * Float::NEGATIVE_INFINITY,
5022    ///     Float::INFINITY
5023    /// );
5024    ///
5025    /// assert_eq!(&Rational::exact_from(1.5) * Float::from(2.5), 4.0);
5026    /// assert_eq!(&Rational::exact_from(-1.5) * Float::from(2.5), -4.0);
5027    /// assert_eq!(&Rational::exact_from(1.5) * Float::from(-2.5), -4.0);
5028    /// assert_eq!(&Rational::exact_from(-1.5) * Float::from(-2.5), 4.0);
5029    /// ```
5030    #[inline]
5031    fn mul(self, other: Float) -> Float {
5032        let prec = other.significant_bits();
5033        other.mul_rational_prec_round_val_ref(self, prec, Nearest).0
5034    }
5035}
5036
5037impl Mul<&Float> for &Rational {
5038    type Output = Float;
5039
5040    /// Multiplies a [`Rational`] by a [`Float`], taking both by reference.
5041    ///
5042    /// If the output has a precision, it is the precision of the input [`Float`]. If the product is
5043    /// equidistant from two [`Float`]s with the specified precision, the [`Float`] with fewer 1s in
5044    /// its binary expansion is chosen. See [`RoundingMode`] for a description of the `Nearest`
5045    /// rounding mode.
5046    ///
5047    /// $$
5048    /// f(x,y) = xy+\varepsilon.
5049    /// $$
5050    /// - If $xy$ is infinite, zero, or `NaN`, $\varepsilon$ may be ignored or assumed to be 0.
5051    /// - If $xy$ is finite and nonzero, then $|\varepsilon| < 2^{\lfloor\log_2 |xy|\rfloor-p}$,
5052    ///   where $p$ is the precision of the input [`Float`].
5053    ///
5054    /// Special cases:
5055    /// - $f(x,\text{NaN})=f(0,\pm\infty)=\text{NaN}$
5056    /// - $f(x,\infty)=\infty$ if $x>0$
5057    /// - $f(x,\infty)=-\infty$ if $x<0$
5058    /// - $f(x,-\infty)=-\infty$ if $x>0$
5059    /// - $f(x,-\infty)=\infty$ if $x<0$
5060    /// - $f(x,0.0)=0.0$ if $x\geq0$
5061    /// - $f(x,0.0)=-0.0$ if $x<0$
5062    /// - $f(x,-0.0)=-0.0$ if $x\geq0$
5063    /// - $f(x,-0.0)=0.0$ if $x<0$
5064    ///
5065    /// # Worst-case complexity
5066    /// $T(n) = O(n \log n \log\log n)$
5067    ///
5068    /// $M(n) = O(n \log n)$
5069    ///
5070    /// where $T$ is time, $M$ is additional memory, and $n$ is `max(self.significant_bits(),
5071    /// other.significant_bits())`.
5072    ///
5073    /// # Examples
5074    /// ```
5075    /// use malachite_base::num::basic::traits::{Infinity, NaN, NegativeInfinity};
5076    /// use malachite_base::num::conversion::traits::ExactFrom;
5077    /// use malachite_float::Float;
5078    /// use malachite_q::Rational;
5079    ///
5080    /// assert!((&Rational::exact_from(1.5) * &Float::NAN).is_nan());
5081    /// assert_eq!(
5082    ///     &Rational::exact_from(1.5) * &Float::INFINITY,
5083    ///     Float::INFINITY
5084    /// );
5085    /// assert_eq!(
5086    ///     &Rational::exact_from(1.5) * &Float::NEGATIVE_INFINITY,
5087    ///     Float::NEGATIVE_INFINITY
5088    /// );
5089    /// assert_eq!(
5090    ///     &Rational::exact_from(-1.5) * &Float::INFINITY,
5091    ///     Float::NEGATIVE_INFINITY
5092    /// );
5093    /// assert_eq!(
5094    ///     &Rational::exact_from(-1.5) * &Float::NEGATIVE_INFINITY,
5095    ///     Float::INFINITY
5096    /// );
5097    ///
5098    /// assert_eq!(&Rational::exact_from(1.5) * &Float::from(2.5), 4.0);
5099    /// assert_eq!(&Rational::exact_from(-1.5) * &Float::from(2.5), -4.0);
5100    /// assert_eq!(&Rational::exact_from(1.5) * &Float::from(-2.5), -4.0);
5101    /// assert_eq!(&Rational::exact_from(-1.5) * &Float::from(-2.5), 4.0);
5102    /// ```
5103    #[inline]
5104    fn mul(self, other: &Float) -> Float {
5105        let prec = other.significant_bits();
5106        other.mul_rational_prec_round_ref_ref(self, prec, Nearest).0
5107    }
5108}