mysql float精度與範圍總結

2021-07-12 03:22:46 字數 3691 閱讀 6545

float型別用於表示近似數值資料型別。sql標準 允許在關鍵字float後面的括號內選擇用位指定精度(但不能為指數範圍)。mysql還支援可選的只用於確定儲存大小的精度規定。0到23的精度對應 float列的4位元組單精度。24到53的精度對應double列的8位元組雙精度。

單精度浮點數用4位元組(32bit)表示浮點數

採用ieee754標準的計算機浮點數,在內部是用二進位制表示的

如:7.22用32位二進位制是表示不下的。

所以就不精確了。

mysql中float資料型別的問題總結 

對於浮點列型別,在mysql中單精度值使用4個位元組,雙精度值使用8個位元組。

float型別用於表示近似數值資料型別。sql標準允許在關鍵字float後面的括號內選擇用位指定精度(但不能為指數範圍)。mysql還支援 可選的只用於確定儲存大小的精度規定。0到23的精度對應float列的4位元組單精度。24到53的精度對應double列的8位元組雙精度。

mysql允許使用非標準語法:float(m,d)或real(m,d)或double precision(m,d)。這裡,「(m,d)」表示該值一共顯示m位整數,其中d位位於小數點後面。例如,定義為float(7,4)的乙個列可以 顯示為-999.9999。mysql儲存值時進行四捨五入,因此如果在float(7,4)列內插入999.00009,近似結果是999.0001。

mysql將double視為double precision(非標準擴充套件)的同義詞。mysql還將real視為double precision(非標準擴充套件)的同義詞,除非sql伺服器模式包括real_as_float選項。

為了保證最大可能的可移植性,需要使用近似數值資料值儲存的**應使用float或double precision,不規定精度或位數。

decimal和numeric型別在mysql中視為相同的型別。它們用於儲存必須為確切精度的值,例如貨幣資料。當宣告該型別的列時,可以(並且通常要)指定精度和標度;例如:

salary decimal(5,2)

在該例子中,5是精度,2是標度。精度表示儲存值的主要位數,標度表示小數點後面可以儲存的位數。

在mysql 5.1中以二進位制格式儲存decimal和numeric值。

標準sql要求salary列能夠用5位整數字和兩位小數儲存任何值。因此,在這種情況下可以儲存在salary列的值的範圍是從-999.99到999.99。

在標準sql中,語法decimal(m)等價於decimal(m,0)。同樣,語法decimal等價於decimal(m,0),可以通過計算確定m的值。在mysql 5.1中支援decimal和numeric資料型別的變數形式。m預設值是10。

decimal或numeric的最大位數是65,但具體的decimal或numeric列的實際範圍受具體列的精度或標度約束。如果此類列分配 的值小數點後面的位數超過指定的標度允許的範圍,值被轉換為該標度。(具體操作與作業系統有關,但一般結果均被擷取到允許的位數)。

二、mysql 和 oracle中的數值型別

問題是不是只有 mysql 存在呢?顯然不是,只要是符合ieee754標準的浮點數實現,都存在相同的問題。

mysql中的數值型別(不包括整型):

ieee754浮點數:float(單精度),double或real(雙精度)  

定點數:decimal或numeric

oracle中的數值型別:

oracle 浮點數 :number(注意不指定精度)  

ieee754浮點數:binary_float(單精度),binary_double(雙精度)float,float(n) (ansi要求的資料型別)

定點數:number(p,s)

如果在oracle中,用binary_float等來做測試,結果是一樣的。因此,在資料庫中,對於涉及貨幣或其他精度敏感的資料,應使用定點數來存 儲,對mysql來說是 decimal,對oracle來說就是number(p,s)。雙精度浮點數,對於比較大的資料同樣存在問題!

三、程式設計中也存在浮點數問題

不光資料庫中存在浮點數問題,程式設計中也同樣存在,甚至可以說更值得引起注意!

