按位非运算符的解释
Posted
技术标签:
【中文标题】按位非运算符的解释【英文标题】:Explanation of Bitwise NOT Operator 【发布时间】:2010-11-28 05:41:45 【问题描述】:为什么按位非运算符(大多数语言中为~
)会像这样转换以下值:
-2 -> 1
-1 -> 0
0 -> -1
1 -> -2
不应该将-2
转换为2
、1
转换为-1
等吗?
【问题讨论】:
附录:注意bitwise NOT
几乎总是最快的将字符串解析为数字:jsperf.com/number-vs-plus-vs-toint-vs-tofloat/20
【参考方案1】:
请参阅two's complement 了解负整数在许多语言中的表示。可以看到,-2 用1111110
表示;如果你反转所有这些位,你会得到0000001
,即值 1。
【讨论】:
~0 怎么样?我无法得到它。请帮忙 它是 -1 .... ~(0000) = 1111 .... 通过反向二进制补码将 1111 转换为十进制:1111 - 1 = 1110 -> 0001 = 1 -> -1 .最终,按位 NOT 对数字所做的数学函数是~x = (-1 * (x+1))
@Vicrobot 按照上面提供的链接了解更多详细信息。按位在二进制级别上工作,因此二进制上的 0 将被视为 0000_0000,并且(在二进制补码中)-1 是 1111_1111,这不是 0 将所有位翻转为 1,因此将 0 更改为 -1。但在无符号类型(如 C# uint)中,它将是可能的最大值。【参考方案2】:
如果您以二进制形式查看它会有所帮助。
首先,如您所知,负数表示为(最大可能的无符号数加 1 负值)。因此,16 位整数中的 -1(最高无符号值为 65535)将是 65536-1=65535,即十六进制的 0xffff 或二进制的 1111 1111 1111 1111
。
所以:
二进制中的 1 = 0000 0000 0000 0001
不是所有位都会导致1111 1111 1111 1110
。十进制是 65534。而 65536 减去 65534 是 2,所以这是 -2。
【讨论】:
【参考方案3】: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
【讨论】:
【参考方案4】:这是由于负数如何表示为位。为此,最常用的是Two's Complements。
-2 在这个符号中恰好是 1111110,取反是 1
【讨论】:
【参考方案5】:大多数(全部?)现代架构使用two's complement 来表示有符号整数。因此,按位 NOT 是整数减一的补码。
【讨论】:
【参考方案6】:这是因为按位运算符将字中的每一位逐位取反。 这不是严格意义上的算术运算,而是逻辑运算。
-2 == %1110, ~-2 == ~%1110 = %0001 == 1
-1 == %1111, ~-1 == ~%1111 = %0000 == 0
等等。
要从 -2 到 2,以及从 1 到 -1,您需要使用算术否定运算。
【讨论】:
【参考方案7】:计算机系统中的数字存储为 2 互补。 如果数字是正数,则正数的 2 个补码相同。但对于负数,则不同。
-2 -> 1
这里 -2 将作为 1110 存储在计算机中(即 -2 的 2 的补码)。现在 1110 的~
是 0001。由于 0001 是正数,它将在计算机中存储为 0001(即 1)
-1 -> 0
这里 -1 将作为 1111 存储在计算机中(即 -1 的 2 的补码)。现在 1111 的~
是 0000。由于 0000 是正数,它将在计算机中存储为 0000(即 0)
0 -> -1
这里 0 将作为 0000 存储在计算机中(即 0 的 2 的补码)。现在~
of 0000 是 1111。由于 1111 是负数,它将作为 0001(即 -1)存储在计算机中(由于 MSB 设置为 1111,因此该数字将为负数)
1 -> -2
这里 1 将作为 0001 存储在计算机中(即 1 的 2 的补码)。现在 0001 的 ~
是 1110。由于 1110 是负数,它将作为 0010(即-2)存储在计算机中(由于 MSB 设置为 1110,因此该数字将为负数)
【讨论】:
以上是关于按位非运算符的解释的主要内容,如果未能解决你的问题,请参考以下文章