Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [php] Bardzo dziwna sprawa, php twierdzi że
Forum PHP.pl > Forum > Przedszkole
artur81
Witam!
Mam dziwny problem, napisałem niedawno skrypt do obsługi kasy. Wszystko działa ładnie, poza jednym dziwnym zachowaniem. Obsługa polega na wypełnieniu pól z wpłatami, jest kilka opcji do wyboru. Podczas wypełniania na bierząco jest przeliczana suma i prowizja (jej wielkość jest pobierana z bazy) za pomocą Ajax'a. Nie wiem dlaczego tak się dzieje, ale jak w pole gaz wpiszę 126.42, dalej przeklikam się tabulatorem i zaakceptuję wpłatę to pojawia się błąd. Wcześniej miałem funckę która sprawdzała mi czy wpłaty się bilansują tzn. suma wpłat cząstkowych + prowizja = suma wpłat. Jak się nie bilansowało z jakiegoś powodu to program miał zwrocić komunikat o błędzie a jak się bilansują to dodać wpłatę do bazy. Problem pojawił się przy owej magicznej kwocie 126.42, sprawdzałem zmienne pobierane przez skrypt, liczyłem ręcznie i wsio powinno grać, a tymczasem skrypt uparcie twierdzi że suma_getow > suma_wplat (zmienne w kodzie). Zgłupiałem jak to zobaczyłem, tymbardziej ze po "wyechowaniu" zmiennych okazuje się że są one identyczne! Może wy dopatrzycie się jakiegoś babola, bo ja nic nie widzę. Zaczynam od pliku wplada_update.php (to jest oczywiście fragment pliku, wyciąłem z niego pola do danych adresowych, ktore otrzymywalem sesją, więc nie zastanawiajcie sie dlaczego jest rozszerzenia php a nie ma ani grama kodu w php w tym pliku.

