malachite_float/arithmetic/
shl.rs

1// Copyright © 2025 Mikhail Hogrefe
2//
3// This file is part of Malachite.
4//
5// Malachite is free software: you can redistribute it and/or modify it under the terms of the GNU
6// Lesser General Public License (LGPL) as published by the Free Software Foundation; either version
7// 3 of the License, or (at your option) any later version. See <https://www.gnu.org/licenses/>.
8
9use crate::Float;
10use crate::malachite_base::num::arithmetic::traits::{ShlRound, ShlRoundAssign};
11use core::ops::{Shl, ShlAssign};
12use malachite_base::rounding_modes::RoundingMode::*;
13
14macro_rules! impl_shl {
15    ($t:ident) => {
16        impl Shl<$t> for Float {
17            type Output = Float;
18
19            /// Left-shifts a [`Float`] (multiplies it by a power of 2), taking it by value.
20            ///
21            /// `NaN`, infinities, and zeros are unchanged. If the [`Float`] has a precision, the
22            /// output has the same precision.
23            ///
24            /// $$
25            /// f(x, k) = x2^k.
26            /// $$
27            ///
28            /// - If $f(x,k)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
29            /// - If $f(x,k)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
30            /// - If $0<f(x,k)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
31            /// - If $2^{-2^{30}-1}<f(x,k)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
32            /// - If $-2^{-2^{30}-1}\leq f(x,k)<0$, $-0.0$ is returned instead.
33            /// - If $-2^{-2^{30}}<f(x,k)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
34            ///
35            /// Constant time and additional memory.
36            ///
37            /// # Examples
38            /// See [here](super::shl#shl).
39            #[inline]
40            fn shl(self, bits: $t) -> Float {
41                self.shl_round(bits, Nearest).0
42            }
43        }
44
45        impl Shl<$t> for &Float {
46            type Output = Float;
47
48            /// Left-shifts a [`Float`] (multiplies it by a power of 2), taking it by value.
49            ///
50            /// `NaN`, infinities, and zeros are unchanged. If the [`Float`] has a precision, the
51            /// output has the same precision.
52            ///
53            /// $$
54            /// f(x, k) = x2^k.
55            /// $$
56            ///
57            /// - If $f(x,k)\geq 2^{2^{30}-1}$, $\infty$ is returned instead.
58            /// - If $f(x,k)\leq -2^{2^{30}-1}$, $-\infty$ is returned instead.
59            /// - If $0<f(x,k)\leq2^{-2^{30}-1}$, $0.0$ is returned instead.
60            /// - If $2^{-2^{30}-1}<f(x,k)<2^{-2^{30}}$, $2^{-2^{30}}$ is returned instead.
61            /// - If $-2^{-2^{30}-1}\leq f(x,k)<0$, $-0.0$ is returned instead.
62            /// - If $-2^{-2^{30}}<f(x,k)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is returned instead.
63            ///
64            /// Constant time and additional memory.
65            ///
66            /// # Examples
67            /// See [here](super::shl#shl).
68            #[inline]
69            fn shl(self, bits: $t) -> Float {
70                self.shl_round(bits, Nearest).0
71            }
72        }
73
74        impl ShlAssign<$t> for Float {
75            /// Left-shifts a [`Float`] (multiplies it by a power of 2), in place. If the [`Float`]
76            /// has a precision, the precision is unchanged.
77            ///
78            /// `NaN`, infinities, and zeros are unchanged.
79            ///
80            /// $$
81            /// x \gets x2^k.
82            /// $$
83            ///
84            /// - If $f(x,k)\geq 2^{2^{30}-1}$, $\infty$ is assigned instead.
85            /// - If $f(x,k)\leq -2^{2^{30}-1}$, $-\infty$ is assigned instead.
86            /// - If $0<f(x,k)\leq2^{-2^{30}-1}$, $0.0$ is assigned instead.
87            /// - If $2^{-2^{30}-1}<f(x,k)<2^{-2^{30}}$, $2^{-2^{30}}$ is assigned instead.
88            /// - If $-2^{-2^{30}-1}\leq f(x,k)<0$, $-0.0$ is assigned instead.
89            /// - If $-2^{-2^{30}}<f(x,k)<-2^{-2^{30}-1}$, $-2^{-2^{30}}$ is assigned instead.
90            ///
91            /// Constant time and additional memory.
92            ///
93            /// # Examples
94            /// See [here](super::shl#shl_assign).
95            #[inline]
96            fn shl_assign(&mut self, bits: $t) {
97                self.shl_round_assign(bits, Nearest);
98            }
99        }
100    };
101}
102apply_to_primitive_ints!(impl_shl);