MySQL浮点类型
MySQL浮點類型
1:類型介紹
浮點數和定點數類型的特點是可以 處理小數 ,你可以把整數看成小數的一個特例。因此,浮點數和定點
數的使用場景,比整數大多了。
MySQL支持的浮點數類型,分別是 FLOAT、DOUBLE、REAL。
注意:上面提到可以把整數看成小數的一個特例,所以例:我們向一個FLOAT型字段插入一個整數是可以的,只是存儲的時候后面加個.00而已
-
FLOAT 表示單精度浮點數
-
DOUBLE表示雙精度浮點數
-
REAL默認就是DOUBLE。如果你把SQL模式設定為啟用"REAL_AS_FLOAT",那么MySQL就認為REAL是FLOAT。如果你要這樣啟用,可通過以下SQL語句實現。
SET sql_mode = “REAL_AS_FLOAT”;
注意:
MySQL 存儲浮點數的格式為: 符號(S) 、 尾數(M) 和 階碼(E) 。
因此,無論有沒有符號,MySQL 的浮點數都會存儲表示符號的部分。因此, 所謂的無符號數取值范圍,其實就是有符號數取值范圍大于等于零的部分.
2:數據精度說明
-
***MySQL允許使用 非標準語法 (其他數據庫未必支持,因此如果涉及到數據遷移,則最好不要這么
用)***: FLOAT(M,D) 或 DOUBLE(M,D) 。這里,M稱為 精度 ,D稱為 標度 。(M,D)中 M=整數位+小數
位,D=小數位。 D<=M<=255,0<=D<=30。
例如,定義為FLOAT(5,2)的一個列可以顯示為-999.99-999.99。如果超過這個范圍會報錯(不影響正負數值表示)。 -
FLOAT和DOUBLE類型在不指定(M,D)時,默認會按照實際的精度(由實際的硬件和操作系統決定)
來顯示。 -
不管是否顯式設置了精度(M,D),這里MySQL的處理方案如下:
-
如果存儲時,整數部分超出了范圍,MySQL就會報錯,不允許存這樣的值。
-
如果存儲時,小數點部分若超出范圍,就分以下情況:
-
若四舍五入后,整數部分沒有超出范圍,則只警告,但能成功操作并四舍五入刪除多余
的小數位后保存。例如在FLOAT(5,2)列內插入999.009,近似結果是999.01。 -
若四舍五入后,整數部分超出范圍,則MySQL報錯,并拒絕處理。如FLOAT(5,2)列內插入
999.995和-999.995都會報錯。
-
-
-
從MySQL 8.0.17開始,FLOAT(M,D) 和DOUBLE(M,D)用法在官方文檔中已經明確不推薦使用,將來可
能被移除。另外,關于浮點型FLOAT和DOUBLE的UNSIGNED也不推薦使用了,將來也可能被移除。
舉例:
CREATE TABLE test_double1( f1 FLOAT, f2 FLOAT(5,2), f3 DOUBLE, f4 DOUBLE(5,2) ); DESC test_double1; INSERT INTO test_double1(f3, f4) VALUE(123.456,123.456); #該行存在四舍五入,f4變成123.46 INSERT INTO test_double1(f3, f4) VALUE(123.45,999.95); #Out of range value for column 'f4' at row 13:精度誤差說明
浮點數類型有個缺陷,就是不精準。
例:
我們設計一個表,有f1這個字段,插入值分別為0.47,0.44,0.19,我們期待的運行結果是:0.47 + 0.44 + 0.19 = 1.1。而使用sum之后查詢:
查詢結果是 1.0999999999999999。雖然誤差很小,但確實有誤差。 如果把數據類型
改成 FLOAT,然后運行求和查詢,得到的是, 1.0999999940395355。顯然,誤差更大了。
那么,為什么會存在這樣的誤差呢?問題還是出在 MySQL 對浮點類型數據的存儲方式上。
MySQL 用 4 個字節存儲 FLOAT 類型數據,用 8 個字節來存儲 DOUBLE 類型數據。無論哪個,都是采用二進制的方式來進行存儲的。比如 9.625,用二進制來表達,就是 1001.101,或者表達成 1.001101×2^3。如果尾數不是 0或5(比如9.624),你就無法用一個二進制數來精確表達。進而,就只好在取值允許的范圍內進行四舍五入。
注意:在編程中,如果用到浮點數,要特別注意誤差問題,因為浮點數是不準確的,所以我們要避免使用“=”來判斷兩個數是否相等。同時,在一些對精確度要求較高的項目中,千萬不要使用浮點數,不然會導致結果錯誤,甚至是造成不可挽回的損失。
總結
- 上一篇: LM317电源模块
- 下一篇: linux cmake编译源码,linu