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);