在Rust中的位移操作符中进行符号扩展

huangapple go评论121阅读模式
英文:

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. 有了这种填充方式,对于负数,`>> 1` 永远等于 `/ 2` 是正确的。或者在我们的例子中,右移 `2` 等同于除以 `4`
  2. 左移 (`<<`) 总是用 `0` 填充。这导致 `<< 1` 等同于 `* 2`,对于负数也没有特殊情况。
  3. 有关整数在二进制中如何表示的更多信息,请阅读有关[二进制补码](https://en.wikipedia.org/wiki/Two%27s_complement)的内容。
英文:
  1. Signed:
  2. 64 (0b01000000) >> 2 = 16 (0b00010000) // filled with 0, because sign is positive
  3. -64 (0b11000000) >> 2 = -16 (0b11110000) // filled with 1, because sign is negative
  4. Unsigned:
  5. 64 (0b01000000) >> 2 = 16 (0b00010000) // filled with 0, because unsigned
  6. 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:

  1. fn main() {
  2. println!("Signed:");
  3. println!(
  4. " {} ({:#010b}) >> 2 = {} ({:#010b}) // filled with 0, because sign is positive",
  5. 64i8,
  6. 64i8,
  7. 64i8 >> 2,
  8. 64i8 >> 2
  9. );
  10. println!(
  11. " {} ({:#010b}) >> 2 = {} ({:#010b}) // filled with 1, because sign is negative",
  12. -64i8,
  13. -64i8,
  14. -64i8 >> 2,
  15. -64i8 >> 2
  16. );
  17. println!();
  18. println!("Unsigned:");
  19. println!(
  20. " {} ({:#010b}) >> 2 = {} ({:#010b}) // filled with 0, because unsigned",
  21. 64u8,
  22. 64u8,
  23. 64u8 >> 2,
  24. 64u8 >> 2
  25. );
  26. println!(
  27. " {} ({:#010b}) >> 2 = {} ({:#010b}) // filled with 0, because unsigned",
  28. (-64i8) as u8,
  29. (-64i8) as u8,
  30. (-64i8) as u8 >> 2,
  31. (-64i8) as u8 >> 2
  32. );
  33. }

huangapple
  • 本文由 发表于 2023年4月11日 13:00:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/75982535.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定