如果将int(-2 ^ 31..2 ^ 31-1)的长度超出范围转换为int,会发生什么?

时间:2014-09-16 16:36:09

标签: java casting primitive

我正在运行代码,试图找出由于在整数十进制数字类型之间进行转换而导致精度丢失时Java的行为,并且我发现了一个意外的结果:

long l2 = 999999999999999999L;   //outside of range -2147483648..2147483647 for int
int i3=(int)l2;    
System.out.println(l2); //999999999999999999, as expected.
System.out.println(i3); //I expected 2147483647, but got -1486618625

有人可以解释我是如何从一个大的正长线中得到一个大的负数吗?我本来期望系统至少做出尽力而为的投射尝试,返回最大正整数(最接近的有效int到long,它太大而不能存储在整数中。)相反,我得到了一个负数对我来说没有意义的数字。

4 个答案:

答案 0 :(得分:2)

longint的缩小基元转换会丢弃除原始数字的低32位之外的所有内容,因此您无法获得Integer.MAX_VALUE

JLS, Section 5.1.3,声明:

  

有符号整数到整数类型T的缩小转换只会丢弃除n个最低位之外的所有位,其中n是用于表示类型T的位数。除了可能丢失有关幅度的信息之外数值,这可能导致结果值的符号与输入值的符号不同。

这与从浮点类型到int的原始缩小转换形成对比,如果原始值太大,则可能导致Integer.MAX_VALUE

double l2 = 999999999999999999.0;
System.out.println((int) l2);

打印:

2147483647

答案 1 :(得分:0)

让我们先来看看结果编号位:

enter image description here

现在看一下999999999999999999的位表示:

enter image description here

请注意,前两种情况都是相同的。

现在考虑JLS,第5.1.3节,如rgettman所述:

  

有符号整数到整数类型T的缩小转换只会丢弃除n个最低位之外的所有位,其中n是用于表示类型T的位数。除了可能丢失有关幅度的信息之外数值,这可能导致结果值的符号与输入值的符号不同。

因此在进行演员表时你只能保留32个第一位(10100111011000111111111111111111)。因此,考虑有符号整数的最高位代表数字的符号,你将得到负数(1)0100111011000111111111111111111

这等于-1486618625作为十进制值。

答案 2 :(得分:0)

演员不进行任何对话,也不关心数据。 (或关于截断)

二进制文件中的

9999999999999999990000 1101 1110 0000 1011 0110 1011 0011 1010 0111 0110 0011 1111 1111 1111 1111

将其转换为signed int时,只使用低32位: 1010 0111 0110 0011 1111 1111 1111 1111 - 现在,这个数字意味着(它现在由于转换而成为有符号整数):

  • 前导1 =负数
  • 010 0111 0110 0011 1111 1111 1111 1111将在{... 1}}中显示...不正确。
  • Java使用了Two的补码,这意味着如果你只是查看"数字"如果是负数,则需要反转每一位并添加660865023以获得实际数值:

这样:

1

010 0111 0110 0011 1111 1111 1111 1111 101 1000 1001 1100 0000 0000 0000 0000 + 1 101 1000 1001 1100 0000 0000 0000 0001 101 1000 1001 1100 0000 0000 0000 0001 - 它是否定的:瞧,你的1486618625

答案 3 :(得分:-1)

有符号整数的最高位是符号位。因此,如果您将操作溢出到该位,您将得到一个负数。在这种情况下,你是通过施放来完成的。

= 1101 1110 0000 1011 0110 1011 0011 1010 0111 0110 0011 1111 1111 1111 1111

Truncated to (int):
                     1010 0111 0110 0011 1111 1111 1111 1111


Twos' compliment transform:

                     0101 1000 1001 1100 0000 0000 0000 0001 = 1486618625