2010-11-25 52 views
5

對於這個問題,我做而不是有能力使用printf設施(我不能告訴你爲什麼,不幸的是,但現在我們假設我知道我在做什麼)。如何打印出IEEE754號碼(無printf)?

對於IEEE754單精度數,則有以下位:

SEEE EEEE EFFF FFFF FFFF FFFF FFFF FFFF 

其中S是符號,E是指數和F是分數。

打印跡象是比較容易的所有情況,因爲正趕上所有的特殊情況下,像NaNE == 0xff, F != 0),InfE == 0xff, F == 0)和0E == 0, F == 0,視爲特殊只是因爲指數偏差沒有在這種情況下使用)。

我有兩個問題。

第一個是如何最好地將非規範化數字(其中E == 0, F != 0)轉換爲規範化數字(其中1 <= E <= 0xfe)?我懷疑這將是必要的,以簡化對下一個問題的答案(但我可能是錯的,所以請隨時教育我)。

第二個問題是如何打印出規範化的數字。我希望能夠以兩種方式將它們打印出來,如-3.74195E3等指數和非指數如3741.95。雖然,只要看看這兩個並排,只需移動小數點就可以很容易地將前者變成後者。所以我們只關注指數形式。

我有我以前早就打印出來PI,你使用的日益減少公式之一,並保持對可能性的上限和下限,輸出數字算法的一個模糊的記憶,當這兩個限制同意,並將計算偏移10倍(因此當上限和下限分別爲3.23643.1234時,可以輸出3並在計算中進行調整)。

但是自從我這麼做以來,它一直是long因此我甚至不知道這是否適合採取此方法。看起來如此,因爲當移動小數部分(1/2,1/4,1/8等)時,每一位的值是前一位的一半。

我真的喜歡不得不去通過printf源代碼跋涉,除非絕對必要的,這樣,如果有人可以幫助與此,我永遠感激。

+0

你需要一個快速的或任何會做? – ruslik 2010-11-25 08:28:47

+1

這是一個黑暗的角落,每一刻都有微妙的等待咬住。通過使用許可證從C運行時庫提取代碼可以更好地滿足您的預期用途。當然,轉換其他方向並不容易...... – RBerteig 2010-11-25 08:29:02

+0

這裏是[eglibc的實現](http://www.eglibc.org/cgi-bin/viewcvs.cgi/branches/eglibc-2_12 /libc/stdio-common/printf_fp.c?rev=10495&view=markup)。它似乎有很好的評論,但閱讀起來並不樂觀。 OMG! – 2010-11-25 13:11:53

回答

3

如果您想要獲得每次轉換的準確結果,您必須使用任意精度算法,正如在printf()實現中所做的那樣。如果你想得到「接近」的結果,也許只有最低有效數字不同,那麼一個非常簡單的基於雙精度的算法就足夠了:對於整數部分,重複地除以十,並將餘數附加到形成十進制字符串(反向);對於小數部分,重複乘以十,然後減去整數部分以形成十進制字符串。

我最近寫了一篇關於這種方法的文章:http://www.exploringbinary.com/quick-and-dirty-floating-point-to-decimal-conversion/。它不打印科學記數法,但這應該是微不足道的補充。該算法打印低於正常數字(我打印出來的數據準確,但你必須做更徹底的測試)。

1

非標準化數字不能轉換爲相同浮點類型的標準化數字。等效歸一化數的指數太小而不能由指數表示。爲了打印歸一化的數字,我能想到的一個愚蠢的方式是反覆乘以10(好吧,小數部分)。

0

您需要做的第一件事就是使用對數將指數轉換爲十進制(因爲大概這就是您想要的輸出)。您將該結果的一部分與尾數相乘,並將該尾數乘以該分數的exp10,然後將其轉換爲十進制字符。從那裏你只需要在適當的位置插入小數點,移動現在的十進制指數。

0

G. Steele的論文更詳細地描述了一種算法,它似乎基於與您概述的原理相同的原理。如果使用內存,則有時候你不得不使用無限的精度算法。 (我認爲它是如何準確地打印浮點數但citeseer目前是從這裏下來的,我無法確認,谷歌的結果也被20年後的回顧報告所污染)。