我试图理解Java中的类型转换.我已阅读, long被转换成int通过使用降低的模通过的范围int和float被转换为int通过去除小数部分.我尝试了以下代码.
class test
{
public static void main(String arf[])
{
System.out.println((int)2147483648.0);
System.out.println((int)2147483648L);
}
}
Run Code Online (Sandbox Code Playgroud)
...其中2147483647是最大值int.
输出是:
2147483647
-2147483648
Run Code Online (Sandbox Code Playgroud)
当float转换int为其小数部分时被删除.所以,(int)2147483648.0也应该等于-2147483648.
任何人都可以向我解释为什么2147483648.0要施展2147483647?
Mak*_*oto 12
2147483648.0实际上是2 31,而an的最大值int是2 31 -1.因此,该浮点值实际上是一个值太高而不适合的值.
将它截断为最高int值的原因在语言规范中描述为缩小转换.
在第一步中,浮点数转换为long(如果T为long)或转换为int(如果T为byte,short,char或int),如下所示:
如果浮点数为NaN(§4.2.3),则转换的第一步结果为int或long 0.
否则,如果浮点数不是无穷大,则浮点值将四舍五入为整数值V,使用IEEE 754舍入为零的模式(第4.2.3节)向零舍入.然后有两种情况:
如果T很长,并且该整数值可以表示为long,则第一步的结果是长值V.
否则,如果此整数值可以表示为int,则第一步的结果是int值V.
这里的相关部分是该值将向零舍入.只要浮点值(或长)在上面Integer.MAX_VALUE,转换int将导致其最高值.对于低于此值的值也是如此Integer.MIN_VALUE.
如果你使用(int)-214783649L,会发生一些奇怪的事情; 它会突然变成214783647!为什么会发生这种情况也在JLS中解释,强调我的:
将有符号整数缩小到整数类型T只会丢弃除n个最低位之外的所有位,其中n是用于表示类型T的位数.除了可能丢失有关数值大小的信息之外,这可能导致结果值的符号与输入值的符号不同.
使用表示32位截止的管道以二进制形式表示该值的长度,如下所示:
1111 1111 1111 1111 1111 1111 1111 1111 | 0111 1111 1111 1111 1111 1111 1111 1111
Run Code Online (Sandbox Code Playgroud)
转换发生时,前32位将被丢弃,从而使您尽可能高int.
反向为真,正长 - 高32位包含转换时丢弃的所有1.
完整的结构如下,管道再次表示32位标记:
1111 1111 1111 1111 1111 1111 1111 1111 | 1000 0000 0000 0000 0000 0000 0000 0000
Run Code Online (Sandbox Code Playgroud)
无论你给出哪个更大的值(比int max值)float,它都会削减(拟合)到int最大值2147483647
System.out.println((int)2147483699.0); //2147483647
System.out.println((int)3147483699.0); //2147483647
Run Code Online (Sandbox Code Playgroud)
编辑:
java中的long的范围是-9,223,372,036,854,775,808 and 9,223,372,036,854,775,807 (inclusive).在哪里-2,147,483,648 and 2,147,483,647 (inclusive).
因此,如果您的long值大于/小于a给出的值int,则转换永远不准确.