Skip to main content

malachite_float/float/arithmetic/
mul.rs

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