我最近参加了 Java 类(class)(为期一周的速成类(class)),我们讲了一些二进制数学。
这个一元 ~ 运算符(波浪号,我想它叫什么?)是这样向我们解释的:
它反转位模式,将每个“0”变为“1”,将每个“1”变为“0”。 例如一个字节有 8 位。如果您有以下字节:00000000,则反转后的值将变为 11111111。
以上解释简明扼要,对我来说完全有道理。直到,也就是说,我尝试实现它。
鉴于此:
byte x = 3;
byte y = 5;
System.out.println(~x);
System.out.println(~y);
输出是:
-4
-6
我很困惑这是怎么发生的。
如果 +3 在二进制中是 11,那么它的倒数就是 00,这显然不是 -3。
但是一个字节有8位,那么+3的二进制表示不应该写成00000011吗?
这将反转为 11111100。转换回十进制值将为 252。 但是,如果您将 +3 写为 011,那么它确实会转换为 100,也就是 +4,但是您怎么知道它是负数?
如果您尝试将 0011 转换为 1100 怎么样,如果您将第一位用作符号,那么它确实会变成 -4。
啊 - 所以在这一点上,我认为我正在取得进展。
但后来我得到了 y = 5 的第二个值。
我们怎么写这个?使用相同的逻辑,+5 转换为二进制 0101,它反转为 1010。
现在我非常困惑。这看起来代表一个有符号的值 -2,或者一个无符号的值 +10 十进制?这两个都不是我打印出来的 -6。
同样,如果我将长度增加到一个字节的 8 位数字,+5 就是 00000101,倒过来就是 11111010。我实在找不到办法把它变成 -6。
有没有人明白这一点,因为我不知道这里发生了什么,我打印的数字越多,我就越困惑。
Google 似乎并没有在这方面提出任何建议 - 也许它不喜欢看小的运算符(operator)标志.. :-(
最佳答案
看这个演示:-
3 -> 0011
~3 -> 1100 -> -4 (2's complement)
5 -> 0101
~5 -> 1010 -> -6 (2's complement)
由于有符号整数存储为 2 的补码,因此对 1100
进行 2 的补码
得到 4
。现在因为 1100
是一个负数。所以,结果是 -4
。 1010
也是如此。
1100
0011 - 1's complement
0100 - 2's complement - value = 4 (take negative)
关于java - 一元 "~"运算符 - 这里到底发生了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13535947/