[英]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 值的原因在語言規范中描述為縮小轉換。
第一步,將浮點數轉換為 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.