MySQL - float, double, decimal

0

Jest tabelka z kolumną typu float, double, decimal(10,3). We wszystkie wstawiamy tę samą wartość: 12345.67

Jak to jest z precyzją float'a skoro jako jedyny pokazuje "śmieci" bo w wyniku otrzymujemy 12345.7
To nie jest przecież jakieś wielkie wymaganie, aby float pomieścił liczbę z precyzją 7 cyfr, Jak to jest z domyślnymi ustawieniami floata. Wiem, że można jeszcze w nawiasie podać np. float (10,2) i zadziała, ale jestem ciekaw jak sprawa wygląda domyślnie

0

Tak, ja wiem na czym polega zaokrąglanie itd. Przykładowo nigdy w kodzie nie znadziemy u mnie dla floata:
if (x == 1.02)
zawsze będzie wymuszenie przedziału z uwzględnieniem dokładności.

Jestem poinformowany o tym, że zapis binarny nie zawsze jest możliwy dla zapisu dziesiętnego (części ułamkowej).

Kłopot jednak w tym, że MySQL dla floata nie przeszkadza zaokrąglanie nawet liczb dziesiętnych np. 12345678 zostaje ucięte i pojawia nam się zero zamiast pełnej liczby. Kłopot jest tym większy, że MySQL przechowuje prawidłowo zapisaną wartość, ale niechlujnie zwraca ją obciętą (przybliżoną). Po prostu pomiędzy skryptem a bazą danych już w chwili zwracania, zwracana jest wartość bezprawnie zaokrąglona.

I tu moje pytanie: jak zmusić MySQL, żeby zwracał mi pełne rozwinięcie liczby, dokładnie tak jak jest ona zapisana wewnątrz bazy, bez stosowania jakichkolwiek zaokrągleń i zaokrąglenia pozostawi mi.

Offtop.
Co do zaokrąglania cen, to tutaj tesco pobiło wszystkie faktury z "błędami' jakie do tej pory widziałem. Tam na fakturze dostałem w podsumowaniu zsumowane wszystkie kolumny z wartością brutto, wartością netto i podatkiem VAT. To jest po prostu jakaś kpina, bo z podsumowania wynikało, że NETTO+VAT != BRUTTO ;). Ktoś poszedł kompletnie na łatwiznę i wszystko zsumował, zamiast prawidłowo na końcu rozbić wszystkie kwoty brutto na poszczególne stawki VAT (akurat ja miałem wszystko 23%), następnie z uzyskanych wartości obliczyć podatek i kwotę netto bez wdawania się w sumowanie tego co jest przy poszczególnych produktach, bo tak się nie robi z powodu możliwych powstających błędów zaokrągleń.

0

myślę że Twój problem jest po stronie aplikacji, która na jakimś etapie (stawiał bym na interfejs użytkownika i samą wizualizację) zaokrągla dane pobrane z bazy

0

Nie jest to możliwe. Zmieniam w tabelach na double i wyniki są piękne. Zmianiam na decimal(10,5) i wyniki są piękne. A nawet proste zapytanie sql "Select * From tabela" daje błędne wyniki. Pozostaje jedynie w zapytaniach dodawać np round lub cast lub strukturę tabeli zmienić na np. float(10, 3) i będzie ok.

Wydaje mi się, że problem tkwi w tym, że zapytania sql z poziomu PHP dają wręcz identyczne wyniki co te wyświetlające normalnie tabele, a to oznacza, że sql do zapytań celowo formatuje wartości liczbowe, aby były one bardzie przystępne przy wyświetlaniu... niestety, to co jest dobre do wyświetlania wyników w zapytaniach sql, jest beznadziejnym rozwiązaniem przy przekazywaniu wartości między programami. Przykładowo mamy miernik temperatury. Mierzy z rozdzielczością 0.01st. Na wyświetlaczu wyświetla z rozdzielczością 0.1st. Ale interfejsem jakimkolwiek zdecydowanie powinien wysyłać wartość w ogóle niezaokrągloną, aby to użytkownik mógł zdecydować co dalej z nią zrobić, czy przyciąć czy nie przyciąć. Zapytania SQL jednak tak akurat nie działają domyślnie i to samo o co pytamy np. w phpmyadmin to dokładnie to samo dostajemy w skypcie php, chociaż mechanizmy prezentacji wyników powinny być: pierwszy uproszczony, drugi w pełni dokładny.

Przestroga przed używaniem float, double i decimal nie jest tutaj konieczna tak bardzo jak przestroga dotycząca tego, że zapytania zwracają nie tylko uproszczony wynik kiedy zadajemy je z konsoli czy z poziomu phpmyadmin'a, ale dają równie uproszczone wyniki przy zapytaniach z poziomu skryptów. I choć wydaje się to logiczne, że wyniki są identyczne, to mechanizm taki mocno wprowadza w błąd, gdyż w bazie danych może widnieć liczba 1234567.8910000... (trzy po przecinku są ważne) a wyświetli się domyślnie 1234570 bez kropki... utnie nawet jedności. I półbiedy gdyby ucinało tylko wynik przy prezentowaniu, ale przy przekazywaniu go pomiędzy bazą a skryptem również go ucina. I to już nie jest fajne.

0

Myślę że to nie baza danych przekłamuje i zaokrągla, a problem jednak jest po stronie aplikacji. Być może aplikacja nieprawidłowo "obrabia" dane typu float. Przecież nie czytasz wprost tego co odpowiada baza, bo zapewne korzystasz z warstw pośrednich (klas) "wrapujących" dostęp do danych.
Pisałem o "user interface", ale problem równie dobrze może tkwić w niższych warstwach dostępu do danych z bazy
Mogę się mylić, bo MySql to trochę nie moja bajka

0

Wiesz co, korzystam z PHP, a pośrednikiem jest mysqli:
http://php.net/manual/en/book.mysqli.php
czyli nie korzystam z niczego nadzwyczajnego. Kłopot w tym, że zapytania zadane przez mysqli dają identyczny wynik jak zadałbym je z konsoli, w efekcie dostaje coś co ładnie wygląda zamiast coś co powinienem sam obrobić, żeby ładnie wyglądało :). Żeby otrzymać coś mądrzejszego musiałbym absurdalnie dla każdego zapytania dodawać round lub cast, aby uzyskać dokładniejsze wyniki, ale to zbyt inteligentne nie jest jeśli do komunikacji z bazą musimy wymuszać dokładność z jaką otrzymamy wyniki. To trochę tak, jakby w języku C przy przypisaniu:
float a = 1234567.7891;
float b = a;
gdzie przy b=a musiałbym określić z jaką dokładnością otrzymam wynik przypisania do b wartości a, bo jeśli tego nie zrobię to otrzymam np. b == 1234560 :). I to mi się właśnie nie podoba. Co innego wyrzucić zaokrąglenia na ekran z automatu, a co innego martwić się tym na etapie "przypisań" w kodzie źródłowym.

1 użytkowników online, w tym zalogowanych: 0, gości: 1