Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions integer/src/bits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,8 +497,13 @@ mod repr {

#[inline]
fn are_dword_low_bits_nonzero(dword: DoubleWord, n: usize) -> bool {
let n = n.min(WORD_BITS_USIZE) as u32;
dword & ones_dword(n) != 0
// For n >= DWORD_BITS, every bit of the dword is "low" so just test for any
// set bit. `ones_dword(DWORD_BITS as u32)` would underflow its shift, so we
// must early-return here rather than rely on it.
if n >= DWORD_BITS_USIZE {
return dword != 0;
}
dword & ones_dword(n as u32) != 0
}

fn are_slice_low_bits_nonzero(words: &[Word], n: usize) -> bool {
Expand Down
7 changes: 7 additions & 0 deletions integer/tests/shift.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,13 @@ fn test_ibig_shr() {
((ibig!(-0xff) << 1000) - ibig!(1), 1000, ibig!(-0x100)),
((ibig!(-0xff) << 1000) - (ibig!(1) << 999), 1000, ibig!(-0x100)),
(ibig!(-0xff) << 1000, 2000, ibig!(-1)),
// A negative magnitude whose highest set bit sits in the upper word
// of a DoubleWord, shifted by an amount that equals or exceeds its
// bit length, must round toward -infinity to -1.
(-(ibig!(1) << 127), 127, ibig!(-1)),
(-(ibig!(1) << 127), 128, ibig!(-1)),
(-(ibig!(1) << 127), 200, ibig!(-1)),
(-(ibig!(1) << 64), 128, ibig!(-1)),
];
for (a, b, c) in &test_cases {
assert_eq!(a >> b, *c);
Expand Down
Loading