java - 一元 "~"运算符 - 这里到底发生了什么?

标签 java binary

我最近参加了 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 是一个负数。所以,结果是 -41010 也是如此。

1100 
0011  - 1's complement
0100  - 2's complement  - value = 4 (take negative)

关于java - 一元 "~"运算符 - 这里到底发生了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13535947/

相关文章:

Javascript将图片字节转换为十六进制

java - 如何在Firestore(Android)中显示某个成员制作的文件?

java - Java中的页面置换算法模拟

java - java异常处理中的return语句

输出的c++ bitset问题

java - 十进制、二进制、八进制、十六进制转换错误

java - LoadRunner Java over HTTP 协议(protocol)与 WEB (http/html) 协议(protocol)

java - 关闭客户端和服务器后孤立的 TCP 连接

linux - 用 0xff 填充拆分二进制文件

c++ - 为什么 basic_ifstream 显示错误的结果?