私は条件があります。
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バグですか?
私は条件があります。
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バグですか?
浮動小数点値は正確ではありません出力:
は、私はちょうどこれをテストしました。あなたはそれが大体このような< = 0.3だかどうかを確認することができますif ($x <= 0.3000001) {
echo 'yay';
}
うわー - なぜそんなの? 12.8-12.5は本当に.3ではありません。私はクライアントと確認する必要がありますが、うまくいけば2桁の精度で作業しているだけです – dan
これは、それが進むにつれてそれ自体を構築するかなり有能な説明です:http://support.microsoft。com/kb/42980 – dkamins
ところで、特に好奇心が強い場合を除いて、なぜそれを正確に理解する必要はありません。主なことは、99%の時間、浮動小数点数は、演算子と直接比較してはならないという一般的なルールです。整数は当然(バイナリで直接表現できるので)もちろん可能です。 – dkamins
hmmm、私はあなたのvar $x
が実際に.3
と等しくないと仮定する必要があります。
<?
$var = 0.3;
if($var <= .3)
{
echo 'yay';
}
else
{
echo 'boo';
}
?>
、それはyay
もちろんそうではありません。 0.3はほとんどのコンピュータに実際には存在しないからです。 –
これは動作しますが、私の変数は実際には$ x = 12.8-12.5で作成されますが動作しません。 – dan
$ X = 0.4;
if($ x < = .3){echo 1; }
はどこに$ xを取得している...しかし$ X
で異なる値を試してみました...ここに罰金作品?比較する前に値を「丸める」必要があるかもしれません。
これは、すべての浮動小数点数のバイナリ表現についてです:
var_dump(sprintf("%.40f", 0.3));
// string(42) "0.2999999999999999888977697537484345957637"
は基本的には、0.3がベース2に正確に表現することができないので、それは数桁の後に切り捨てられます。これは基本的にベース10の1/3に似ています.0.3をタイプすることはできますが、0.33はより正確です。したがって、0.333、0.3333などです。正確に表現することはできません。
浮動小数点は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
あなたが行く、やることは通常簡単です: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
だから、無限大が無限大と無限大ではありませんが、同時に無限大よりも小さいと無限大よりも大きくなります。それについて考えると、実際には意味をなさない...
これはバグではありません。誰かがこれを閉じるために複製を見つけてください。 –
$ xが0.3であることをどのように知っていますか?コード全体$ x = .3; if($ x <=。3)echo 1? –
$ x – erenon