2012-04-01 73 views
14

衆所周知,當您使用printf輸出float的值時,精度有限。
然而,還有一招,以增加輸出的精度,如下例所示:使用printf漂浮物的精度

#include <stdio.h> 

int main() 
{ 
    float f = 1318926965;  /* 10 random digits */ 
    printf("%10.f\n", f);  /* prints only 8 correct digits */ 
    printf("%10d\n", *(int*)&f); /* prints all digits correctly */ 
    return 0; 
} 

,我的問題是,爲什麼沒有人更頻繁地使用這一招?

+1

因爲潛在的未定義行爲是不好的。 (編輯:從技術上講,這可能不是未定義的行爲,因爲我不確定標準對此有何評論。儘管如此,Endianess可能會咬你。) – Corbin 2012-04-01 08:53:56

+8

對於一個好的4月的第一個笑話+1。 – Henrik 2012-04-01 09:03:02

+0

它顯然讓我x.x – Corbin 2012-04-01 09:16:05

回答

11

四月傻瓜?

您的「隨機數」1318926965具有十進制和浮點格式相同的基礎表示形式。

嘗試其他值,例如10。這將打印爲:

 10 
1092616192 

因此,要回答你的問題:

and my question is, why don't people use this trick more often? 

因爲只有一天的一年是愚人節......天的伎倆行不通的休息...

4

嘗試用不同的數字,同樣的伎倆,說2318926965.

#include <stdio.h> 

int main() 
{ 
    float f = 2318926965;  /* 10 random digits */ 
    printf("%10.f\n", f);  /* prints only 8 correct digits */ 
    printf("%10d\n", *(int*)&f); /* prints all digits correctly */ 
    return 0; 
} 
$ gcc -Wall -O3 t.c 
t.c: In function ‘main’: 
t.c:7:5: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing] 
$ ./a.out 
2318926848 
1326069764 

我沒有看到精度的提高,在所有依賴於該位表示你的「絕招」浮在你的平臺上(據我瞭解)。

This thread有一些其他的「魔法浮動」和一種方式來產生它們。

+0

它取決於IEEE 754浮點數的位表示,而不是「在您的平臺上」。 (模擬可能的字節順序問題,在任何現實世界的機器上都不存在)。IMO這樣的代碼唯一不好的地方就是應該用工會代替的不合適的類型雙關語(粗略但是所有編譯器都支持)或者'memcpy'(100%合法C)。 – 2012-04-01 13:55:47

+0

如果IEEE 754是強制性的,那麼'__STDC_IEC_559__'定義的用途是什麼? – Mat 2012-04-01 14:09:51

+0

這不是強制性的,但考慮C標準如何破壞非IEEE符合實現的浮點數,並且沒有其他方法可以告訴你可以依賴於浮點算術,我會考慮它對於想要可移植到非IEEE數學系統以便使用浮點的程序來說是一個巨大的錯誤。 (當然,您可以將它用於僅用於單個非IEEE數學實現的非便攜式程序。) – 2012-04-01 14:15:48

0

精度的限制是浮點表示,而不是printf()這是一個錯誤的前提。

此外,一個單精度浮點數只能保證正確的6位數的精度,所以「詭計」會自欺欺人;在一般情況下它不起作用。

如果你想要10位浮點數,那麼你應該使用雙精度,這對15位數是有好處的。