2010-11-19 33 views
0

Olası Çoğalt: o x az 0,3PHP eşit olmak için iki eşit sayı bulamıyor? böcek?

eğer $ yalnızca echo 1 olacak

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

:


compare floats in php

i bir şartım var x EQUAL ila .3, ben bir 1.

almıyorum

i floatval() x işaretini sarma denedi, ama hayır şans

i $ x yankı çalıştı ve ben "0,3"

i if ($x == .3) denedim olsun - i eğer hiçbir şey

Açıkça if (.3 == .3)'u denediniz mi?

Herhangi bir fikir? bu bir PHP hatası mı?

+1

Bu bir hata değil. Birisi bunu kapatmak için bir kopyasını bulabilir mi? –

+0

$ x'nin .3, örn. kodun tamamı $ x = .3; eğer ($ x <=. 3) eko 1? –

+0

Lütfen bir $ x – erenon

cevap

1

Kayan nokta değerleri kesin değildir verir:

ben sadece bu test etti. Bunu kabaca böyle < = 0.3 olup olmadığını görmek için kontrol edebilirsiniz:

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

wow - neden böyle? böylece 12.8-12.5 gerçekten değil .3 - .3 olarak yazdırılsa bile? İstemci ile kontrol etmek zorundayım, ama umarım sadece 2 haneli doğrulukta çalışıyor – dan

+0

Bu, birlikte ilerledikçe kendini geliştiren oldukça yetkin bir açıklamadır: http://support.microsoft.com/kb/42980 – dkamins

+0

BTW Özellikle merak etmedikçe neden tam olarak anlamanız gerekmiyor. Akılda tutulması gereken en önemli nokta, zamanın% 99'unun kayan nokta sayılarının doğrudan akıl yürütme operatörleri ile karşılaştırılmaması gerektiği genel kuraldır. Tamsayılar elbette olabilir (çünkü bunlar doğrudan ikili olarak gösterilebilir). – dkamins

0

hmmm, var $x'un gerçekten .3'a eşit olmadığını varsaymak zorundayım.

<? 
    $var = 0.3; 

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

ve yay

+0

Tabii ki değil. 0.3, çoğu bilgisayarlarda gerçekten bulunamadığından. –

+0

bu çalışır, ancak değişkem aslında $ x = 12.8-12.5 tarafından yaratılmıyor. – dan

0

$ x = 0,4;
($ x < = .3) {echo 1; }
Burada iyi çalışıyor ... $ x
adresinden farklı değerler denedim ... nerede $ x alıyorsunuz? Karşılaştırmadan önce değeri "tamamlamanız" gerekebilir.

4

Bu kayan nokta sayılarının ikili gösterimi hakkında tüm açıklanmıştır:

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

Temelde, 0.3 tam tabanı 2'de temsil edilemez, bu nedenle birkaç basamak sonra kesiliyorsa. Temelde 10 temelde 1/3 gibi: 0.3 yazabilirsin, ama 0.33 daha hassas, yani 0.333, 0.3333, vb. Tam olarak temsil edemezsin.

0

Kayan noktalar% 100 doğru değildir. Kısacası, fraksiyonel bileşen genellikle 1/(2^n) birlikte eklenerek depolanır. örneğin, 1/2 + 1/4, 3/4'ün nasıl saklanacağıdır. Yani bu bir hata değil, belirli bir PHP sorusu da değil.

Ancak bu her zaman doğru olmalıdır:

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

aynı yanlışlık hem mevcut olacağından.

Ama bunun doğru olduğunu garanti edilmez:

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

delta çok küçük bir sayıdır, $: Bu bir delta kullanmaktır etrafında

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

basit bir yolu çalışmak.

Doğruluğu gerekiyorsa, BCMath uzantısı gibi bir şeye bakın. Bu parayla ise

, o zaman işte $ 1,23 = 123.

1

sen, büyük, kırmızı ve yağ nereye sadece, tüm sent (tamsayı) hesaplamaları yapmak için genellikle daha kolaydır: Floating Point Numbers:

0.1 veya 0.7 gibi basit ondalık kesirlerinin, iç kopyalarına gibi küçük bir hassasiyeti kaybı olmadan dönüştürülmeleri normaldir. Bu kafa karıştırıcı sonuçlara yol açabilir: örneğin, kat ((0.1 + 0.7) * 10) iç temsil beri yerine beklenen 8, ait dönüş 7 7.9 gibi bir şey olacak olacak.

rakam sonlu sayı ile ondalık gösterimle bazı kesirleri ifade etmek imkansız olmasından kaynaklanmaktadır. Örneğin, ondalık biçiminde 1/3, 0,3 olur.

numarayı yüzen eşitlik için kayan nokta sayıları karşılaştırmak asla son basamağa ve sonucun ne Yani asla. Daha yüksek hassasiyet gerekiyorsa, arbitrary precision math functions ve gmp işlevleri kullanılabilir.

PS: daha eğlenceli yok:

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

Yani sonsuzluk sonsuzluk ve sonsuzluk değil aynı zamanda sonsuzluğa göre daha küçük ve sonsuza daha büyüktür. Bu konuda düşünürseniz, aslında biraz mantıklı ...

İlgili konular