SQL oferuje użytkownikom typy danych real i float. Oferują one bardzo dużą dokładność oraz możliwość zapisania w bazie danych bardzo dużych liczb. Zgodnie z informacją z Books Online:
Data type | Range | Storage |
---|---|---|
float | – 1.79E+308 to -2.23E-308, 0 and 2.23E-308 to 1.79E+308 | Depends on the value of n |
real | – 3.40E + 38 to -1.18E – 38, 0 and 1.18E – 38 to 3.40E + 38 | 4 Bytes |
Te typy mają jednak także pewne wady.
Otóż dane w nich zapisywane są w sposób przybliżony. Każdy matematyk potwierdzi, że 1,999999…. (liczba 9 w okresie) to w gruncie rzeczy z matematycznego punktu widzenia już 2. Chociaż dla normalnych ludzi, a nie dla matematyków jest niezrozumiałe… Liczby typu float i real są zmiennoprzecinkowe i z natury nie idealnie dokładne. Co za tym idzie nie można mieć 100% pewności, że 0=0 !
Zobaczmy to na przykładzie. Ile razy wykona się taka pętla?
DECLARE @f float; SET @f = -1; WHILE @f <> 0BEGIN
PRINT @f;
SET @f=@f+0.1;
END
GO Wydawało by się, że skończy się w memencie gdy @f przyjmie wartość zero. A tymczasem na moim kompterze pętla wykonywała się w nieskończoność i trzeba ją było przerwać, zaś na karcie messages wyświetliło się:
-1
-0.9
-0.8
-0.7
-0.6
-0.5
-0.4
-0.3
-0.2
-0.1
-1.38778e-016
0.1
0.2
0.3
0.4
0.5……
O rety! Po wartości -0.1 pojawiła się strasznie mała liczba (rzeczywiście bliska zeru), ale nie zero. Ale nawet gdzy zmieniłem konstrukcję pętli i PRINT wyświetliło „zero”, to i tak nie spowodowało to przerwania pętli. Zobacz np ten fragment kodu dla typu real:
DECLARE @r real; SET @r = 0; WHILE @r <> 1BEGIN
PRINT @r;
SET @r=@r+0.1;
END
To też jest pętla nieskończona, chociaż polecenie PRINT wyświetliło:
00.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1
1.1
1.2
1.3
1.4…
Tak więc, jeśli piszesz aplikację biznesową, a nie naukową staraj się unikać typów float i real, no chyba że szekasz kłopotów….
Przy okazji – real to to samo co float(24), gdzie 24 oznacza ilość bitów przeznaczonych na przechowywanie mantysy liczby.
Komentarze:
[…] Ot zmieni? typ (wi?cej o typach i zwi?zanych z nimi przygodami znajdziesz na Mobilo / mobilo24 tutaj)? DECLARE @smallValue int SET @smallValue = 20000 + 20000 SELECT […]