1

だから私は自分のコードでこのバグを見つけたばかりで、理解していないルールは何だろうと思っています。

I have a float variable logDiff, that currently contains a very small number. I want to see if it's bigger than a constant expression (80% of a 12th). I read years ago in Code Complete to just leave calculated constants in their simplest form for readability, and the compiler (XCode 4.6.3) will inline them anyway. So I have,

            if ( logDiff > 1/12 * .8 ) {  

I'm assuming the .8 and the fraction all evaluates to the correct number. Looks legit:

(lldb) expr (float) 1/12 * .8
(double) $1 = 0.0666666686534882
(lldb) expr logDiff
(float) $2 = 0.000328541

But it always wrongly evaluates to true. Even when I mess with enclosing parens and stuff.

(lldb) expr logDiff > 1/12 * .8
(bool) $4 = true
(lldb) expr logDiff > (1/12 * .8)
(bool) $5 = true
(lldb) expr logDiff > (float)(1/12 * .8)
(bool) $6 = true

I found I have to explicitly spell at least one of them as floats to get the correct result,

(lldb) expr logDiff > (1.f/12.f * .8f)
(bool) $7 = false
(lldb) expr logDiff > (1/12.f * .8)
(bool) $8 = false
(lldb) expr logDiff > (1./12 * .8f)
(bool) $11 = false
(lldb) expr logDiff > (1./12 * .8)
(bool) $12 = false

しかし最近、人気のあるスタイル ガイドを読み、これらの凝った数値リテラルを明示的に避けています。これは、明らかに、コンパイラが私よりも賢く、Do What I Mean よりも優れているという私の仮定によるものです。

1.f浮動小数点数が必要な場合のように、数値定数を常にスペルする必要がありますか? 迷信に聞こえます。なぜ、いつ必要なのかを理解するのに役立ちますか?

4

4 に答える 4

4

1/12整数除算です。つまり、結果はゼロとして切り捨てられます。

これを(float) 1/12float としてキャストすると、式全体が浮動小数点式になります。

于 2013-08-14T08:13:57.007 に答える
1

C ではint/intを与えますint。少なくとも 1 つを float に変換するようコンパイラに明示的に指示しない場合、除算が行われ、最も近い int (この場合は 0) に切り捨てられます。

リンクされたスタイル ガイドには、実際には「必要がない限り、数値を特定の型にすることは避けてください」と書かれていることに注意してください。この場合、コンパイラがいくつかの型変換を行うために必要なためです。

于 2013-08-14T08:16:49.117 に答える
1

のような式1 / 4は整数除算として扱われるため、小数精度はありません。この特定のケースでは、結果は になります0int / intこれは を意味するものと考えることができますint

数値定数が float である必要がある場合、常に 1.f のようにスペルする必要がありますか? 迷信に聞こえます。なぜ、いつ必要なのかを理解するのに役立ちますか?

これは迷信ではありません。これらはリテラル (例として float) であり、コンパイラはそれらに対するすべての操作をそのように扱うことをコンパイラに伝えています。

さらに、式をキャストできます。次の点を考慮してください。

float result = ( float ) 1 / 4;

...1フロートになるようにキャストしているため、の結果はfloat / intになりますfloat。データ型操作の優先順位 (または昇格) を参照してください。

于 2013-08-14T08:17:56.400 に答える