按位非运算符

Posted

技术标签:

【中文标题】按位非运算符【英文标题】:bitwise not operator 【发布时间】:2011-01-31 14:16:25 【问题描述】:

为什么按位运算 (~0); 打印 -1 ?在二进制中,不是 0 应该是 1 。为什么?

【问题讨论】:

如果要翻转一个位,请使用x ^ 1 这不是一个“非”运​​算符。它是一个“补”运算符。 @EJP:一个 one's 补码运算符。 不,不是。语言规范#4.2.2 将“~”定义为“按位补码运算符”。 Java 中没有“NOT 位运算符”这样的东西。 @lh3: 不。它在 C 和 C++ 中都是一个补码运算符。 【参考方案1】:

其实你们很亲近。

在二进制中,不是 0 应该是 1

是的,当我们谈论一点时,这是绝对正确的。

但是,值为 0 的 int 实际上是 32 位全零! ~ 将所有 32 个 0 反转为 32 个 1。

System.out.println(Integer.toBinaryString(~0));
// prints "11111111111111111111111111111111"

这是-1 的二进制补码表示。

同样:

System.out.println(Integer.toBinaryString(~1));
// prints "11111111111111111111111111111110"

也就是说,对于采用二进制补码表示的 32 位无符号 int~1 == -2


进一步阅读:

Two's complement 这是 Java(以及其他)用来表示以位为单位的有符号数值的系统 JLS 15.15.5 Bitwise complement operator ~ “请注意,在所有情况下,~x 等于 (-x)-1

【讨论】:

【参考方案2】:

您实际上是在说〜0x00000000,结果为0xFFFFFFFF。对于 java 中的 (signed) int,这意味着 -1。

【讨论】:

【参考方案3】:

您可以将有符号数的第一位想象为 -(2x -1),其中 x 是位数。

因此,给定一个 8 位数字,每个位的值(按从左到右的顺序)为:

-128 64 32 16 8 4 2 1

现在,在二进制中,0 显然全是 0:

    -128 64 32 16 8 4 2 1
0      0  0  0  0 0 0 0 0 = 0

当你按位而不是~ 时,这些 0 中的每一个都变成 1:

     -128 64 32 16 8 4 2 1
~0      1  1  1  1 1 1 1 1
 =   -128+64+32+16+8+4+2+1 == -1

这也有助于理解溢出:

     -128 64 32 16 8 4 2 1
126     0  1  1  1 1 1 1 0  =  126
 +1     0  1  1  1 1 1 1 1  =  127
 +1     1  0  0  0 0 0 0 0  = -128  overflow!

【讨论】:

【参考方案4】:

~ 是位运算符。

~0 = 1 which is -1 in 2's complement form  

http://en.wikipedia.org/wiki/Two's_complement

一些二进制补码形式的数字和它们的位不是~(就在它们下面):

0 1 1 1 1 1 1 1 = 127 1 0 0 0 0 0 0 0 = -128

0 1 1 1 1 1 1 0 = 126 1 0 0 0 0 0 0 1 = -127

1 1 1 1 1 1 1 1 = -1 0 0 0 0 0 0 0 0 = 0

1 1 1 1 1 1 1 0 = -2 0 0 0 0 0 0 0 1 = 1

1 0 0 0 0 0 0 1 = -127 0 1 1 1 1 1 1 0 = 126

1 0 0 0 0 0 0 0 = -128 0 1 1 1 1 1 1 1 = 127

【讨论】:

+1 为清楚的例子。喜欢解谜的程序员只要仔细研究你的例子,就可以知道 ~ 是如何工作的,以及二进制补码是如何工作的!【参考方案5】:

因为~ 不是二进制反转,而是按位反转。二进制反转为 ! 并且只能(在 Java 中)应用于布尔值。

【讨论】:

【参考方案6】:

在标准二进制编码中,0 都是 0,~ 是按位非。对于有符号整数类型,全 1(通常)为 -1。所以对于有符号字节类型:

0xFF = -1    // 1111 1111
0xFE = -2    // 1111 1110
...
0xF0 = -128  // 1000 0000
0x7F = 127   // 0111 1111
0x7E = 126   // 0111 1110
...
0x01 = 1     // 0000 0001
0x00 = 0     // 0000 0000

【讨论】:

【参考方案7】:

这是二进制反转,第二个补码-1是0的二进制反转。

【讨论】:

【参考方案8】:

这里的0不是一点点。它是一个字节(至少;或更多)- 00000000。使用按位或我们将得到 11111111。它是 -1 作为有符号整数...

【讨论】:

【参考方案9】:

对于 32 位有符号整数

~00000000000000000000000000000000=11111111111111111111111111111111(即-1)

【讨论】:

【参考方案10】:

我认为真正的原因是~是二进制补码。

javascript 将波形符 ~ 指定为二进制补码,尽管在大多数编程语言中,波形符表示一个补码的位切换。

【讨论】:

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

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

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

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

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

位运算

java中的位运算