Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [php] Porównanie float
markonix
post 9.05.2012, 13:29:53
Post #1





Grupa: Zarejestrowani
Postów: 2 707
Pomógł: 290
Dołączył: 16.12.2008
Skąd: Śląsk

Ostrzeżenie: (0%)
-----


  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..

Ten post edytował markonix 9.05.2012, 13:30:31


--------------------
Go to the top of the page
+Quote Post
Crozin
post 9.05.2012, 13:36:06
Post #2





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


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.

Ten post edytował Crozin 9.05.2012, 13:37:22
Go to the top of the page
+Quote Post
markonix
post 9.05.2012, 15:39:25
Post #3





Grupa: Zarejestrowani
Postów: 2 707
Pomógł: 290
Dołączył: 16.12.2008
Skąd: Śląsk

Ostrzeżenie: (0%)
-----


Wszystko się zgadza.
Jest jakiś "naj" sposób? Rzutowanie na float, round przy obliczaniu?


--------------------
Go to the top of the page
+Quote Post
Crozin
post 9.05.2012, 16:00:19
Post #4





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

Ostrzeżenie: (0%)
-----


@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.

Ten post edytował Crozin 9.05.2012, 16:13:13
Go to the top of the page
+Quote Post
markonix
post 10.05.2012, 10:52:11
Post #5





Grupa: Zarejestrowani
Postów: 2 707
Pomógł: 290
Dołączył: 16.12.2008
Skąd: Śląsk

Ostrzeżenie: (0%)
-----


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.


--------------------
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 26.06.2025 - 01:38