【问题标题】:Sign of integer and binary AND check整数符号和二进制与检查
【发布时间】:2020-06-28 11:03:01
【问题描述】:

如果我在 C++ 中是正确的,则 LSB 是最后一位并确定整数的符号。因此,例如,如果是 8 位 1111 1111 将是 -127 而 1111 1110 将是 127。如果我错了,请纠正我,但这不相关。

我会在 Go 中检查整数的符号,所以我写了以下内容:

func signCheck(n int8) {
    var sign int8 = 1<<7

    if n&sign == 1 {
        fmt.Printf("%d is odd - %b\n", n, n)
    } else {
        fmt.Printf("%d is even - %b\n", n, n)
    }
}

这将打印出“constant 128 overflows int8”,但这是有道理的,因为只有 7 位用于确定一个数字。所以我修改如下:

func signCheck(n int8) {
    if n&1<<7 == 1 {
        fmt.Printf("%d is odd - %b\n", n, n)
    } else {
        fmt.Printf("%d is even - %b\n", n, n)
    }
}

在这种情况下,我不必说它是 int8,但我用 -127 和 127 对其进行了测试,得到了以下打印结果:

-127 is even - -1111111
127 is even - 1111111

那么在这种情况下,我应该如何检查标志? go 版本 go1.13.1 linux/amd64

【问题讨论】:

    标签: go binary-operators


    【解决方案1】:

    为了表示负整数,Go(我相信 C++ 也像大多数语言一样)使用 2's complement 格式和标准。

    在 2 的补码中,如果数字为负数,最高位 (MSB) 将为 1,否则为 0

    在 Go 中,您不能使用具有 int8 作为其类型的 0x80 类型常量,因为这超出了其有效范围。

    但是,您可以“无损”地将int8 转换为uint8,然后您就可以这样做了。

    另外,当您屏蔽0x80 位时,您必须将结果与0x80 进行比较,因为x &amp; 0x80 永远不会产生1,只能产生00x80

    func signCheck(n int8) {
        if uint8(n)&0x80 == 0x80 {
            fmt.Printf("%d is negative - %b\n", n, n)
        } else {
            fmt.Printf("%d is non-negative - %b\n", n, n)
        }
    }
    

    另一种选择是将屏蔽结果与0进行比较:

    if uint8(n)&0x80 != 0 { }
    

    两种解决方案都给出了输出(在Go Playground 上尝试):

    -127 is negative - -1111111
    127 is non-negative - 1111111
    

    【讨论】:

    • 请注意,标准 C 允许补码和符号和大小(请参阅 retrocomputing.stackexchange.com/questions/7095/…)。我不确定 C++ 是否允许它,尽管浮点数是符号和大小,但现在没有人真正使用二进制补码以外的任何东西。
    猜你喜欢
    • 1970-01-01
    • 2019-02-23
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 2019-08-20
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多