为什么按位NOT运算符(在大多数语言中为~
)会转换以下值,如下所示:
-2 -> 1
-1 -> 0
0 -> -1
1 -> -2
不应该-2
转换为2
,1
转换为-1
等?
有关多种语言中负整数的表示,请参阅two's complement。如您所见,-2由1111110
表示;如果你反转所有这些位,你得到0000001
,即值为1。
如果你用二进制看它会很有帮助。
首先,如您所知,负数表示为(最高可能的无符号数加1减去值)。因此,具有最高无符号值65535的16位整数中的-1将是65536-1 = 65535,即十六进制中的0xffff或二进制中的1111 1111 1111 1111
。
所以:
1 in binary = 0000 0000 0000 0001
不是所有位都会导致1111 1111 1111 1110
。以十进制表示的是65534.而65536减去65534是2,所以这是-2。
这是由于负数如何表示为位。为此,最常使用Two's Complements。
在这种表示法中,-2恰好是1111110,否则为1
这是因为逐位运算符实际上反转了字中的每个位。它不是严格的算术运算,而是逻辑运算。
-2 == %1110, ~-2 == ~%1110 = %0001 == 1 -1 == %1111, ~-1 == ~%1111 = %0000 == 0
等等。
要从-2到2,从1到-1,您需要使用算术否定操作。
Dim mask As Integer = -1
'11111111111111111111111111111111
For x As Integer = -3 To 3
Dim i As Integer = x
Debug.WriteLine("")
Debug.WriteLine("'" & Convert.ToString(i, 2).PadLeft(32, "0"c) & " > Num = " & i.ToString)
i = i Xor mask 'reverse the bits (same as Not)
Debug.WriteLine("'" & Convert.ToString(i, 2).PadLeft(32, "0"c) & " > Not = " & i.ToString)
i += 1 'convert to two's complement
Debug.WriteLine("'" & Convert.ToString(i, 2).PadLeft(32, "0"c) & " > 2's Comp = " & i.ToString)
Next
'debug results
'11111111111111111111111111111101 > Num = -3
'00000000000000000000000000000010 > Not = 2
'00000000000000000000000000000011 > 2's Comp = 3
'11111111111111111111111111111110 > Num = -2
'00000000000000000000000000000001 > Not = 1
'00000000000000000000000000000010 > 2's Comp = 2
'11111111111111111111111111111111 > Num = -1
'00000000000000000000000000000000 > Not = 0
'00000000000000000000000000000001 > 2's Comp = 1
'00000000000000000000000000000000 > Num = 0
'11111111111111111111111111111111 > Not = -1
'00000000000000000000000000000000 > 2's Comp = 0
'00000000000000000000000000000001 > Num = 1
'11111111111111111111111111111110 > Not = -2
'11111111111111111111111111111111 > 2's Comp = -1
'00000000000000000000000000000010 > Num = 2
'11111111111111111111111111111101 > Not = -3
'11111111111111111111111111111110 > 2's Comp = -2
'00000000000000000000000000000011 > Num = 3
'11111111111111111111111111111100 > Not = -4
'11111111111111111111111111111101 > 2's Comp = -3
大多数(所有?)现代架构使用two's complement来表示有符号整数。因此,按位NOT是整数的补码减1。
计算机系统中的数字存储为2个互补。如果数字是正数,那么正数的2个补码是相同的。但是对于负数,它是不同的。
1.-2 - > 1这里-2将作为1110存储在计算机中(即-2的2的补码)。现在的1110是0001.因为0001是正数,它将作为0001存储在计算机中(即1)
2.-1 - > 0这里-1将作为1111存储在计算机中(即2的补码为-1)。现在1111是0000.由于0000是正数,它将作为0000存储在计算机中(即0)