wplata_update.php
  1. <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-2" />
  2. <link href="Level3_3.css" rel="stylesheet" type="text/css">
  3. <script type="text/javascript" src="advajax.js"></script>
  4. <script type="text/javascript">
  5. function $(id) {
  6. return document.getElementById(id);
  7. }
  8.  
  9. function przelicz_prowizja() {
  10. var gaz=$("gaz").value;
  11. var prad=$("prad").value;
  12. var tel_kom=$("tel_kom").value;
  13. var tel_stac=$("tel_stac").value;
  14. var isko=$("isko").value;
  15. var inne=$("inne").value;
  16. var zapytanie = "prowizja.php?gaz="+gaz+"&prad="+prad+"&tel_kom="+tel_kom+"&tel_stac="+tel_stac+"&isko="+isko+"&inne="+inne;
  17. advAJAX.get({
  18. url : zapytanie,
  19.  
  20. onSuccess : function(obj) {
  21. document.getElementById("prowizja").value=obj.responseText;
  22. },
  23. onLoading : function(obj) {
  24. document.getElementById("prowizja").value="Przeliczanie...";
  25. }
  26. });
  27. }
  28.  
  29.  
  30.  
  31.  
  32. function $(id) {
  33. return document.getElementById(id);
  34. }
  35.  
  36. function przelicz_suma() {
  37. var gaz=$("gaz").value;
  38. var prad=$("prad").value;
  39. var tel_kom=$("tel_kom").value;
  40. var tel_stac=$("tel_stac").value;
  41. var isko=$("isko").value;
  42. var inne=$("inne").value;
  43. var prowizja=$("prowizja").value;
  44. var zapytanie = "suma.php?gaz="+gaz+"&prad="+prad+"&tel_kom="+tel_kom+"&tel_stac="+tel_stac+"&isko="+isko+"&inne="+inne+"&prowizja="+prowizja;
  45.  
  46. advAJAX.get({
  47. url : zapytanie,
  48.  
  49. onSuccess : function(obj) {
  50. document.getElementById("suma_wplat").value=obj.responseText;
  51. },
  52. onLoading : function(obj) {
  53. document.getElementById("suma_wplat").value="Przeliczanie...";
  54. }
  55. });
  56.  
  57. }
  58.  
  59. function $(id) {
  60. return document.getElementById(id);
  61. }
  62.  
  63. function przelicz_reszta() { //suma+start
  64. var suma_wplat=$("suma_wplat").value;
  65. var kont_gotowka=$("kont_gotowka").value;
  66. var zapytanie = "reszta.php?suma_wplat="+suma_wplat+"&kont_gotowka="+kont_gotowka;
  67.  
  68. advAJAX.get({
  69. url : zapytanie,
  70. onSuccess : function(obj) { document.getElementById("kont_reszta").value=obj.responseText; },
  71. onLoading : function(obj) { document.getElementById("kont_reszta").value="Przeliczanie...";}
  72. });
  73.  
  74. } //suma stop
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81. </head>
  82. <form method="GET" action="wplata_action.php" name="wplata">
  83. <input type = "hidden" name="akcja" value="dodaj">
  84. <input type = "hidden" name="id_wplaty" value=""><table>
  85.  
  86. <tr><td><font color=black><b>Gaz:</b></font></td><td><input type = "text" name="gaz" id="gaz" size="30" title="Gaz" value="0.00" onFocus="przelicz_suma()" onChange="przelicz_prowizja()" onClick="przelicz_prowizja()" onKeyUp="przelicz_suma()"></td></tr>
  87.  
  88. <tr><td><font color=black><b>Prąd:</b></font></td><td><input type = "text" name="prad" id="prad" size="30" title="Prąd" value="0.00" onFocus="przelicz_suma()" onChange="przelicz_prowizja()" onClick="przelicz_prowizja()" onKeyUp="przelicz_suma()"></td></tr>
  89.  
  90. <tr><td><font color=black><b>Isko:</b></font></td><td><input type = "text" name="isko" id="isko" size="30" title="Isko" value="0.00" onFocus="przelicz_suma()" onChange="przelicz_prowizja()" onClick="przelicz_prowizja()" onKeyUp="przelicz_suma()"></td></tr>
  91.  
  92. <tr><td><font color=black><b>Telefonia GSM:</b></font></td><td><input type = "text" name="tel_kom" id="tel_kom" size="30" title="Telefonia GSM" value="0.00" onFocus="przelicz_suma()" onChange="przelicz_prowizja()" onClick="przelicz_prowizja()" onKeyUp="przelicz_suma()"></td></tr>
  93.  
  94. <tr><td><font color=black><b>Telefonia stacjonarna:</b></font></td><td><input type = "text" name="tel_stac" id="tel_stac" size="30" title="Telefonia stacjonarna" value="0.00" onFocus="przelicz_suma()" onChange="przelicz_prowizja()" onClick="przelicz_prowizja()" onKeyUp="przelicz_suma()"></td></tr>
  95.  
  96. <tr><td><font color=black><b>Inne:</b></font></td><td><input type = "text" name="inne" id="inne" size="30" title="Inne" value="0.00" onFocus="przelicz_suma()" onChange="przelicz_prowizja()" onClick="przelicz_prowizja()" onKeyUp="przelicz_suma()"></td></tr>
  97.  
  98. <tr><td><font color=black><b>Suma opłat:</b></font></td><td><input name="suma_wplat" type = "text" id="suma_wplat" style="background:#EEEB7B; font-weight:bold; color:#000000" title="Suma opłat" readonly="" onClick="przelicz_suma()" onKeyUp="przelicz_suma()" value="0.00" size="30" maxlength="7"></td></tr>
  99.  
  100. <tr><td><font color=black><b>Gotówka:</b></font></td><td><input type = "text" name="kont_gotowka" id="kont_gotowka" size="30" title="Gotówka" value="0.00" onChange="przelicz_reszta()" onClick="przelicz_suma()"></td></tr>
  101.  
  102. <tr><td><font color=black><b>Reszta:</b></font></td><td><input name="kont_reszta" type = "text" id="kont_reszta" style="background:#BBD7EE; font-weight:bold" title="Reszta" value="0.00" size="30" maxlength="7" onClick="przelicz_reszta()"></td></tr>
  103.  
  104. <tr><td><font color=black><b>Prowizja:</b></font></td><td><input type = "text" name="prowizja" id="prowizja" size="30" title="Prowizja" value="0.00" onClick="przelicz_prowizja()"></td></tr>
  105. </table><input type="submit" value="Wpłać" title="Wciśnij aby zaakceptować wpłatę"></form>
  106.  
  107. </body>
  108. </html>


