Skocz do zawartości
Ryszka

DOUBLE/DECIMAL - MySQL/PHP - trzymanie precyzji

Polecane posty

Drodzy Forumowicze!

 

Mam pytanie. Klepię obecnie w PHP pewną aplikację.

Problem polega na tym, że mam kwiatki z precyzją liczb gdy korzystam z typu DOUBLE (co zresztą oczywiste).

 

Potrzebuję często dwóch miejsc po przecinku, jednak czasem więcej.

Z tego co się orientowałem to wymagania moje odnośnie przechowywania danych chyba spełni typ DECIMAL w MySQL.

 

Jak jednak wygląda sprawa gdy wyciągnę tego DECIMAL'a z bazy danych MySQL do PHP i na nim wykonuję obliczenia? Czy jest on konwertowany i tak do DOUBLE? (być może to trochę głupie pytanie, bo wtedy ten typ straciłby trochę sens ale jak to jest?)

 

Potrzebuję precyzji czyli 0.1 + 0.01 ma się równać zawsze 0.11 ale także 1000.1 + 0.000001 ma się równać 1000.100001 i na to ma nie być bata.

 

Co polecicie?

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Przy takiej tablicy pobranej z bazy MySQL:

Array
(
    [0] => Array
        (
            [wp_id] => 1
            [0] => 1
            [wp_price] => 8.44
            [1] => 8.44
        )

    [1] => Array
        (
            [wp_id] => 2
            [0] => 2
            [wp_price] => 11.01
            [1] => 11.01
        )

)

Po wykonaniu kodu:

var_dump($rows[0]['wp_price'] + $rows[1]['wp_price']);
var_dump($rows[0]['wp_price'] + 10);
var_dump($rows[0]['wp_price'] + 0.01);
var_dump($rows[1]['wp_price'] / 2);

Dostajesz:

float(19.45)
float(18.44)
float(8.45)
float(5.505)

Struktura wp_price: decimal(20,2)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Tylko, że float w tym przypadku jest wynikowy w MySQL i mozna wyniki float zapisac bez problemu do bazy w decimal

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

float(19.45)
float(18.44)
float(8.45)
float(5.505)

Struktura wp_price: decimal(20,2)

 

Wygląda niby ok ale co mnie zaniepokoiło dostaliśmy float, a float teoretycznie tutaj trzyma precyzję do trzech miejsc po przecinku (nawet więcej). Jak zachowa się to np. dla 9 miejsc po przecinku? Chyba nawet jutro to sam sprawdzę :)

 

 

 

Wielkie dzięki za linka. Zauważyłem jednak, że nie ma w tym arcie opisanego przykładu gdzie wyciągamy tą liczbę z bazy do PHP, wykonujemy na niej obliczenia i otrzymujemy wynik równie precyzyjny. Jest co prawda tam obliczenie ale jest ono wykonywane w zapytaniu MySQL przez MySQL więc MySQL wie, że to DECIMAL i może to zrobić. Pytanie jak sobie radzi samo PHP?

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Gość Kamikadze

Artykuł dość stary i w tedy wykonywane było to jeszcze na mysql_. Teraz raczej z PDO sobie wyciągniesz wszystko. Musisz przetestować bez tego ciężko powiedzieć zwłaszcza dla takich dużych miejsc po przecinku.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Ok. Będę próbował, wielkie dzięki :)

 

Dla potomnych jednak napiszę, że znalazłem to: http://www.php.net/manual/en/ref.bc.php

 

Także nawet jeżeli stockowo PHP nie da rady to myślę z tym już nie powinno być problemów - są tam wszystkie podstawowe operacje + round() napisany w komencie przez usera (nie wiem czy działa w 100% poprawnie ale teoretycznie jest).

 

Jutro wszystko przetestuję.

Wielkie dzięki!

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Decimal zapisuje Ci liczbe tak, jak ją do mysql wrzuciles, float potrafi niestety to przekłamać. Float zajmuje mniej miejsca (fizycznie) w bazie danych ale jeśli zależy Ci na precyzji to decimal jak najbardzij pomoże w tym przypadku.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Dużo zależy od tego co w tej zmiennej trzymasz - double wystarcza do znacznej większości obliczeń zmienno-przecinkowych i ma wystarczająco dobrą precyzję, ale decimal jest obowiązkowy jeśli zmienna ma przechowywać np. kursy walut czy same waluty (które będą przez nie pomnożone).

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Bądź aktywny! Zaloguj się lub utwórz konto

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto

Zarejestruj nowe konto, to proste!

Zarejestruj nowe konto

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się


×