Bitshift and overflowing behavior


#1

G’day folks!

I’m looking for simple, straightforward, traditional bitshift behavior and can’t find it in the Rust docs.

I assume that because, 1u32 << 32 overflows, it panics because overflow is defined as undefined, or something.

But what if I don’t want it to panic? What if I want 1u32 << 32 == 0?

So I found wrapping_shl and it’s unstable companion overflowing_shl(), but I find the behavior of those bizarre. Maybe I just haven’t come across the use case where the shift should keep wrapping around. It doesn’t seem generally useful for std::u32::MAX << 32 == std::u32::MAX

Is there any way to do a simple overflowing shift that doesn’t wrap and doesn’t panic without an excess of anding and conditional instructions when one basic shl instruction will do? Or do I basically have to use a condition to return 0 when the shift would overflow?

Thanks for any advice!


#2

Unless I’m misreading things, x86 will mask the shift width to the range 0 to 31, so a 32 bit shift will be a noop. See page 4-340 of the Instruction Set Reference.

checked_shl and checked_shr methods seem to be missing but make sense to add, IMO, at which point your desired behavior would be a.checked_shl(b).unwrap_or(0).


#3

Wow you’re right. I’m relying on a 20 year old memory of shl behavior on x86 and I never recalled that the instruction itself masks the shift.

Thanks for setting me straight!