Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php] Porównanie float
Forum PHP.pl > Forum > PHP
markonix
  1. var_dump($price);
  2. var_dump(50.4);
  3. if ($price > 50.4)
  4. echo 't';


Wynik:
Kod
float(50.4)
float(50.4)
t


Jak to jest możliwe?
Jeżeli zrobię rzutowanie na float albo jeszcze raz zadeklaruje wartość to działa ale wg var_dump to jest już float!
Zmienna $price to argument metody. Wygląda to jakby gdzieś po drodze ta zmienna została .. uszkodzona..
Crozin
Zakładam, że zmienna $price jest w wyliczana w jakiś dynamiczny sposób? Wszystko jest w porządku - widocznie ma wartość większą niż 50.4, a jedynie przy wyświetlaniu jest zaokrąglana do jednego miejsca po przecinku.

1. Liczny 50.4 nie da się precyzyjnie zapisać przy pomocy typu float. W rzeczywistości jest to tylko jakieś przybliżenie tej liczby:
  1. printf("%.50f\n", 50.4); // 50.3999999999999985789145284797996282577515

2. https://www.google.com/search?sourceid=chro...600&bih=775

EDIT: Zmienna $price ma wartość większą niż te 50.399...515, które podajesz wpisując 50.4.
markonix
Wszystko się zgadza.
Jest jakiś "naj" sposób? Rzutowanie na float, round przy obliczaniu?
Crozin
@markonix: Generalnie wszystko zależy od konkretnej sytuacji, jednak tutaj powinieneś skorzystać z liczb o "stałej"/dużej precyzji*. W PHP do dyspozycji masz chociażby GMP.
Ewentualnie do porównywania liczb zmiennoprzecinkowych w przypadkach, gdzie nie interesuje nas aż tak bardzo ich dokładność można skorzystać z prostej funkcji:
  1. function compareFloats($a, $b, $epsilon = 0.00001) {
  2. if ($a === $b) {
  3. return true;
  4. }
  5.  
  6. return abs(($a - $b) / $b) <= $epsilon;
  7. }
  8.  
  9. // następie:
  10.  
  11. if (!compareFloats($price, 50.4) && $price > 50.4) {
  12. // ...
  13. }


* Nie mam najmniejszego pojęcia jakie będzie poprawne przetłumaczenie angielskiego arbitrary-precision.
markonix
Myślę, że round do dwóch miejsc po przecinku będzie tutaj najlepszym rozwiązaniem - są to kwoty (ceny) więc i tak dobrze jest to unormować, byle w każdym miejscu jednakowo.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.