Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP] Zły wynik konwersji pierwiastka 3 stopnia
mundeck
post 3.03.2015, 19:44:44
Post #1





Grupa: Zarejestrowani
Postów: 43
Pomógł: 0
Dołączył: 2.09.2012

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


Mam taki kod:

  1. for ($i=0; $i <30 ; $i++) {
  2. var_dump(pow(pow($i, 3), 1/3));
  3. var_dump((int) pow(pow($i, 3), 1/3));
  4. echo "<br>";
  5. }


Daje on taki wynik:

float(0) int(0)
float(1) int(1)
float(2) int(2)
float(3) int(3)
float(4) int(3)
float(5) int(4)
float(6) int(5)
float(7) int(6)
float(8) int(7)
float(9) int(8) itd.

Na mój chłopski rozum, pierwiastek z 3 stopnia dowolnej potęgi 3 stopnia z danej liczby daję tę właśnie liczbę, niezależnie od tego, do jakiego typu jest konwertowana. A tutaj począwszy od 4 widoczna jest różnica. Przy konwersji zachodzi jakby odjęcie 1 od wyniku. I to tylko przy wykładniku 1/3, sprawdzałem dla innych i działa poprawnie. O co może chodzić?
Go to the top of the page
+Quote Post
nospor
post 3.03.2015, 22:07:51
Post #2





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




1/3 to nie jest dla komputera jedna trzecia, tylko to jest 0.333333333333333333333333..... i niestety predzej czy poźniej napotkasz na tym poziomie bledy co zresztą wlasnie doswiadczyles


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
blahy
post 3.03.2015, 23:03:28
Post #3





Grupa: Zarejestrowani
Postów: 82
Pomógł: 22
Dołączył: 20.07.2010

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


http://php.net/manual/en/language.types.float.php ramka Floating point precision (floor((0.1+0.7)*10) to 7). I tu nie chodzi o PHP tylko ogolnie reprezentacje liczb zmiennoprzecinkowych: http://floating-point-gui.de/
Zawsze mozna lepiej zaaokraglac wyniki albo uzyc BC Math http://php.net/manual/en/function.bcpow.php
Go to the top of the page
+Quote Post
mundeck
post 4.03.2015, 11:17:22
Post #4





Grupa: Zarejestrowani
Postów: 43
Pomógł: 0
Dołączył: 2.09.2012

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


Poradziłem sobie inaczej, bez użycia pow(). Ale trochę powątpiewam, czy to na pewno wina liczb zmiennoprzecinkowych, bo np. dla 1/11 działa. Poza tym wynik jest w zasadzie liczbą całkowitą, tylko typu float, więc powinien spokojnie zrzutować.
Go to the top of the page
+Quote Post
blahy
post 5.03.2015, 19:03:25
Post #5





Grupa: Zarejestrowani
Postów: 82
Pomógł: 22
Dołączył: 20.07.2010

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


sprawdz jakie masz precission w ini, php to zaokragla. to ze masz var_dump double 5, nie znaczy ze to jest 5 dokladnie...

  1. php > echo number_format(pow(pow(5, 3), 1/3), 10);
  2. 5.0000000000
  3. php > echo number_format(pow(pow(5, 3), 1/3), 100);
  4. 4.999999999999999111821580299874767661094665527343750000000000000000000000000000
    0000000000000000000000

Czyli w wyniku jest 4,999.... rzutowane na int daje 4.
Jeszcze raz odsylam do linkow wyzej. Wystarczy zaokraglac wyniki do wystarczajacej precyzji albo uzyc bcmath.
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: 13.06.2025 - 06:22