2010-11-19 15 views
0

可能性の重複:
compare floats in phpPHPは2つの等しい数が等しくないと見つけませんか?バグ?

私は条件があります。

if($x <= .3) 
    echo 1; 

$場合には、xが未満0.3

で1場合にのみ、エコーされますxは.3に等しく、私は1を得ません。

場合、私は - 私は)(FLOATVALのXを包む試したが、私はif ($x == .3)を試してみました運

iは$ xをエコーし​​ようとしていないと私は "0.3"

を取得

試みたif (.3 == .3)は明らかに動作します

アイデア?これはPHPバグですか?

+1

これはバグではありません。誰かがこれを閉じるために複製を見つけてください。 –

+0

$ xが0.3であることをどのように知っていますか?コード全体$ x = .3; if($ x <=。3)echo 1? –

+0

$ x – erenon

答えて

1

浮動小数点値は正確ではありません出力:

は、私はちょうどこれをテストしました。あなたはそれが大体このような< = 0.3だかどうかを確認することができます

if ($x <= 0.3000001) { 
    echo 'yay'; 
} 
+0

うわー - なぜそんなの? 12.8-12.5は本当に.3ではありません。私はクライアントと確認する必要がありますが、うまくいけば2桁の精度で作業しているだけです – dan

+0

これは、それが進むにつれてそれ自体を構築するかなり有能な説明です:http://support.microsoft。com/kb/42980 – dkamins

+0

ところで、特に好奇心が強い場合を除いて、なぜそれを正確に理解する必要はありません。主なことは、99%の時間、浮動小数点数は、演算子と直接比較してはならないという一般的なルールです。整数は当然(バイナリで直接表現できるので)もちろん可能です。 – dkamins

0

hmmm、私はあなたのvar $xが実際に.3と等しくないと仮定する必要があります。

<? 
    $var = 0.3; 

    if($var <= .3) 
    { 
     echo 'yay'; 
    } 
    else 
    { 
     echo 'boo'; 
    } 
?> 

、それはyay

+0

もちろんそうではありません。 0.3はほとんどのコンピュータに実際には存在しないからです。 –

+0

これは動作しますが、私の変数は実際には$ x = 12.8-12.5で作成されますが動作しません。 – dan

0

$ X = 0.4;
if($ x < = .3){echo 1; }
はどこに$ xを取得している...しかし$ X
で異なる値を試してみました...ここに罰金作品?比較する前に値を「丸める」必要があるかもしれません。

4

これは、すべての浮動小数点数のバイナリ表現についてです:

var_dump(sprintf("%.40f", 0.3)); 
// string(42) "0.2999999999999999888977697537484345957637" 

は基本的には、0.3がベース2に正確に表現することができないので、それは数桁の後に切り捨てられます。これは基本的にベース10の1/3に似ています.0.3をタイプすることはできますが、0.33はより正確です。したがって、0.333、0.3333などです。正確に表現することはできません。

0

浮動小数点は100%正確ではありません。要するに、分数成分は、一般に1 /(2^n)を足し合わせて格納される。例えば、1/2 + 1/4は3/4がどのように記憶されるかである。これはバグでもなく、特定のPHPに関する質問でもありません。

しかし、これは常に真でなければなりません:

$x = 0.3; 
if ($x == 0.3) echo "true"; 

同じ不正確さの両方に存在することになるので。

しかし、これは真実であることが保証されていません。

$x = 0.1; 
$y = 0.2; 
if ($x + $y == 0.3) echo "true"; 

この問題を回避するための簡単な方法は、デルタ使用することです:

if (abs($a - $b) < $delta) echo "true" 

$デルタは非常に少数です。

正確性が必要な場合は、BCMath拡張機能のようなものをチェックしてください。

これはお金のためであるならば、それはちょうど、大きな赤いと脂肪ここで全体セント単位で計算(整数)、$ 1.23 = 123

1

あなたが行く、やることは通常簡単です:Floating Point Numbers

0.1または0.7のような小数は、 精度のわずかな損失なしに、対応する内部バイナリ の内部バイナリに変換することはできません。これにより、 の結果が混乱することがあります。たとえば フロア((0.1 + 0.7)* 10)は となります。内部表現が のようなものになるため、 は予期された8の代わりに7を返します。

数字の有限 数と10進表記のいくつかの画分 を発現することが不可能であるという事実によるものです。例えば、 小数点の1/3は0.3になります。

だから、浮動番号が最後の桁に をもたらし、そしてが平等ため 浮動小数点数を比較することはありません信用しません。 高精度が必要な場合は、 arbitrary precision math functionsおよび gmpの関数を使用できます。

PS:さらに楽しくがあります:

INF == INF => false 
INF < INF => true 
INF > INF => true 

だから、無限大が無限大と無限大ではありませんが、同時に無限大よりも小さいと無限大よりも大きくなります。それについて考えると、実際には意味をなさない...

関連する問題