通過上面的介紹,浮點數的誤差問題應該比較清楚了。如果在程式中做複雜的浮點數運算,誤差還會進一步放大。因此,在程式設計中,如果用到浮點數,一定要意 識到可能產生的誤差問題。不僅如此,浮點數如果處理不好,還會導致程式bug!看下面的語句:if (x != y) 這個語句看起來沒有問題,但如果是浮點數,就可能存在問題!再看下面的語句會輸出什麼結果: public class test }     我們可能會想當然地認為輸出結果應該是 0.22 ,實際結果卻是 0.21999979 !

因此,在程式設計中應盡量避免做浮點數的比較,否則可能會導致一些潛在的問題!除了這些,還應注意浮點數中的一些特殊值,如 nan、+0、-0、+無窮、-無窮等,ieee754雖然對此做了一些約定,但各具體實現、不同的硬體結構,也會有一些差異,如果不注意也會造成錯誤! 四、總結:

從上面的分析,我們可以得出以下結論:

1、浮點數存在誤差問題;

2、對貨幣等對精度敏感的資料,應該用定點數表示或儲存;

3、程式設計中,如果用到浮點數,要特別注意誤差問題,並盡量避免做浮點數比較;

4、要注意浮點數中一些特殊值的處理。

例項為了能夠引起大家的重視,在介紹浮點數與定點數以前先讓大家看乙個例子:

**如下

mysql> create table test (c1 float(10,2),c2 decimal(10,2));

query ok, 0 rows affected (0.29 sec)

mysql> insert into test values(131072.32,131072.32);

query ok, 1 row affected (0.07 sec)

mysql> select * from test;

+-----------+-----------+

| c1| c2|

+-----------+-----------+

| 131072.31 | 131072.32 |

+-----------+-----------+

1 row in set (0.00 sec)

從上面的例子中我們看到c1列的值由131072.32變成了131072.31,這就是浮點數的不精確性造成的。

在mysql中float、double(或real)是浮點數,decimal(或numberic)是定點數。

浮點數相對於定點數的優點是在長度一定的情況下,浮點數能夠表示更大的資料範圍;

它的缺點是會引起精度問題。

float型別和double型別的區別

float[(m,d)]   [zerofill]  

乙個小(單精密)浮點數字。不能無符號。允許的值是-3.402823466e+38到-1.175494351e-38,0   和1.175494351e-38到3.402823466e+38。m是顯示寬度而d是小數的位數。沒有引數的float或有 <24   的乙個引數表示乙個單精密浮點數字。  

double[(m,d)]   [zerofill]  

乙個正常大小(雙精密)浮點數字。不能無符號。允許的值是-1.7976931348623157e+308到 -2.2250738585072014e-308、   0和2.2250738585072014e-308到1.7976931348623157e+308。m是顯示寬度而d是小數字數。沒有乙個引數的 double或float(x)(25   <   =   x   <   =   53)代表乙個雙精密浮點數字。

mysql float精度與範圍總結

float型別用於表示近似數值資料型別。sql標準 允許在關鍵字float後面的括號內選擇用位指定精度 但不能為指數範圍 mysql還支援可選的只用於確定儲存大小的精度規定。0到23的精度對應 float列的4位元組單精度。24到53的精度對應double列的8位元組雙精度。單精度浮點數用4位元組 ...

MySQL float 型別的精度

總結 要得到1位或2位精確小數的話,整數不能高於 32767 即 f 32767.99 因為 2e15 32768 所以最多只能正確處理0 32767的整數,要得到3位 精確 小數的話,整數不能高於16383 即 f 16383 999 因為 2e14 16384 要得到4位 精確 小數,整數不能高...

float與double的範圍和精度

floa 與 double 的範圍和精度 1.範圍 float和double的範圍是由指數的位數來決定的。float的指數字有8位,而double的指數字有11位,分布如下 float 1bit 符號位 8bits 指數字 23bits 尾數字 double 1bit 符號位 11bits 指數字 ...