Java 解惑 -05:十六进制的趣事
🏷️ 《Java 解惑》
java
System.out.println(Long.toHexString(0x100000000L + 0xcafebabe)); // print cafebabe
1
这段代码并不会打印 1cafebabe ,实际的打印结果没有前面的 1 。
前面的 1 哪里去了?
这个问题的根源在于使用十六进制的字面量表示法表示数值时,其正负是由最前一位来决定的。
0xcafebabe 是一个 int 型的负数,其实际值为 -889275714 。
java
System.out.println(0xcafebabe); // print -889275714
1
在和 long 数值进行加法计算时,会自动提升为 long 型,此时其值为 oxffffffffcafebabe 。
java
System.out.println(Long.toHexString(0xcafebabe)); // print ffffffffcafebabe
System.out.println(0xffffffffcafebabeL); // print -889275714
1
2
2
至于为什么提升为 long 前面补的不是 0 而是 1 ,这个是因为负数是通过补码的方式表示的。
java
System.out.println(0xffffffffffffffffL); // print -1
System.out.println(01777777777777777777777L); // print -1
1
2
2
0x100000000L + 0xcafebabe
实际的计算过程如下:
bash
ffffffffcafebabe
+ 0000000100000000
------------------
100000000cafebabe
1
2
3
4
2
3
4
最高位(第 65 位)的 1 已经超出了 long 型长度,会被忽略掉,所以结果就变成了 0x00000000cafebabe 。
如果要打印想定的结果: 1cafebabe ,只需将后面的字面量也定义为 long 型就可以了。
java
System.out.println(Long.toHexString(0x100000000L + 0xcafebabeL)); // print 1cafebabe
1
此时没有 int 到 long 型的扩展提升,其实际的计算过程如下:
bash
00000000cafebabe
+ 0000000100000000
------------------
00000001cafebabe
1
2
3
4
2
3
4