2011-08-10 182 views
4

爲什麼下面的代碼和C中的代碼一樣?IEEE 754:它究竟如何工作?

float x = 2147483647; //2^31 
printf("%f\n", x); //Outputs 2147483648 

這裏是我的思維過程:

2147483647 = 0  1001 1101  1111 1111 1111 1111 1111 111 

    (0.11111111111111111111111)base2 = (1-(0.5)^23)base10 
=> (1.11111111111111111111111)base2 = (1 + 1-(0.5)^23)base10 = (1.99999988)base10 

因此,對IEEE轉換754記號回十進制:1.99999988 * 2^30 = 2147483520

所以從技術上來說,C程序必須打印出來2147483520,右?

回答

3

要表示將2147483647可以表示這種方式下兩個值是2147483520和2147483648

由於後者更接近不可表示的「理想一個」的值,它被使用:在浮點數,值變爲四捨五入,不被截斷。

1

The standard is available here。你可能不得不購買它,因爲IEEE(以及其他類似組織)主要通過銷售該標準來賺錢,在組裝時支付他們的成本,遊說接受和提高標準的質量。

該位僅僅意味着什麼有人表示他們是

「當我用一個詞,」矮胖子在一個相當輕蔑的口吻說,「這意味着 正是我選擇它的意思 - 不多也不少「。 「問題是,」愛麗絲說,「你是否可以讓這些詞意味着很多不同的東西。」 「問題是,」Humpty Dumpty說,「這是 成爲主人 - - 就是這樣。」 (透過玻璃看,第6章)

在這種情況下,IEEE已經決定什麼位的意思,那printf的標誌%F打印出相應的人類代表權是由於標誌也是繼的原因相同的標準。

有時您可以設法將位轉換爲另一種數據類型(如int)並打印出這些位的「其他」表示。 C會捕獲很多正常數量的促銷活動,但您可能會混淆它,通常是將錯誤類型的指針分配到正確的地址(並將它們取消引用)。

請注意,雖然您正在手動進行數學運算,但實際硬件並不能保證按照您的要求進行數學運算。使用整數運算時,表示中的精度要高得多,但對於浮點數學運算,如何舍入一個數字會使輸出有很大差異。這甚至沒有提到有時被燒入系統的浮點錯誤(幸好不是經常)。

1

浮點格式通常處於「規範化形式」,其中尾數的最高位始終爲1.由於它始終爲1,因此不需要花費一點時間來存儲它。因此,在解碼這種數字表示時,您需要在頂部添加1。

1
2147483647 = 2^31 - 1 = +1 * 2^30 * 1.1111 1111 1111 1111 1111 1111 1111 11 

當以IEEE 754-1985單精度格式對此數字進行編碼時,有效數將被正確舍入。對於四捨五入模式,即使最接近(默認舍入模式),這意味着它會四捨五入。

四捨五入之前:

exponent = 30, significand = 1.1111 1111 1111 1111 1111 1111 1111 11 

小數點後四捨五入尾數以23位數字後:

exponent = 30, significand = 10.0000 0000 0000 0000 0000 000 

正火後:

exponent = 31, significand = 1.0 

在單精度格式編碼:

1 | 10011110 | 00000000000000000000000