【问题标题】:Why does ^1 equal -2?为什么 ^1 等于 -2?
【发布时间】:2022-04-12 15:19:38
【问题描述】:
fmt.Println(^1)

为什么会打印-2

标签: go bitwise-operators twos-complement


【解决方案1】:

^ 运算符是按位补码运算符。 Spec: Arithmetic operators:

对于整数操作数,一元运算符+-^ 定义如下:

+x                          is 0 + x
-x    negation              is 0 - x
^x    bitwise complement    is m ^ x  with m = "all bits set to 1" for unsigned x
                                      and  m = -1 for signed x

所以二进制中的1 是一个单一的 1 位,前面是全零:

0000000000000000000000000000000000000000000000000000000000000001

所以按位补码是一个 0 位,前面有一个全 1:

1111111111111111111111111111111111111111111111111111111111111110

^1 是一个无类型的常量表达式。当它被传递给一个函数时,它必须被转换为一个类型。由于1 是无类型整数constant,因此将使用其默认类型int。 Go 中的int 使用2's complement 表示,其中负数以1 开头。完整的数字是-1,小一的数字(二进制​​)是-2等。

上面的位模式是-2 的 2 的补码表示。

要打印位模式和类型,请使用以下代码:

fmt.Println(^1)
fmt.Printf("%T\n", ^1)
fmt.Printf("%064b\n", 1)
i := ^1
fmt.Printf("%064b\n", uint(i))

它输出(在Go Playground 上尝试):

-2
int
0000000000000000000000000000000000000000000000000000000000000001
1111111111111111111111111111111111111111111111111111111111111110

【讨论】:

    【解决方案2】:

    好的,这与我们在计算中使用符号的方式有关。

    对于一个 1 字节的数字,你可以得到

    D B
    -8 1000
    -7 1001
    -6 1010
    -5 1011
    -4 1100
    -3 1101
    -2 1110
    -1 1111
    0 0000
    1 0001
    2 0010
    3 0011
    4 0100
    5 0101
    6 0110
    7 0111

    您可以在此处看到 1 等于 0001(没有任何变化),但 -1 等于 1111。^ 运算符执行按位异或运算。所以:

    0001
    1111 xor
    -------
    1110 -> That is actually -2. 
    

    这一切都是因为two complement 的约定,我们用它来进行负数计算。当然,这可以外推到更长的二进制数。

    您可以通过使用 windows 计算器进行异或位计算来测试这一点。

    【讨论】:

      猜你喜欢
      • 2014-07-04
      • 2013-08-17
      • 1970-01-01
      • 1970-01-01
      • 2016-05-14
      • 1970-01-01
      • 2013-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多