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

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

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
    );
}

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:

确定