Skip to content

Commit 5d8b135

Browse files
committed
impl Shl for i256, and add trailing_zeros in trait Int
1 parent ff52c97 commit 5d8b135

File tree

2 files changed

+30
-27
lines changed

2 files changed

+30
-27
lines changed

libm/src/math/support/big.rs

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -148,42 +148,39 @@ macro_rules! impl_common {
148148
Self { lo, hi }
149149
}
150150
}
151-
};
152-
}
153151

154-
impl_common!(i256);
155-
impl_common!(u256);
152+
impl ops::Shr<u32> for $ty {
153+
type Output = Self;
156154

157-
impl ops::Shr<u32> for u256 {
158-
type Output = Self;
155+
fn shr(mut self, rhs: u32) -> Self::Output {
156+
debug_assert!(rhs < Self::BITS, "attempt to shift right with overflow");
159157

160-
fn shr(mut self, rhs: u32) -> Self::Output {
161-
debug_assert!(rhs < Self::BITS, "attempted to shift right with overflow");
162-
if rhs >= Self::BITS {
163-
return Self::ZERO;
164-
}
158+
let half_bits = Self::BITS / 2;
159+
let low_mask = half_bits - 1;
160+
let s = rhs & low_mask;
165161

166-
if rhs == 0 {
167-
return self;
168-
}
162+
let lo = self.lo;
163+
let hi = self.hi;
169164

170-
if rhs < 128 {
171-
self.lo >>= rhs;
172-
self.lo |= self.hi << (128 - rhs);
173-
} else {
174-
self.lo = self.hi >> (rhs - 128);
175-
}
165+
self.hi = hi >> s;
176166

177-
if rhs < 128 {
178-
self.hi >>= rhs;
179-
} else {
180-
self.hi = 0;
167+
#[allow(unused_comparisons)]
168+
if rhs & half_bits == 0 {
169+
self.lo = (hi << (low_mask ^ s) << 1) as _;
170+
self.lo |= lo >> s;
171+
} else {
172+
self.lo = self.hi as _;
173+
self.hi = if hi < 0 { !0 } else { 0 };
174+
}
175+
self
176+
}
181177
}
182-
183-
self
184-
}
178+
};
185179
}
186180

181+
impl_common!(i256);
182+
impl_common!(u256);
183+
187184
impl HInt for u128 {
188185
type D = u256;
189186

libm/src/math/support/int_traits.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub trait MinInt:
99
+ ops::BitOr<Output = Self>
1010
+ ops::Not<Output = Self>
1111
+ ops::Shl<u32, Output = Self>
12+
+ ops::Shr<u32, Output = Self>
1213
+ ops::Add<Output = Self>
1314
+ ops::Sub<Output = Self>
1415
{
@@ -103,6 +104,7 @@ pub trait Int:
103104
fn carrying_add(self, other: Self, carry: bool) -> (Self, bool);
104105
fn borrowing_sub(self, other: Self, borrow: bool) -> (Self, bool);
105106
fn leading_zeros(self) -> u32;
107+
fn trailing_zeros(self) -> u32;
106108
fn ilog2(self) -> u32;
107109
}
108110

@@ -168,6 +170,10 @@ macro_rules! int_impl_common {
168170
<Self>::leading_zeros(self)
169171
}
170172

173+
fn trailing_zeros(self) -> u32 {
174+
<Self>::trailing_zeros(self)
175+
}
176+
171177
fn ilog2(self) -> u32 {
172178
// On our older MSRV, this resolves to the trait method. Which won't actually work,
173179
// but this is only called behind other gates.

0 commit comments

Comments
 (0)