Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [mysql+php] dziwne zachowanie z UPDATE do float
Forum PHP.pl > Forum > Przedszkole
Snoopy
Mam pole w tabeli typu float, i wszystko działa pięknie do momentu zrobienia UPDATE'u na tym polu. Dokonuję pewnych zmian w skrypcie php na wartości z tego pola a poźniej chcę zaktualizować to pole ale już ze zmienioną wartością.

Dla przykładu...

  1. <?php
  2. $wart = mysql_fetch_assoc(mysql_query("SELECT * FROM info WHERE id='1'"));
  3. echo $wart['cena']; //wyświetla 1000.00 - czyli poprawnie
  4. $new = $wart['cena'] - 20;
  5. echo $new; // wyświetla 980.00 - czyli poprawnie
  6. mysql_query("UPDATE tab SET cena='$new' WHERE id='1'");
  7. // --------------------------------------
  8. $wart2 = mysql_fetch_assoc(mysql_query("SELECT * FROM info WHERE id='1'"));
  9. echo $wart2['cena']; // wyświetla 978.00 - i o co tu chodzi?
  10. ?>


No i już nie mam pojęcia o co chodzi. Skrypt mam bardzo rozbudowany ale dla pewności że nie ma żadnych anomalii, wstawiłem zaraz po UPDATE, exit; więc skrypt nie jest dalej wykonywany, a tuż przed UPDATE dałem echo żeby sprawdzić jaką wartość zapytanie aktualizuje, i niby jest wszystko ok... czy ja jako początkujący zapomniałem o czymś?

PS. znaki \" jakoś same się dodały i nie wiem jak je wywalić, sorki jeśli kod jest mało czytelny
em_pl
Sprawdź jak w tabeli masz zdefiniowany float (PEWNIE DECIMAL 7,0) jak tak to zmień np na 7,2.
Snoopy
mam ustawione na 10,2 czyli jesli dobrze rozumiem pole zapisuje max 10 cyfr z czego 2 są to cyfry po przecinku
I dalej mnie to wkurza :/
artur81
A sprawdzałeś jak będzie jak odejmiesz 20,00?
Poza tym powinieneś zaokrągląć te liczby, do wartości po przecinku jakiej się spodziewasz. Jeśli to są kwoty to rób zaokrąglanie do dwóch miejsc. Kiedyś miałem spore porblemy jak nie zaokrąglałem obliczeń.
Niby jak wyświetlałem wyniki echem to były równe a jednak się różniły na 7 cz 8 miejscu po przecinku.
Sedziwoj
Po pierwsze cen nie zapisuje się w ten sposób, reprezentacja dziesiętna jest nie dokładna w zapisie dwójkowym. Prawidłowo nie powinno się zapisywać tylko w całości czyli złotówki i grosze osobno, gdyby ktoś napisał w ten sposób program księgowy to by były jaja biggrin.gif
Snoopy
zamiast pisać jak sie nie powinno zapisywać moglbys napisać jak Zapisywać, żeby było dobrze
JaRoPHP
Cytat(Sedziwoj @ 27.11.2006, 19:00:59 ) *
Prawidłowo nie powinno się zapisywać tylko w całości czyli złotówki i grosze osobno...
Niezły misz-masz; zdanie kompletnie nie zrozumiałe dla mnie... @Sedziwoj masz na myśli, aby część całkowitą ceny (np. złotówki) przechowywać w jednej kolumnie tabeli, a część ułamkową (np. grosze) w drugiej?

@Snoopy - wykonaj zapytanie tylko w bazie danych (w SQL), nie angażując w to php i zobacz, czy otrzymane wyniki są zgodne z oczekiwaniami (np. sprawdzając tylko wartości w odpowiedniej kolumnie).
Sedziwoj
Tak to mam na myśli, czyli nie jedna kolumna 'cena float', a dwie 'cena_zl int, cena_gr int'.
Wiesz, cały kłopot jest w tym, że w zapisie binarnym 0,1 ma postać binarną 111111111111111111111.... czy coś w tym stylu (nie chce mi się przypominać systemów 'ułamkowych') ale chodzi o to że jest nieskończoność, więc przy większej liczbie operacji (a wcale nie jest to tak duża liczba) wychodzi że 1zł + 1zł = 2,01zł (lub podobnie) dlatego części dziesiętne (jeśli mają być precyzyjne i maja ograniczoną długość) lepiej zapisywać osobno. Na pewno ta zasada tyczy się systemów finansowych.

...
Teraz też sobie pomyślałem że można również przechowywać cena jako ilość groszy, czyli nie 1zł 20gr tylko 120gr biggrin.gif
artur81
Pisałem wyżej: zaokrąglaj każde działanie do takiej części ułamkowej jaka jest istotna i nie będzie takich numerów
jak robisz sobie np dodawanie:
$wwynik = round($liczba1+$liczba2,2);
i wtedy zaokrąglisz do dwóch miejsc po przecinku,
Pisałem kiedyś program kasowy i wiem że były niezłe jaja bez zaokrąglania, bo liczby się różniły na dalszych miejscach po przecinku i się wpłaty i wypłaty nie chciały bilansować.
Sedziwoj
Ale mimo wszystko to jest robienie na siłę i ryzykowaniem, że coś będzie nie tak. Ja bym się pod takim programem nie podpisał.
Jest pewne że nie ma dobrej reprezentacji ułamków dziesiętnych w zapisie dwójkowym, więc powinno się to omijać. Są programy które działają i są dobre programy.
Ja stawiam EOT, chyba że ktoś poruszy coś ciekawego.
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.