英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论