Hızlı bir düzeltme olarak bu deneyin:
$price_int = intval(floor($price_corrected + 0.5));
Karşılaştığınız sorun, kayan nokta aritmetiği ile gerçek sayıları kullanarak tüm programlama dilleri benzer sorunları var, PHP'nin hatası değildir.
Parasal hesaplamalar için başparmak genel kural yüzer (veritabanındaki ne de komut ne) kullanmak asla etmektir. Sen her zaman yerine dolar sent saklayarak her türlü sorunları önleyebilirsiniz. Sent tamsayı ve özgürce birlikte ekleyebilirsiniz, ve diğer tamsayılar ile çarpabilirsiniz. Eğer numarasını görüntülemek zaman, son iki basamak önünde bir nokta eklemek emin olun.
Yerine 115 114 alıyorsanız neden nedeni floor
, böylece kat, en yakın tam sayıya doğru, aşağı yuvarlar (114,999999999) 114 olur olmasıdır. * 100 1.15 114,999999999 yerine 115 neden daha ilginç bir soru. Bunun nedeni, 1.15 tam olarak 115/100 değil, 100 ile çarpın eğer, 115 daha küçük biraz daha küçük bir sayı olsun bu yüzden, çok daha az olmasıdır.
İşte echo 1.15 * 100;
ne daha ayrıntılı bir açıklama:
- Bu ikili kayan nokta sayısına 1.15 ayrıştırır. Bu 1.15 yakın ikili kayan nokta sayısını almak için biraz aşağı yuvarlamak olur, yuvarlama içerir. Eğer (yuvarlama hata olmaksızın) bir tam sayı alamayan neden nedeni 1.15 baz 2 sayıların sonsuz sayıda olmasıdır.
- Bu ikili kayan nokta sayısına 100 ayrıştırır. Bu yuvarlama içerir, ancak 100 küçük bir tam sayı olduğu, yuvarlama hata sıfırdır.
- Bu, önceki iki sayının çarpımını hesaplar. Bu, aynı zamanda en yakın ikili kayan nokta sayısını bulmak için, biraz yuvarlama içerir. Yuvarlama hatası bu operasyon sıfır olur.
- Bir nokta ile bir taban 10 ondalık sayıya ikili kayan nokta sayısını dönüştürür ve baskılar bu temsili. Bu da biraz yuvarlama içerir.
PHP şaşırtıcı yazdıran nedeni Corrected price = float(115)
(yerine 114,999 arasında ...) var_dump
(!) Tam sayısını yazdırmak, ama n yuvarlanır numarasını yazar olmamasıdır - 2 (n - 1) n basamaklı hesaplama hassas olan rakam. Bunu kolayca doğrulayabilirsiniz:
echo 1.15 * 100; # this prints 115
printf("%.30f", 1.15 * 100); # you 114.999....
echo 1.15 * 100 == 115.0 ? "same" : "different"; # this prints `different'
echo 1.15 * 100 < 115.0 ? "less" : "not-less"; # this prints `less'
Katları baskı yapıyorsanız, hatırlıyorum: you don't always see all digits when you print the float.
Ayrıca PHP float docs başlangıcına yakın büyük uyarıyı bkz.