wplata_action.php ( w tym pliku byl wczesniej kod do sprawdzania bilanu i wstawiania wplaty do bazy, obenie tylko zwykle wyswietlanie)
  1. <?php
  2. $akcja=$_GET['akcja'];
  3. if ($akcja == 'dodaj') {
  4. $id_wplaty=$_GET['id_wplaty'];
  5. $gaz=(float)$_GET['gaz'];
  6. $prad=(float)$_GET['prad'];
  7. $isko=(float)$_GET['isko'];
  8. $tel_kom=(float)$_GET['tel_kom'];
  9. $tel_stac=(float)$_GET['tel_stac'];
  10. $inne=(float)$_GET['inne'];
  11. $suma_wplat=(float)$_GET['suma_wplat'];
  12. $kont_gotowka=(float)$_GET['kont_gotowka'];
  13. $kont_reszta=(float)$_GET['kont_reszta'];
  14. $prowizja=(float)$_GET['prowizja'];
  15.  
  16.  
  17. $suma_getow=($_GET['gaz']) + ($_GET['prad']) + ($_GET['isko']) + ($_GET['tel_kom']) + ($_GET['tel_stac']) + ($_GET['inne']) + ($_GET['prowizja']);
  18.  
  19. echo 'suma getów - '.$suma_getow.'<br>';
  20. echo 'suma wplat get - '.$suma_wplat.'<br><br>';
  21.  
  22. if ($suma_getow > $suma_wplat )  
  23. { echo 'suma_getow > suma_wplat <br>';  }
  24. elseif ($suma_getow < $suma_wplat)  { echo 'suma_getow < suma_wplat<br>';  }
  25. elseif ($suma_getow == $suma_wplat)  { echo 'suma_getow == suma_wplat<br>'; }
  26. else {echo 'to jakie są w końcu te wpłaty<br>';}
  27.  
  28. }
  29. ?>


i pliki odpowiadające za przeliczenie sumy wpłat i prowizji

suma_wplat.php
  1. <?php
  2. $gaz=$_GET['gaz'];
  3. $prad=$_GET['prad'];
  4. $tel_kom=$_GET['tel_kom'];
  5. $tel_stac=$_GET['tel_stac'];
  6. $isko=$_GET['isko'];
  7. $prowizja=$_GET['prowizja'];
  8. $inne=$_GET['inne'];
  9.  
  10. $suma=$gaz+$prad+$tel_kom+$tel_stac+$isko+$prowizja+$inne;
  11. echo $suma;
  12. ?>


prowizja.php
  1. <?php
  2. $gaz=$_GET['gaz'];
  3. $prad=$_GET['prad'];
  4. $tel_kom=$_GET['tel_kom'];
  5. $tel_stac=$_GET['tel_stac'];
  6. $isko=$_GET['isko'];
  7. $inne=$_GET['inne'];
  8. //pobieranie prowizji
  9. require_once('./polacz_z_baza.php');
  10. $zapytanie="Select * from prowizje";
  11. $wynik = mysql_query($zapytanie) or die ('Nie moge pobrac prowizji');
  12. $rekord=mysql_fetch_array($wynik);
  13. $wielkosc_prowizji=$rekord[1];
  14.  
  15. $prowizja=0;
  16.  
  17. if ($gaz>0) { $prowizja+=$wielkosc_prowizji; }
  18. if ($prad>0) { $prowizja+=$wielkosc_prowizji; }
  19. if ($tel_kom>0) { $prowizja+=$wielkosc_prowizji; }
  20. if ($tel_stac>0) { $prowizja+=$wielkosc_prowizji; }
  21. if ($isko>0) { $prowizja+=$wielkosc_prowizji; }
  22. if ($inne>0) { $prowizja+=$wielkosc_prowizji; }
  23. echo $prowizja;
  24. ?>


Jak dla mnie wszystko jest w porządku, nie mam pojęcia skąd się bierze owa sytuacja, czy może mieć na to wpływ konfiguracja serwera? Mi się wydaje że nie, ba, nawet jestem pewnien że nie, ale mogę się mylić, dlatego chciałbym poznać waszą opinię.
Pozdrawiam!
kszychu
Może spróbuj to też rzutować:
  1. <?php
  2. $suma_getow=(float)$_GET['gaz'] + (float)$_GET['prad'] + (float)$_GET['isko'] + (float)$_GET['tel_kom'] + (float)$_GET['tel_stac'] + (float)$_GET['inne'] + (float)$_GET['prowizja'];
  3. ?>
dr_bonzo
Tak poprostu zachowuje sie reprezentacja liczb zmiennoprzecinkowych (standard ieee754) -- zwiazane jest to z jej reprezentacja w pamieci: w systemie dwojkowym. Nie kazda liczbe ulamkowa w syst. dziesietnym da sie dokladnie reprezentowac w syst. dwojkowym, np: 0.3 (chyba sie nie da, na 95%)
Wiec w czasie dodawania kwot mozesz kilkaktornie utracic dokladnosc co sprowadza sie do 128.92 != 128.92 (prawdop. roznia sie bitem na odleglej pozycji po przecinku, a w syst. dziesietnym jest to niewyswietlane).

Sprobuj zastosowac TYLKO liczby calkowite:
[128.92] kwota
odczytujesz to JSem i robijasz na zlote i grosze: 128zl i 92gr
mozysz zlotowki razy 100 i dodajesz do nich grosze: 12800+92 = 12892
i operuj na takich liczbach -- na pewno bedzie dokladnie,
na koniec rozbij ja na zl i gr zeby ja wyswietlic.
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.