Java类型转换 - 浮点(和长)到int

Roh*_*egi 10 java casting

我试图理解Java中的类型转换.我已阅读, long被转换成int通过使用降低的模通过的范围intfloat被转换为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值的原因在语言规范中描述为缩小转换.

  1. 在第一步中,浮点数转换为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)

  • 我还没有找到一个并不贵的IEEE 754副本,但我怀疑IEEE 754是零往返是重要的部分.我很确定那部分仍然会产生`2147483648.0`.重要的部分就在你引用的部分之后,它描述了如果结果仍然无法在T型中表示会发生什么:"否则,以下两种情况之一必须为真:......值必须太大(a**大幅度**或正无穷大的正值),第一步的结果是int或long类型的最大可表示值." (3认同)

Sur*_*tta 8

无论你给出哪个更大的值(比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,则转换永远不准确.

  • @ downvoter,我从不关心那个-2代表.但如果您发现任何错误,请发表评论.会学习. (2认同)