2012-11-26 10 views
6

私はかなり新しい初心者です。だから私は小さなゲームのデモを書くとき、私は本当に奇妙な問題に直面しています。フロートは0.1を追加すると変更されません

void testC() 
{ 
    float a = 825300160; 
    float b = a + 0.1; 
    assert(a != b); 
} 

上記のassert文は受け入れられません。非常に奇妙な。
私の環境はmac os mlです。 gcc 4.2.1

+3

'float'は' 825300160'と '825300160.1'を区別するのに十分な精度を持っていません。 – Mysticial

+1

浮動小数点数の精度は約6桁です。 (代わりに 'double'を試してください。) –

+0

' float'は通常24ビットの精度しかありません。 'a'は' 2^29'より大きく、 'b <2 ^( - 3)'であるので、 'b'は' a'に影響を与える数ビットを超えています。 –

答えて

8

floatの小数部は23ビットで構成されています。 825300160を表すには30ビットが必要なので、数値のうち重要度の低い部分が削除されます。 .1を追加すると、違いはありません - あなたが変更する数のおよそ32を追加する必要があります。

float a = 825300160; 
float b = a + 31.5; 
assert(a != b); // No change is detected 
float c = a + 32; 
assert(a != c); // Change is detected 
+0

+1浮動小数点の素晴らしい説明をしています。私はこれが浮動小数点標準をよく知っていればいいと思う。 – tjameson

+0

この問題が発生するのを避けるために、コンパイラに何かできることがあります。コンパイラが同じことをやり直すときに警告を出すのではないでしょうか。または、私はちょうどフロートの範囲を念頭に置いて、それが再び起こらないようにする必要があります。ありがとう。 –

+0

私は前にJavaプログラマーですので、小さな問題が私のコードに隠れていてもコンパイラは私をコンパイルさせません。だから私はCコードを書くとき、私は以前にも考えていない多くの問題に直面するでしょう。 –

6

フロートタイプには十分な精度がありません。あなたが実際に0.1追加を825300160のような大きな数に区別する必要がある場合は、doubleを使用します。

1

this siteとしてショーを、AとBの両方が、IEEE規格の

0 10011100 10001001100010001010011 

として表されます浮動小数点数の場合、最初のビットは符号、次の8は指数、残りの23は仮数です。指数が非常に大きいので、差を表すのに23ビットに十分なスペースがありません。

関連する問題