整数types转换如何在Java中处理超出整数范围的数字?
这是我的程序。
public class Foo { public static void main(String[] args) { System.out.println((int) 2147483648l); System.out.println((int) 2147483648f); } }
这是输出。
-2147483648 2147483647
为什么不把2147483648l和2147483648ftypes转换为相同的整数? 你能解释一下这里发生了什么,或者我需要了解什么概念来预测types转换的输出?
这些是缩小原始转换操作的示例。
在你的第一个例子中, long到int :
将有符号整数缩小到整数typesT只是简单地丢弃n个最低位的所有位,其中n是用于表示typesT的位数。除了可能丢失关于数值的大小的信息这可能会导致结果值的符号与input值的符号不同。
所以你的(int) 2147483648l正在采取长的64位:
00000000 00000000 00000000 00000000 10000000 00000000 00000000 00000000
…并完全丢弃前32位:
10000000 00000000 00000000 00000000
…并将余下的32位作为int 。 因为最左边的那个现在是一个符号位( long和int被存储为二进制补码),并且由于它正好设置在你的值中,所以你最终得到一个负数。 由于没有其他位被设置,所以在二进制补码中,这意味着你有最低的负数int可以表示:-2147483648。
float到int例子遵循一个更复杂的规则。 您的价值的相关部分是:
…如果浮点数不是无穷大,则使用IEEE 754 round-to-zero模式(第4.2.3节)将浮点值四舍五入为整数值V.
… [如果]值太大(正数大数值或正数无穷大),那么第一步的结果是int或longtypes的最大可表示值。
(但是请参阅上面链接的部分详细说明。)
因此,由于2147483648f 2147483648 ,并且2147483648太大而不适合int ,所以使用int的最大值( 2147483647 )代替。
所以在long的int ,这是有点摆弄; 在float到int ,它更加math。
在你已经问过的评论中:
你知道为什么
(short) 32768和(short) 32768f评估为-32768? 我正在考虑后者评估到32767。
很好的问题,这就是我的“看到部分规格链接上面的细节”上面。 (short) 32768f ,实际上, (short)(int)32768f :
在上面链接的spec部分中,在“将浮点数缩小到整数typesT中分两步:”
- 在第一步中,如果T是
long,则将浮点数转换为int;如果T是byte,short,char或int,则将浮点数转换为int。
然后在步骤2的第二个项目符号中:
- *如果T是
byte,char或short,则转换的结果是第一步结果的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。