Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Zaokrąglone liczby i serializacja
Forum PHP.pl > Forum > Przedszkole
adam882
Witam

Przykladowo posiadam wartość w tablicy, którą zaokrąglam do jednego miejsca po przecinku:

  1. $tablica['srednia'] = round($wynik, 1);


Tablica wygląda tak:

Array
(
[srednia] => 42.9
)

Problem pojawia się w momencie, gdy chcę tego typu tablicę zapisać do bazy danych w formie zserializowanej.

  1. $do_zapisu_w_mysql = addslashes(serialize($tablica));


Okazuje się, że mimo użycia round(), zapisuje się w bazie liczba 42.89999999999999857891452847979962825775146484375 zamiast 42.9 .
Niby nie jest to poważny problem, ale przez tak długą i niepotrzebną liczbę, rekordy w bazie mogą niepotrzebnie zajmować więcej miejsca.

Jak można zrobić, aby zapisana w tablicy wartość do bazy była zaokrąglona?
I tak na marginesie chciałbym też zapytać się, czy po serializacji i przed dodaniem wartości do bazy warto zabezpieczyć ją dodatkowo funkcją addslashes() dla pewności ?


Pozdrawiam!





Wazniak96
Rzutuj wynik zaokrąglenia do String. Winowajcą jest serialize. smile.gif

  1. $tablica['srednia'] = (String) round($wynik, 1);


Co do drugiego pytania:
Dane do bazy danych raczej filtruje się przez funkcję mysql_real_escape_string. Ale raczej radziłbym Ci zainteresować się biblioteką PDO i bindowaniem
peter13135
Cytat
Winowajcą jest serialize.

Niekoniecznie "winny".
Liczby float i double (zmiennoprzecinkowe) są zapisywane w pamięci komputera w postaci wykładniczej. Dowiedz się co to cecha i mantysa, to wszystko się wyjaśni. W skrócie wadą tego systemu zapisu jest to, że jak przypiszesz sobie do jakiejś zmiennej jakąś wartość ułamkową, to komputer najprawdopodbniej nie będzie potrafił zapisać dokładnie takiej liczby w swojej pamięci - zapisze więc jej przybliżoną wartość. Czyli zamiast 42.9 będzie owe 42.89999999999999857891452847979962825775146484375. Właśnie dlatego, ceny (tutaj ważna jest dokładność, żeby wszystko zgadzało się co do grosza i ceny po różnych operacjach nie wychodziły z więcej niż dwoma miejscami po przecinku) w bazie danych nie powinny być zapisywane jako liczby zmiennoprzecinkowe (float,double) ale jako liczby stałoprzecinkowe - decimal (zdaje się, że tu jest używane BCD skoro każda cyfa po przecinku zajmuje 4 bity) lub int (w tym przypadku liczbę 1234 traktujesz 12.34 - przy założeniu, dwóch miejsc po przecinku).

Dlatego, tak naprawdę nie ma żadnego znaczenia, czy liczbę float najpierw zrzutujesz do stringa i dopiero potem zserializujesz, czy zserialzujesz od razu, bo po odwórceniu procesu (deserializacja i ewentualne rzutowania ze stringa na float) Twoja wartość w pamięci komputera i tak nie będzie idealnie równa 42.9 tylko wartość przybliżoną.
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.