英文:
sign extending in shift operators in rust
问题
"Bit shifting is always sign-extending on signed integer types and zero-extending on unsigned integer types"
我的问题是什么是"always sign-extending"?如果可能的话,提供一个例子。在Rust中,如何处理移位操作的溢出和下溢。
谢谢您提前为您的时间和帮助。
英文:
I am reading rust programming language using book Programming Rust 2nd edition. Here in context of right shift operators and left shift operators mentioned as below
> Bit shifting is always sign-extending on signed integer types and zero-extending on unsigned integer types
My question is what is "always sign-extending"? If possible, provide an example. How overflowing and underflowing is handled in shift operators in Rust.
Thanks in advance for your time and help.
答案1
得分: 6
有了这种填充方式,对于负数,`>> 1` 永远等于 `/ 2` 是正确的。或者在我们的例子中,右移 `2` 等同于除以 `4`。
左移 (`<<`) 总是用 `0` 填充。这导致 `<< 1` 等同于 `* 2`,对于负数也没有特殊情况。
有关整数在二进制中如何表示的更多信息,请阅读有关[二进制补码](https://en.wikipedia.org/wiki/Two%27s_complement)的内容。
英文:
Signed:
64 (0b01000000) >> 2 = 16 (0b00010000) // filled with 0, because sign is positive
-64 (0b11000000) >> 2 = -16 (0b11110000) // filled with 1, because sign is negative
Unsigned:
64 (0b01000000) >> 2 = 16 (0b00010000) // filled with 0, because unsigned
192 (0b11000000) >> 2 = 48 (0b00110000) // filled with 0, because unsigned
With that way of padding, it is always true that a >> 1
is equal to a / 2
, even for negative numbers. Or in our example, a right shift of 2
is equal to a division through 4
.
Left shifts (<<
) are always padded with 0
. This again causes << 1
to be equal to * 2
, no special case for negative numbers is needed here.
For more information about how integers are represented in binary, read about the two's complement.
Source:
fn main() {
println!("Signed:");
println!(
" {} ({:#010b}) >> 2 = {} ({:#010b}) // filled with 0, because sign is positive",
64i8,
64i8,
64i8 >> 2,
64i8 >> 2
);
println!(
" {} ({:#010b}) >> 2 = {} ({:#010b}) // filled with 1, because sign is negative",
-64i8,
-64i8,
-64i8 >> 2,
-64i8 >> 2
);
println!();
println!("Unsigned:");
println!(
" {} ({:#010b}) >> 2 = {} ({:#010b}) // filled with 0, because unsigned",
64u8,
64u8,
64u8 >> 2,
64u8 >> 2
);
println!(
" {} ({:#010b}) >> 2 = {} ({:#010b}) // filled with 0, because unsigned",
(-64i8) as u8,
(-64i8) as u8,
(-64i8) as u8 >> 2,
(-64i8) as u8 >> 2
);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论