整数types转换如何在Java中处理超出整数范围的数字?
这是我的程序。
public class Foo { public static void main(String[] args) { System.out.println((int) 2147483648l); System.out.println((int) 2147483648f); } }
这是输出。
-2147483648 2147483647
为什么不把2147483648l
和2147483648f
types转换为相同的整数? 你能解释一下这里发生了什么,或者我需要了解什么概念来预测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
是一个long
types,对于int
来说,转换long
太大的规则是将换行规则应用到目标types中。 (在引擎盖下,来源types的有效位被简单地丢弃。)
2147483648f
是一个float
types,并且对于目标types来说,转换float
过大的规则是尽可能使目标types更大。 参考Javatypes的原始types是否在铸造types的MAX_INT上“封顶”?
标准的好处在于有太多select。