繁体   English   中英

Java 类型转换 - float(和 long)到 int

[英]Java type casting - float (and long) to int

我试图理解 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);
    }
}

...其中 2147483647 是int的最大值。

输出是:

2147483647
-2147483648

float转换为int它的小数部分将被删除。 因此, (int)2147483648.0也应该等于-2147483648

谁能向我解释为什么2147483648.0被转换为2147483647

2147483648.0 实际上是 2 31 ,而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,并且这个整数值可以用long表示,那么第一步的结果就是long值V。

    • 否则,如果这个整数值可以表示为一个int,那么第一步的结果就是int值V。

这里的相关部分是该值将向零舍入 只要浮点值(或 long)高于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

发生转换时,前 32 位将被丢弃,为您留下可能的最高int

对于正 long 反之亦然 - 高 32 位包含在转换时被丢弃的所有 1。

完整结构如下,管道再次表示 32 位标记:

1111 1111 1111 1111 1111 1111 1111 1111 | 1000 0000 0000 0000 0000 0000 0000 0000

无论您给出哪个更大的值(比 int max 值)作为float值,它都会削减(适合)到int最大值,即2147483647

 System.out.println((int)2147483699.0); //2147483647
 System.out.println((int)3147483699.0); //2147483647

编辑 :

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 值大于/小于给定的int值,则转换永远不会准确。

编译器是这里聪明人 如果仔细观察字节码,可以看到编译器正在将浮点值替换为 Integer.MAX_VALUE。

所以,就像Suresh所说的,任何高于 2147483647.0 的浮点值都会被 2147483647 替换。

代码 :

public static void main(String arf[]) {
        int i = (int) 2147483649121.0f;
        System.out.println(i);
        System.out.println((int) 2147483648L);
    }

字节码:

public static void main(java.lang.String[]);
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: ldc           #16                 // HERE : int 2147483647
         2: istore_1      
         3: getstatic     #17                 // Field java/lang/System.out:Ljava/io/PrintStream;
         6: iload_1       
         7: invokevirtual #23                 // Method java/io/PrintStream.println:(I)V
        10: getstatic     #17                 // Field java/lang/System.out:Ljava/io/PrintStream;
        13: ldc           #29                 // int -2147483648
        15: invokevirtual #23                 // Method java/io/PrintStream.println:(I)V
        18: return        

任何大于2147483647整数都会导致溢出。 在这种情况下,任何赋值或转换都会产生负的 max int -

看 (int)2147483699L) 也产生-2147483647

System.out.println((int)2147483699L);

int 不能显示十进制。 因此,在转换时,浮点数省略了小数点,只表示绝对数。 这种方法是窄铸造。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM