簡體   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