整数types转换如何在Java中处理超出整数范围的数字?

这是我的程序。

public class Foo { public static void main(String[] args) { System.out.println((int) 2147483648l); System.out.println((int) 2147483648f); } } 

这是输出。

 -2147483648 2147483647 

为什么不把2147483648l2147483648ftypes转换为相同的整数? 你能解释一下这里发生了什么,或者我需要了解什么概念来预测types转换的输出?

这些是缩小原始转换操作的示例。

在你的第一个例子中, longint

将有符号整数缩小到整数typesT只是简单地丢弃n个最低位的所有位,其中n是用于表示typesT的位数。除了可能丢失关于数值的大小的信息这可能会导致结果值的符号与input值的符号不同。

所以你的(int) 2147483648l正在采取长的64位:

 00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000000

…并完全丢弃前32位:

 10000000 00000000 00000000 00000000

…并将余下的32位作为int 。 因为最左边的那个现在是一个符号位( longint被存储为二进制补码),并且由于它正好设置在你的值中,所以你最终得到一个负数。 由于没有其他位被设置,所以在二进制补码中,这意味着你有最低的负数int可以表示:-2147483648。

floatint例子遵循一个更复杂的规则。 您的价值的相关部分是:

…如果浮点数不是无穷大,则使用IEEE 754 round-to-zero模式(第4.2.3节)将浮点值四舍五入为整数值V.

… [如果]值太大(正数大数值或正数无穷大),那么第一步的结果是int或longtypes的最大可表示值。

(但是请参阅上面链接的部分详细说明。)

因此,由于2147483648f 2147483648 ,并且2147483648太大而不适合int ,所以使用int的最大值( 2147483647 )代替。

所以在longint ,这是有点摆弄; 在floatint ,它更加math。


在你已经问过的评论中:

你知道为什么(short) 32768(short) 32768f评估为-32768 ? 我正在考虑后者评估到32767

很好的问题,这就是我的“看到部分规格链接上面的细节”上面。 (short) 32768f ,实际上, (short)(int)32768f

在上面链接的spec部分中,在“将浮点数缩小到整数typesT中分两步:”

  1. 在第一步中,如果T是long ,则将浮点数转换为int ;如果T是byteshortcharint ,则将浮点数转换为int

然后在步骤2的第二个项目符号中:

  1. *如果T是bytecharshort ,则转换的结果是第一步结果的typesT(第5.1.3节)缩小转换的结果。

所以在第一步中, 32768f变成了32768 (一个int值),然后当然是(short)32768在上面的long => int看到了我们所看到的比特斩波,给我们一个short-32768

太好了! 看到devise决策的效果是如此的美妙。

2147483648l是一个longtypes,对于int来说,转换long太大的规则是将换行规则应用到目标types中。 (在引擎盖下,来源types的有效位被简单地丢弃。)

2147483648f是一个floattypes,并且对于目标types来说,转换float过大的规则是尽可能使目标types更大。 参考Javatypes的原始types是否在铸造types的MAX_INT上“封顶”?

标准的好处在于有太多select。