2011-06-30 84 views
6

在C編程語言中,默認情況下浮點常數是雙精度型
所以3.1415是雙精度型,除非使用'f'或'F'後綴來指示浮點類型。將C中的double常量賦值給float變量而不發出警告?

我假設const float pi = 3.1415會引起警告,但實際上不會。

當我嘗試這些下GCC與-Wall:

float f = 3.1415926; 
double d = 3.1415926; 
printf("f: %f\n", f); 
printf("d: %f\n", d); 
f = 3.1415926f; 
printf("f: %f\n", f); 
int i = 3.1415926; 
printf("i: %d\n", i); 

結果是:

f: 3.141593 
d: 3.141593 
f: 3.141593 
i: 3 

結果(包括雙可變)顯然失去了精準,但沒有任何警告編譯。
那麼編譯器用這個做了什麼?還是我誤解了某些東西?

回答

7

-Wall不使有關的精度損失,值截斷等警告,因爲這些警告是惱人的噪音和「固定」它們需要用一堆堆醜陋的演員混淆正確的代碼。如果你想要這種性質的警告,你需要明確地啓用它們。

此外,您對printf的使用與實際變量的精度無關,只是精度爲printf正在打印,默認值爲小數點後6位。

+0

'printf'的可變屬性確保浮點數在通過時隱式轉換爲雙精度? – 2011-06-30 17:44:39

+0

是的,雖然這與OP的問題無關。 –

+0

我想知道哪一個更大:「從double到float可能導致精度損失」的錯誤數量,或者代碼程序員必須明確強制許多事情「浮動」以產生錯誤的次數編譯器很高興,也會強制「浮動」本來不應該的東西[例如'const float oneTenth = 1.0f/10.0f; float value1 = 8.0f * oneTenth; double value2 = 4.0f * oneTenth;'請注意,如果'oneTenth'可能是'double',那麼所有東西都可以很好地工作。 – supercat

2

%f可與floatdouble一起使用。如果你想更精確的使用

printf("f: %.16f",d); 

這是什麼引擎蓋下回事:

float f = 3.1415926; // The double 3.1415926 is truncated to float 
double d = 3.1415926; 
printf("f: %f\n", f); 
printf("d: %f\n", d); 
f = 3.1415926f;  // Float is specified 
printf("f: %f\n", f); 
int i = 3.1415926; // Truncation from double to int 
printf("i: %d\n", i); 
+0

不應該是'%lf'的雙重? –

+3

@sharth:'scanf'''lf''和'f'不同但'printf'中的相同 – Jacob

1

如果你想得到這個警告,我相信-Wconversion標誌他們在主線gcc-4.3和更高版本。

如果您恰巧使用OS X,-Wshorten-64-to-32自從gcc-4.0.1以來一直在Apple的GCC中標記它們。然而,我認爲clang與主線gcc行爲相匹配。