溢出如何在java中工作?

Lui*_*sk4 18 java integer-overflow

我已经读过有关溢出的内容,我知道"溢出是指当一个数字如此之大以至于它将不再适合数据类型时,所以系统"回绕"到下一个最低值并从那里开始计数".

例如:

short s = (short)1921222; // Stored as 20678
Run Code Online (Sandbox Code Playgroud)

在那个例子中,我们从-32768 开始计数(Short.MIN_VALUE),但是当我尝试在另一个整数数据类型中进行证明时,它似乎没有相同的工作方式......

byte b = (byte)400; // Stored as -112
Run Code Online (Sandbox Code Playgroud)

上面的例子从0开始计数,这是我发现得到-112的唯一方法

我不知道我做错了什么.

S.L*_*ica 17

Java语言规范说:

整数类型是byte,short,int和long,其值分别为8位,16位,32位和64位二进制补码整数,以及char,其值为16位无符号整数代表UTF-16代码单元.

所以,short并且byte都是两个补码整数.

short是16位,这意味着它可以容纳2 ^ 16 = 65536个不同的值.在65536th值之后,它溢出.
1921222 modulo 65536是20678.这小于32768(2 ^ 15,两个补码的转折点)所以我们保持正数.

byte是8位,这意味着它可以容纳2 ^ 8 = 256个不同的值.这个值在第256个值之后溢出.400模256为144.该值高于128,即两个补码的转折点 - 因此它将被解释为负2的补数.

  • "`short`是16位,意味着它的最大值是2 ^ 16 = 65536" - 这是非常误导的.值"65536"不适合Java"short". (3认同)
  • @wchargin好点,编辑了答案. (2认同)

Kyl*_*los 16

演员正在截断数字.(JLS)

0000 0001 1001 0000
Run Code Online (Sandbox Code Playgroud)

丢失高字节成为

1001 0000
Run Code Online (Sandbox Code Playgroud)

这是-112.


cнŝ*_*ŝdk 6

在java中,byte原始类型是一个有8 bit 符号整数,这就是你-112调用它的原因:

byte b = (byte) 400;
Run Code Online (Sandbox Code Playgroud)

您可以通过二进制添加它来避免这种情况并获得其未签名的值0xFF:

int b = (byte) 400 & 0xFF;
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请查看: