溢流在Java中如何工作



我已经阅读了有关溢出的信息,我知道"溢出是当一个数字如此之大以至于它不再适合数据类型,因此系统"绕开"到下一个最低值,从那里计数"。

例如:

short s = (short)1921222; // Stored as 20678

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

byte b = (byte)400; // Stored as -112

上面的示例从 0 开始计数,这是我发现获得 -112

的唯一方法

我不知道我是否做错了什么。

Java语言规范说:

积分类型分别为8位,16位,32位和64位的字节,短,int和长,分别签署了两个符合整数,其值为16--代表UTF-16代码单元的位无符号整数。

所以, shortbyte都是两个的补充整数。

short是16位,这意味着它可以保持2^16 = 65536不同的值。在第65536个值之后,它溢出。
1921222 Modulo 65536是20678。这小于32768(2^15,两者补充的转折点),因此我们保持一个正数。

byte是8位,这意味着它可以保持2^8 = 256个不同的值。这个值在256小时之后溢出。400 Modulo 256是144。该值高于128,这是两者补充的转折点 - 因此将被解释为负两个的补体编号。

铸件正在截断数字。(JLS)

0000 0001 1001 0000

失去高字节

1001 0000

是-112。

在Java中,byte原始类型是8 bit 签名 Integer,这就是为什么您从呼叫中获得-112的原因:

byte b = (byte) 400;

您可以通过将其添加到0xFF这样的二进制文件来避免并获得其未签名的值:

int b = (byte) 400 & 0xFF;

有关更多详细信息,您可以检查:

  • Java 原始数据类型文档。
  • 如何将int转换为未签名的字节和back

除了其他答案之外,您还可以通过手动计算获得该答案。

在Java中,数据类型byte是一个8位,已签名整数。因此值是在间隔[-128, 127]中。如果您的值为400并且想查看该类型的实际值,则可以从该数字中减去间隔的 size ,直到您达到间隔内的值。

正如我所说,byte是8位,因此间隔的大小为256。从您的初始值中减去:400 - 256 = 144。此值仍然不在间隔之外,因此您必须再次减去:144 - 256 = -112。该值现在在间隔内,确实是您在测试中看到的值。

对于您的第一个示例也是如此:short是16位并签名,因此间隔为[-32768, 32767],尺寸为65536。从值1921222进行重复减法最终将为您提供测试中所见的值20678

相关内容

  • 没有找到相关文章

最新更新