Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> php kilejność działań, Dlaczego PHP nie umie liczyć?
mimol
post
Post #1





Grupa: Zarejestrowani
Postów: 247
Pomógł: 5
Dołączył: 10.12.2007

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


Witam, niedawno miałem problem związany z tym, że PHP nie umie liczyć.
Mógłby ktoś wytłumaczyć mi na czym polega problem?
Wiem, że to ma związek z floating point i precyzją, ale to są PROSTE działania, max 3 miejsca po przecinku...
Załóżmy że mam taki kod
  1. $price = 24.5;
  2. $discountPrice = 7.35;
  3. $discount = $price - $discountPrice;
  4.  
  5.  
  6. $offerValue = 100 * $discount / $price;
  7. var_dump($offerValue); // zwraca ładnie 70
  8. var_dump((int)$offerValue); // zwraca 69 tutaj magia...
  9.  
  10. //idzemy więc dalej
  11. $offerValue = 100 * ($discount / $price);
  12. var_dump((int)$offerValue); // zwraca 70, zmiana kolejności wykonywania działań,


Proszę o podanie jakiegoś powodu dlaczego
  1. //discount / price = 0.7
  2. echo (int)(100 * ($discount / $price)); //70
  3. echo (int)(100 * $discount / $price); //69
  4. echo (int)($discount / $price * 100); //70


ew jak wyświetlić prawdziwą wartość $discount / $price (powinno być 0.7) a pewnie jest (6.9999999999999999999),
Oczywiście poradziłem sobie używając bcmath

Ten post edytował mimol 31.12.2013, 19:10:34
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Crozin
post
Post #2





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

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


Nie jest żadną magiczną liczbą. Popatrz sobie na dokładne wartości liczbowe i ilość dziewiątek po przecinku: http://ideone.com/Bfdmye
Go to the top of the page
+Quote Post
bostaf
post
Post #3





Grupa: Zarejestrowani
Postów: 374
Pomógł: 79
Dołączył: 6.04.2010
Skąd: Ostrów Wielkopolski

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


Cytat(Crozin @ 2.01.2014, 22:34:42 ) *
Nie jest żadną magiczną liczbą. Popatrz sobie na dokładne wartości liczbowe i ilość dziewiątek po przecinku: http://ideone.com/Bfdmye

Dokładnie. To wynika z zaokrąglania pełnej wartości przechowywanej w pamięci. Nie wiem jaka dokładnie jest precyzja wartości przechowywanej w pamięci, ale przy 50 cyfrach po przecinku:
  1. number_format((100 * $discount / $price), 50);
  2. // 69.99999999999998578914528479799628257751464843750000

Zostawiając tylko 14 cyfr dostaniemy:
Kod
69.99999999999998

co zostanie wyświetlone z zaokrągleniem ostatniej 8 do 9, bo kolejna cyfra to 5 (czyli zaokrąglenie w górę).
Przy 13 miejscach po przecinku
Kod
69.9999999999999

co zostanie wyświetlone z zaokrągleniem ostatniej 9 do 0, bo kolejna cyfra to 8 (czyli zaokrąglenie w górę). Zamiana ostatniej cyfry znaczącej na 0 spowoduje łańcuch takich samych zaokrągleń powodujący wyświetlenie tej liczby jako 70,0000000000000.
Go to the top of the page
+Quote Post

Posty w temacie


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

 



RSS Aktualny czas: 27.12.2025 - 14:09