[英]How does overflow work in java?
我已经读过有关溢出的内容,我知道“溢出是指当一个数字如此之大以至于它将不再适合数据类型时,所以系统”回绕“到下一个最低值并从那里开始计数”。
例如:
short s = (short)1921222; // Stored as 20678
在那个例子中,我们从-32768 (Short.MIN_VALUE)
开始计数,但是当我尝试在另一个整数数据类型中进行证明时,它似乎没有相同的工作方式......
byte b = (byte)400; // Stored as -112
上面的例子从0开始计数,这是我发现得到-112的唯一方法
我不知道我做错了什么。
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的补数。
在java中, byte
基元类型是一个8 bit
符号整数,这就是你调用-112
的原因:
byte b = (byte) 400;
您可以避免这种情况并获得其未签名的值,通过二进制将其添加为0xFF
如下所示:
int b = (byte) 400 & 0xFF;
有关详细信息,请查看:
除了其他答案,您还可以通过手动计算得到答案。
在Java中,数据类型byte
是一个8位有符号整数。 所以这些值在区间[-128, 127]
。 如果您的值为400
并且希望查看该类型的实际值,则可以从该数字中减去间隔的大小 ,直到达到该区间内的值。
正如我所说, byte
是8位,所以间隔的大小是256
。 从初始值中减去: 400 - 256 = 144
。 此值仍然在间隔之外,因此您必须再次减去: 144 - 256 = -112
。 此值现在位于区间内,实际上是您在测试中看到的值。
您的第一个示例也是如此: short
为16位且已签名,因此间隔为[-32768, 32767]
,大小为65536
。 从值1921222
重复减法最终会得到您在测试中看到的值20678
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.