2012-10-16 118 views
3

這是代碼Java中的片段:原始值轉換

int i = 1234567890;      
float f = i;     
System.out.println(i - (int)f); 

爲什麼是輸出不等於0?它執行擴大,所以它不應該丟失數據。然後,您只需截斷值。 最好的問候

回答

3

看到區別

int i = 1234567890;  
float f = i;  
System.out.println(i - f); 
System.out.println((int)f); 
System.out.println(f); 
System.out.println(i-(int)f); 

輸出繼電器:

0.0 

1234567936 

1.23456794E9 

-46 
1

你的錯誤是在這裏:

它執行擴大,所以它不應該丟失數據。

這種說法是錯誤的。拓寬並不意味着你不會丟失數據。

Java specification

寬元轉換不會失去對數值的總體規模信息。

將整數或長整型值轉換爲浮點型或將長整型值轉換爲雙精度值可能會導致精度下降 - 也就是說,結果可能會丟失值的某些最低有效位。在這種情況下,使用IEEE 754輪到最近模式(§4.2.4),得到的浮點值將是整數值的正確舍入版本。

強調我的。

該規範明確指出,幅度不會丟失,但精度可能會丟失。

單詞加寬指的不是數據類型的精度,而是指它的範圍。因爲它們有更大的範圍,所以浮點數比整數更寬。

INT

4個字節,符號(2的補數)。 -2,147,483,648至2,147,483,647。

浮子

4個字節,IEEE 754覆蓋從1.40129846432481707e-45的範圍內,以3.40282346638528860e + 38(正或負)。

正如你所看到的,float有一個更大的範圍。但是一些整數不能完全表示爲浮點數。這種表示錯誤是導致結果與0不同的原因。存儲在f中的實際值爲1234567936.

+0

'(F == I)'返回true –

+0

@Quoi:是的,這是正確的......所以呢'(F = =(float)i)'。你的觀點是...? –

0

加寬會損失精度。 int具有32位精度,其中float具有25位精度(24位尾數和隱含的最高位)。爪哇認爲float爲比64位long這是有點狂IMHO

隨着精度的8位差值越寬,誤差可高達約+/- 64,因爲它舍入int值到最近的float表示。

int err = 0; 
for (int i = Integer.MAX_VALUE; i > Integer.MAX_VALUE/2; i--) { 
    int err2 = (int) (float) i - i; 
    if (Math.abs(err2) > err) { 
     System.out.println(i + ": " + err2); 
     err = Math.abs(err2); 
    } 
} 

打印

... deleted ... 
2147483584: 63 
2147483456: -64 
0

你會驚訝地發現,即使這可能是真實的:

(f==(f+1))==true 

給出f足夠大的浮動...

0
int i = 1234567890;  
    float f = i;  
    System.out.println((int)f); 
    System.out.println(i); 
    System.out.println(i - (int)f); 

輸出結果爲:

1234567936 
1234567890 
-46 

看到區別。

比較整數浮點數有較大的值。