2011-06-30 12 views
6

浮動小数点定数浮動小数点定数浮動小数点定数浮動小数点定数浮動小数点定数浮動小数点定数浮動小数点定数浮動小数点定数浮動小数点定数浮動小数点定数浮動小数点定数浮動小数点定数浮動小数点定数浮動小数点定数浮動小数点定数は、デフォルトでdouble型です。Cで警告なしでfloat変数にdouble定数を代入しますか?

私はconst float pi = 3.1415と警告しますが、実際はそうはありません。

私は-Wallとgccの下にこれらを試してみてください。

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'の可変性は渡されたときにfloatが暗黙的に倍精度にキャストされることを保証しますか? –

+0

はい、それはむしろOPの質問には関係ありません。 –

+0

私は、どちらが大きいのだろうと思います。「ダブルからフロートへの精度の低下の可能性がある」というミスの数、または明示的に多くのことを浮かべなければならないプログラマーが「フロート」するときのミスの数コンパイラがうまくいけば、またはなしてはいけない何かを '浮動させる 'ように強制する'const float oneTenth = 1.0f/10.0f; float value1 = 8.0f * oneTenth; double value2 = 4.0f * oneTenth; 'もし' oneTenth'が 'double'であったとすれば、すべてが完全に機能していたでしょう。 – supercat

2

%fは、floatおよびdoubleと一緒に使用できます。あなたがより精度の使用が必要な場合

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: 'lf'と' f'は 'scanf'では異なっていますが、' printf'では同じです。 – Jacob

1

警告を受けたい場合は、-Wconversionがメインラインgcc-4.3以降にフラグを立てていると思います。

OS Xを使用した場合、-Wshorten-64-to-32はgcc-4.0.1以降、AppleのGCCでフラグが立てられています。しかし、clangはメインラインのgccの動作と一致していると私は信じています。

関連する問題