PHP, bu sorunu çözmek için?

4 Cevap php
$onethird = 1.0/3;
$fivethirds = 1.0/3+1.0/3+1.0/3+1.0/3+1.0/3;
$half = 1.0/2;
$threehalf = 1.0/2+1.0/2+1.0/2;
var_dump($onethird + $fivethirds == $half + $threehalf);

hangi çıkışları false, ama hepimizin bildiği gibi: 5/3+1/3=2=3/2+1/2

Bu sorunu çözmek için?

4 Cevap

Bu kayan nokta numaralarının IEEE 754 gösterimi ile ilgili sorunlardan biridir; temsilleri tüm rasyonel sayıları temsil etmek için yeterince doğru değildir.

Bunu yapmak için yol oldukça eşitlik yerine, yakınlık için çok küçük bir dizi karşı farkı karşılaştırmak için:

abs(($onethird + $fivethirds) - ($half + $threehalf)) < 1e-8

Sorun Floating Point arithmetic tarafından tanıtılan küçük hatalar geliyor. Bu PHP özgü değildir.

Siz comparaision yılında ilk değer> = ikinci değer eksi toleransı ve <= ikinci değer artı tolerans olduğunu kontrol ederek, yani küçük bir "hoşgörü" faktörü, getirerek çözebilirsiniz.

var_dump(abs($onethird + $fivethirds - $half + $threehalf) < 0.00001);

see: http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm also: http://docs.sun.com/source/806-3568/ncg_goldberg.html

Bu, tüm programlama dilleri için de geçerlidir.

Ben henüz programcılar yüzen eşitliğini istediğiniz zaman bu otomatik olarak yapılır her dilde rastlamak değil. Birisi belki = ~ = float eşitlik için otomatik olarak epsilon ile diff karşılaştırma yapacağını, hangi yeni bir operatör ile gelmelidir:

if ($float1 =~= $float2) {...

Ben 2000 yılında mezun beri her yıl, yılın bu sefer bazı acemi bazı haber grubu, forum veya e-posta listesine bu soruyu soracaktır ki sinir bozucudur. Sadece geçen ay ben comp.lang.tcl Bu yanıtladı. Ve iki ay önce ben onun Perl kod çalışmıyor neden bana soruyorsun 5 yıldır yazılım geliştirme olmuştur benim iş arkadaşınız için bu açıklamak zorunda kaldı, sadece yenilere değil.

Bu sorunu çözmek için?

Ne actual Sorunu çözmek istiyorsun? Sizin kod sadece kayan noktalı sayıları sınırlı doğruluğa sahip olduğunu gösteriyor - bu yeni bir şey değil.

En gerçek dünya uygulamaları için, zaten% 100 doğru değil giriş ve sonuç sadece ondalık yerlerde birkaç doğru olması gerekir. Eşitlik karşılaştırmaları sadece size çoğu zaman gereken bir şey değildir. Eğer yaparsanız, sonuç verilen bir dizi önceden tanımlanmış bazı küçük mesafesinde olup olmadığını görerek bunu geçiştirmek olabilir.

Belirli hassasiyetle ondalık matematik gerekiyorsa, BC Math fonksiyonları kullanmak - ama karmaşık hesaplamalar için kullanılırsa o çok yavaş olduğunu fark.