Neden `(19.9 * 100) intval` eşit `1989` mi?

4 Cevap

Evlat, bu bir really garip. Ben aşağıdaki kod 1990 yazdırmak için bekliyoruz, ama 1989 yazdırır!

$val = '$19.9';

$val = preg_replace('/[^\d.]/','',$val);
$val = intval($val * 100);

echo $val;

Neden yeryüzünde böyle oluyor?

Edit: ve bu kodu:

$val = '$19.9';
$val = preg_replace('/[^\d.]/','',$val);
echo $val . "<br>";
$val = $val * 100;
echo $val . "<br>";
$val = intval($val);
echo $val;

Baskılar:

19.9
1990
1989

Neden intval(1990) eşit 1989??

4 Cevap

Bu kayan nokta PHP numaraları ve diğer dillerde çok doğasında hassas bir konudur. Bu hata raporu bir int olarak döküm bağlamında, bunu biraz anlatılır:

http://bugs.php.net/bug.php?id=33731

Try round($val * 100) yerine.

Sorusuna bu tür olağan cevabı okumak için What Every Computer Scientist Should Know About Floating-Point Arithmetic.

Neden (1990) intval 1989 eşit mi??

Çünkü sen not alarak intval(1990). Sen intval($val * 100) burada $val yakın bir sayıdır alarak, ancak 19,9, biraz daha küçük ediyoruz.

Neden bu kadar The Floating-Point Guide anlamak için okuyun.

Bunu düzeltmek için nasıl gelince: Hiç para için kayan nokta değerleri kullanmayın. PHP olarak, BCMath yerine kullanmalısınız.

$val kayan noktalı sayı - sonucu "19.9" * 100. Kayan noktalı sayılar (bu tasarım gereğidir) herhangi bir dilde% 100 doğru değildir. Eğer dolar değerleri için% 100 ondalık doğruluk gerekiyorsa, (Örneğin, "$19.90" 1990 olmalı) tamsayıları kullanmak ve sent kullanarak tüm hesaplamaları yapmalıdır.