按位非运算符的解释

Posted

技术标签:

【中文标题】按位非运算符的解释【英文标题】:Explanation of Bitwise NOT Operator 【发布时间】:2010-11-28 05:41:45 【问题描述】:

为什么按位非运算符(大多数语言中为~)会像这样转换以下值:

-2 -> 1-1 -> 00 -> -11 -> -2

不应该将-2 转换为21 转换为-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,因此该数字将为负数)

【讨论】:

以上是关于按位非运算符的解释的主要内容,如果未能解决你的问题,请参考以下文章

JS按位非(~)运算符与~~运算符的理解分析

位运算符按位与按位或按位非左移右移原码反码补码

需要对按位非 (~) 运算符进行说明

JS按位非(~)运算符与~~运算符的理解分析

位运算

java中的位运算