MySQL 浮點型表示,mysql浮點型
MySQL浮點型和定點型可以用類型名稱後加(M,D)來表示,M表示該值的總共長度,D表示小數點後面的長度,M和D又稱為精度和標度,如float(7,4)的可顯示為-999.9999,MySQL儲存值時進行四捨五入,如果插入999.00009,則結果為999.0001。FLOAT和DOUBLE在不指定精度時,預設會按照實際的精度來顯示,而DECIMAL在不指定精度時,預設整數為10,小數為0。
建立下表:
mysql> CREATE TABLE t2(id1 FLOAT(5,2) DEFAULT NULL,id2 DOUBLE(5,2) DEFAULT NULL,id3 DECIMAL(5,2) DEFAULT NULL);
mysql> DESC t2;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id1 | float(5,2) | YES | | NULL | |
| id2 | double(5,2) | YES | | NULL | |
| id3 | decimal(5,2) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
往id1,id2,id3這三個欄位中插入資料1.23:
mysql> INSERT INTO t2(id1,id2,id3) VALUES(1.23,1.23,1.23);
mysql> SELECT * FROM t2;
+------+------+------+
| id1 | id2 | id3 |
+------+------+------+
| 1.23 | 1.23 | 1.23 |
+------+------+------+
資料都正確插入,再向id1插入1.234,id2插入1.234,id3仍然插入1.23:
mysql> INSERT INTO t2(id1,id2,id3) VALUES(1.234,1.234,1.23);
mysql> SELECT * FROM t2;
+------+------+------+
| id1 | id2 | id3 |
+------+------+------+
| 1.23 | 1.23 | 1.23 |
| 1.23 | 1.23 | 1.23 |
+------+------+------+
資料全部正確插入,但是id1和id2由於標度的限制,捨去了最後一位。
同時向id1,id2,id3中插入資料1.234:
mysql> INSERT INTO t2(id1,id2,id3) VALUES(1.234,1.234,1.234);
Query OK, 1 row affected, 1 warning (0.02 sec)
mysql> SELECT * FROM t2;
+------+------+------+
| id1 | id2 | id3 |
+------+------+------+
| 1.23 | 1.23 | 1.23 |
| 1.23 | 1.23 | 1.23 |
| 1.23 | 1.23 | 1.23 |
+------+------+------+
3 rows in set (0.00 sec)
資料也插入成功,但是有一個錯誤提示,
mysql> SHOW warnings;
+-------+------+------------------------------------------+
| Level | Code | Message |
+-------+------+------------------------------------------+
| Note | 1265 | Data truncated for column 'id3' at row 1 |
+-------+------+------------------------------------------+
1 row in set (0.00 sec)
將id1,id2,id3的精度和標度都去掉,再插入資料1.234:
mysql> ALTER TABLE t2 MODIFY id1 FLOAT;
Query OK, 0 rows affected (0.14 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE t2 MODIFY id2 DOUBLE;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> ALTER TABLE t2 MODIFY id3 DECIMAL;
Query OK, 4 rows affected, 4 warnings (0.06 sec)
Records: 4 Duplicates: 0 Warnings: 4
mysql> DESC t2;
+-------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| id1 | float | YES | | NULL | |
| id2 | double | YES | | NULL | |
| id3 | decimal(10,0) | YES | | NULL | |
+-------+---------------+------+-----+---------+-------+
mysql> INSERT INTO t2(id1,id2,id3) VALUES(1.234,1.234,1.234);
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> SHOW WARNINGS;
+-------+------+------------------------------------------+
| Level | Code | Message |
+-------+------+------------------------------------------+
| Note | 1265 | Data truncated for column 'id3' at row 1 |
+-------+------+------------------------------------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM t2;
+-------+-------+------+
| id1 | id2 | id3 |
+-------+-------+------+
| 1.234 | 1.234 | 1 |
+-------+-------+------+
1 row in set (0.00 sec)
id1和id2的資料正確插入,而id3被截斷。
浮點數如果不寫精度和標度,則會按照實際顯示,如果有精度和標度,則會將資料四捨五入後插入,系統不報錯,定點數如果不設定精度和標度,剛按照預設的(10,0)進行操作,如果資料超過了精度和標度值,則會報錯。
mysql的浮點型在什情況下會損失精度,詳解、、
談談個人理解,請帶著懷疑和鑒別的角度去看待。
1 先理解下定點數
--定義:
指規定小數點位置固定不變。
--儲存:
* 在資料庫或電腦中儲存時,整數部分和小數部分分別使用一定的位元組來儲存(理解為分別用兩部分位元組來儲存兩個整數),小數點是作為儲存屬性儲存區的(如作為列類型時,小數點位置儲存在表的定義部分),而不佔用資料的儲存位元組。
* 定點數使用多少位元組來存放資料,依賴於該數指定的精度(精度即為該數的總數字位元),總數字位元為小於2則使用1位元組,為5-9位時用4位元組,為19-38位時使用16位元組(大部分資料庫支援的最大就是38位元字);
--舉例:
numeric(2,1),精度為2,使用1個位元組來存放,存放資料範圍為[-9.9, 9.9];如儲存2.3時,在資料庫儲存為00100011,而小數位置固定在第四位前,這是由定義列時指明的;
--說明:
定點數儲存精確的數字,numeric(2,1)就只能[-9.9, 9.9]之間的數,存的不是近似數(因為兩部分都作為整數儲存);當你在numeric(2,1)中儲存2.33時,實際發生了隱式轉換,實際儲存為9.3(注意這並不是近似);
2 再來理解浮點數
--定義:
指採用浮點數表達方式來表示資料,這種表達方式利用科學計數法來表達實數,即用一個尾數(Mantissa ),一個基數(Base),一個指數(Exponent)以及一個表示正負的符號來表達資料,比如 123.45 用十進位科學計數法可以表達為 1.2345 × 10^2,其中 1.2345 為尾數,10 為基數,2 為指數。稱其為浮點數就是因為利用指數達到了浮動小數點的效果。
--儲存:
浮點數一般是使用IEEE規定的方式,即 對於單精確度浮點數用1bit來儲存符號位(加號或減號),8bit來儲存指數,23bit來儲存尾數;而且要求尾數的整數部分為1(注意,指二進位格式的,如1.01001),而且是使用二進位來儲存,即基數為2;
在大多數資料庫或電腦中儲存時,單精確度使用4位元組,雙精確度使用8位元組儲存;
--舉例:
二進位的 1001.101(對應於十進位的 9.625)可以表達為 1.001101 × 2^3,儲存時符號位+儲存為0,指數3儲存為00000011,尾數1.001101儲存為0011010000..(總共23位,去掉了小數點前的1,IEEE就是這樣要求的);
--近似的產生:
因為我們使用的是十進位數,而電腦要轉換為對應的二進位形式,由於有限的2進位位元表示的小數值不能和十進位一一對應(換句話說,十進位小數轉為二進位可能變為無限小數而導致不精確 ),如2^-1對應0.5,2^-2對應0.25,2^-3對應0.125,因此對於像十進位的0.4(小數的末尾一位元不為5的)則不能精確儲存;
--因近似引起的問題:
create table t (a float, b float); insert into t values(0.11, 0.04), (0.04, 0.11);
select * from t; 查詢時顯示正常,實際底層儲存時發生了近似(十進位轉換為二進位),而顯示時又發生了近似(二進位轉換為十進位);
select sum(a) from t; 查詢顯示 0.14999999850988388 ,為什麼不是0.15的原因也就不言而喻了。
這也就是浮點數在損失精度、計算和比較要格外注意的事項;
3 總結
定點數,能儲存精確數......餘下全文>>
“浮點型資料”是什?為何叫浮點型?
簡單說就是表示帶有小數的資料,與之相對的是整型,也就是只能儲存整數。
特別要說的是電腦儲存浮點型資料是儲存一個有效數字,然後儲存一個介碼,就像科學計數法一樣儲存資料。