我知道byte
和short
数据类型在Java中没有得到2's complement
处理。下面的示例演示了我的这一说法:
byte b1 = 0xFF; //error, 255 is outside the range of byte
byte b2 = 0b1100; //12 is stored, and not -4
现在,举一个例子:
byte b3 = 0;
b3 += 0xFF;
System.out.println(b3); //prints -1 on the console
上例中的第二行是否应该抛出错误,单个0xFF
是255
并且在byte
范围之外?
还有,byte
和short
这个不公平的游戏是什么?我的意思是,为什么不像2's complement system
和int
一样使用long
来解释它们?
答案 0 :(得分:4)
它们是2的补码-不知道您从哪里得到的(但这是错误的)。这个:
byte b1 = 0xFF;
无效,因为它确实超出了byte
的范围。但是,这是
byte b3 = 0;
b3 += 0xFF;
因为+=
是在int
的较大范围内完成的,所以您将其分配给byte
,它占用最后8位,恰好是-1
。
答案 1 :(得分:2)
您应该阅读Java语言规范,而不是尝试通过绘制逻辑推断来解决此问题:
第1点。byte
和short
是带符号的类型。
“整数类型的值是以下范围内的整数:
- 对于
byte
,从-128到127(包括首尾)- 对于
short
,从-32768到32767(含)“来源JLS 4.2.1
点2。带符号整数类型是2的补码。
“整数类型为
byte
,short
,int
和long
,其值分别为8位,16位,32位和64-位分别是带符号的二进制补码整数和char
,其值是代表UTF-16代码单元(第3.1节)的16位无符号整数。”来源JLS 4.2
第3点。您无法将int
变量分配给byte
变量。
如果右侧操作数的类型与变量(§5.2)的类型分配不兼容,则发生编译时错误。来源JLS 15.26.1
第4点。您可以为int
变量提供分配一个byte
编译时常量表达式,该表达式的值在{{1 }}。
“此外,如果该表达式是类型为
byte
,byte
,short
或char
的常量表达式(§15.28):
- 如果变量的类型为
int
,byte
或short
,并且常量表达式的值可以表示为变量的类型,则可以使用缩窄基元转换。”来源JLS 5.2
第5点。char
等同于b3 += 0xFF
第6点。没有b3 = (byte)(b3 + 0xFF)
或byte
文字。
答案 2 :(得分:1)
如果要转换-minus值,Java 8附带了实用程序方法来支持无符号操作
byte b1 = (byte) 0xFF;
Byte.toUnsignedInt(b1); // this method will return 255