Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]Zaokrąglone liczby i serializacja
adam882
post 22.08.2014, 18:39:32
Post #1





Grupa: Zarejestrowani
Postów: 289
Pomógł: 1
Dołączył: 2.11.2007

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


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!





Go to the top of the page
+Quote Post
Wazniak96
post 22.08.2014, 18:49:05
Post #2





Grupa: Zarejestrowani
Postów: 550
Pomógł: 75
Dołączył: 5.06.2012
Skąd: Lębork

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


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

Ten post edytował Wazniak96 22.08.2014, 18:55:41
Go to the top of the page
+Quote Post
peter13135
post 22.08.2014, 20:14:42
Post #3





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

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


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ą.


--------------------
:)
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: 20.07.2025 - 08:21