为什么^1等于-2?

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

Why does ^1 equal -2?

问题

这段代码打印出"-2"的原因是因为^是按位取反运算符,它会将操作数的每个位取反。在这个例子中,操作数是1,它的二进制表示是00000001。按位取反后,得到的结果是11111110,即二进制补码表示的-2。

英文:
fmt.Println(^1)

Why does this print -2?

答案1

得分: 2

^ 运算符是按位取反运算符。规范:算术运算符

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

+x                          等于 0 + x
-x    取反                  等于 0 - x
^x    按位取反              等于 m ^ x,其中 m = "所有位都设置为1"(对于无符号的x)
                                      m = -1(对于有符号的x)

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

0000000000000000000000000000000000000000000000000000000000000001

因此按位取反是一个前面全是1的单个0位:

1111111111111111111111111111111111111111111111111111111111111110

^1 是一个无类型的常量表达式。当它传递给一个函数时,它必须被转换为某种类型。由于 1 是一个无类型整数常量,它的默认类型 int 将被使用。在 Go 中,int 使用 2 的补码 表示,其中负数以 1 开头。全是1的数是 -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
英文:

The ^ operator is the bitwise complement operator. Spec: Arithmetic operators:

> For integer operands, the unary operators +, -, and ^ are defined as follows:
>
> +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

So 1 in binary is a single 1 bit preceded with full of zeros:

0000000000000000000000000000000000000000000000000000000000000001

So the bitwise complement is a single 0 bit preceded by full of ones:

1111111111111111111111111111111111111111111111111111111111111110

The ^1 is an untyped constant expression. When it is passed to a function, it has to be converted to a type. Since 1 is an untyped integer constant, its default type int will be used. int in Go is represented using the 2's complement where negative numbers start with a 1. The number being full ones is -1, the number being smaller by one (in binary) is -2 etc.

The bit pattern above is the 2's complement representation of -2.

To print the bit patterns and type, use this code:

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

It outputs (try it on the Go Playground):

-2
int
0000000000000000000000000000000000000000000000000000000000000001
1111111111111111111111111111111111111111111111111111111111111110

答案2

得分: 0

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

对于一个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 异或
-------
1110 -> 实际上是-2。

所有这些都是因为我们在计算负数时使用的二进制补码约定。当然,这可以推广到更长的二进制数。

你可以使用Windows计算器进行按位异或计算来测试这一点。

英文:

Okay, this has to do with the way that we use signed signs in computation.

For a 1 byte number, you can get

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

You can see here that 1 is equivalent to 0001 (Nothing changes) but -1 is equal to 1111. ^ operator does a bitwise xor operation. Therefore:

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

All this is because of the convention of two complement that we use to do calculations with negative numbers. Of course, this can be extrapolated to longer binary numbers.

You can test this by using windows calculator to do a xor bitwise calculation.

huangapple
  • 本文由 发表于 2022年4月12日 05:45:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/71834634.html
匿名

发表评论

匿名网友

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

确定