2010-11-28 30 views
11

为什么是它的位NOT(在大多数语言~)运算符将像下面这样的值:位非的说明操作

-2 -> 1
-1 -> 0
0 -> -1
1 -> -2

不应该-2转换为2,1转换为-1等?

+0

附录:有用的注意,'按位NOT`几乎总是最快将字符串解析成一个数字:https://jsperf.com/number-vs-plus-vs-toint-vs-tofloat/20 – 2017-10-11 13:38:41

回答

16

请参阅two's complement以表示多种语言中的负整数。如您所见,-2代表1111110;如果反转所有这些位,则得到0000001,即值为1.

0

大多数(所有?)现代体系结构都使用two's complement来表示带符号整数。按位NOT因此是整数减1的补码

10

如果你在二进制中查看它会有所帮助。首先,如你所知,负数表示为(可能的最高无符号数加1减去数值)。因此,具有最高无符号值65535的16位整数中的-1将是65536-1 = 65535,即十六进制中的0xffff或二进制中的1111 1111 1111 1111

所以:

1的二进制= 0000 0000 0000 0001

不是在所有位会导致1111 1111 1111 1110。那是十进制,是65534.而65536减去65535是1,所以这是-1。

0

这是由于如何将负数表示为位。为此最常使用Two's Complements

-2恰好是在这种表示法,其否定1111110是1

0

这是因为逐位操作者字面上反转在字的每个位。 它不是一个严格的算术运算,它是一个逻辑运算。

-2 ==%1110〜-2 ==〜%1110 = 0001%== 1 -1 ==%1111〜-1 ==〜%1111 = 0000%== 0

等。

要从-2变为2和1变为-1,您需要使用算术否定操作。

0
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