Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Dzielenie zmiennych
Forum PHP.pl > Forum > Przedszkole
rkolida
Witam,
niech ktos mi powie dlaczego ten prosty skrypt nie wypisuje w wyniku dzialania: STARCZY PUNKTOW !

co tu jest nie tak questionmark.gif?
  1. <?
  2. $punkty = 0.6;
  3. $ludzie = 3;
  4. $dzielenie = $punkty / $ludzie;
  5.  
  6. if ( $dzielenie >= 0.) {
  7.     echo &#092;"STARCZY PUNKTOW !\";
  8. }
  9.  
  10. ?>


Dodam jeszcze tylko, ze ponizszy dziala, wynik 0.3 jest widziany przez IFa, a 0.2 juz NIE! DLACZEGO questionmark.gifquestionmark.gif
  1. <?
  2. $punkty = 0.6;
  3. $ludzie = 2;
  4. $dzielenie = $punkty / $ludzie;
  5.  
  6. if ( $dzielenie >= 0.) {
  7.     echo &#092;"STARCZY PUNKTOW !\";
  8. }
  9.  
  10. ?>


Czy moze jest jakas funkcja do dzielenia, bo trace glowe jak widze takie sytuacje..
dr_bonzo
Dziel przez 2.0 nie 2 (jesli jedna z liczb jest integerem to wynik tez bedzie)
0.6 / 2 = 0.3 ==> 0
rkolida
Cytat(dr_bonzo @ 2005-04-27 15:04:54)
Dziel przez 2.0 nie 2 (jesli jedna z liczb jest integerem to wynik tez bedzie)
0.6 / 2 = 0.3 ==> 0

To nie pomaga, sprawdzilem. Probuje ustawiac tez wszystkie zmienne settype na double, ale to tez nic nie daje.
Zauwaz, ze w drugim skrypcie tez dziele przez integer i ten skrypt dziala !

I jeszcze co ciekawe:
Jak usawiam punkty 1.6 na przyklad i ludzi 8 to dziala.
A jak ustawiam punkty 1.4 i ludzi 7 to juz nie dziala.
I tak sobie raz dziala raz nie...

Co to jest do cholery za bug questionmark.gif
dr_bonzo
Sorki.
W koncu studia sie do czegos przydadza smile.gif
Floaty sa zapisywane w systemie IEEE 754 (hehe), uzywa on systemu binarnego do zapisania liczby
(1)^(znak) * (znacznik) * 2 ^ (wykladnik) == 32 bity

0.2 w dziesietnym to bedzie
0011 1101 1100 1100 1100 1100 1100 1100b w syst zmiennoprzecinkowym pojedynczej precyzji ieee754

dzielenie 0.6 / 3 tez da ci liczbe z. p. p. ale moze sie troszeczke roznic:
0.6 = 0111 1111 0001 1001 1001 1001 1001 1001b

0.6/3 = 1,(1001)b x 2^(-3) d! =
0111 1101 1100 1100 1100 1100 1100 1100b, hmmm tyle samo

No dobra ja chce miec z tego tylko troje biggrin.gif, moze stosuja inny system zaokraglania, albo gdzies sie machnalem. Zasada jest prosta: 0.2 nie ma skonczonego rozwiniecia w systemi binarnym i 0.2 i 0.6/3 pewnie gdzies sie roznia na odleglym bicie ale przy wyswietlaniu pokazuje ze to takie same wartosci.

http://us4.php.net/operators.comparison
Cytat
Concerning floats: It is simply pointless to compare a float with the value "0.3". The number 0.3 is not exactly representable in binary. Period. So is the number 0.1, and an infinite number of others numbers. Just like 1/3 is not exactly representable in decimal. How would you code the test for your float to be one third? Maybe $myFloat == 0.33333333333  Hmm: you see: Everyone would agree that this test is not accurate.

The test $myFloat == 0.3 is making exactly the same mistake.

So the float which you think should be 0.3 is really something very close to it; if you print it in decimal, the conversion will end up with the closest decimal representation, which may well be "0.3". But "0.3" is also the "right display decimal" for hundreds of float values.

The correct way to "compare" floats is: ( $myFloat - 0.3 ) < $EPSILON where $EPSILON is something like 1e-10, depending on your applic
rkolida
Cytat(dr_bonzo @ 2005-04-27 16:08:29)
Sorki.
W koncu studia sie do czegos przydadza smile.gif
Floaty sa zapisywane w systemie IEEE 754 (hehe), uzywa on systemu binarnego do zapisania liczby
(1)^(znak) * (znacznik) * 2 ^ (wykladnik) == 32 bity

0.2 w dziesietnym to bedzie
0011 1101 1100 1100 1100 1100 1100 1100b w syst zmiennoprzecinkowym pojedynczej precyzji ieee754

dzielenie 0.6 / 3 tez da ci liczbe z. p. p. ale moze sie troszeczke roznic:
0.6 = 0111 1111 0001 1001 1001 1001 1001 1001b

0.6/3 = 1,(1001)b x 2^(-3) d! =
0111 1101 1100 1100 1100 1100 1100 1100b, hmmm tyle samo

No dobra ja chce miec z tego tylko troje biggrin.gif, moze stosuja inny system zaokraglania, albo gdzies sie machnalem. Zasada jest prosta: 0.2 nie ma skonczonego rozwiniecia w systemi binarnym i 0.2 i 0.6/3 pewnie gdzies sie roznia na odleglym bicie ale przy wyswietlaniu pokazuje ze to takie same wartosci.

http://us4.php.net/operators.comparison
Cytat
Concerning floats: It is simply pointless to compare a float with the value "0.3". The number 0.3 is not exactly representable in binary. Period. So is the number 0.1, and an infinite number of others numbers. Just like 1/3 is not exactly representable in decimal. How would you code the test for your float to be one third? Maybe $myFloat == 0.33333333333  Hmm: you see: Everyone would agree that this test is not accurate.

The test $myFloat == 0.3 is making exactly the same mistake.

So the float which you think should be 0.3 is really something very close to it; if you print it in decimal, the conversion will end up with the closest decimal representation, which may well be "0.3". But "0.3" is also the "right display decimal" for hundreds of float values.

The correct way to "compare" floats is: ( $myFloat - 0.3 ) < $EPSILON where $EPSILON is something like 1e-10, depending on your applic

Rany!
Czyli rozumiem ze to blad w oprogramowaniu w samym php a nie z mojej winy ?
Czyli co , nie ma na to sposobu ?
dr_bonzo
1. po co cytujesz taki kawal tekstu jesli TUZ POD NIM odpowiadasz.
2. to nie jest blad, tak po prostu musi byc -- nie da sie odwzorowac zbioru liczb rzeczywistych na 32 bitach (64 lub innej skonczonej ilosci) -- ieee754 tak dziala i sie sprawdza.

3. sprobuj tak:
$dzielenie >= 0.1999999999 (nie przesadz z iloscia dziewiatek, php w domyslnych ustawieniach uzywa tylko 14 cyfr znaczacych, daj ich 10 - 12 -- chyba bedzie ok)
----
0.19999999999999999
dla takiej ilosci jest okj, jedna dziewiatka wiecej i warunek nie jest spelniony
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.