使用JPA
映射一個float
類型到數據庫:html
而後存儲129364.57
,發現存儲的結果是129365
。mysql
從上週就開始研究這個問題,查閱了各類資料,網上許多人都說是由於MySQL
默認是保留六位有效數字,本身測試了一下也確實是這樣。可是查詢MYSQL
官方文檔,並無找到依據。sql
MySQL
官方文檔:Float - MySQL數據庫
若是你看到了這篇文章,歡迎評論發表意見,讓咱們互相學習、進步。segmentfault
寫的很是好的一篇文章,MySQL
存儲的各類嘗試:MySQL數字類型int與tinyint、float與decimal如何選擇性能
用JPA
映射的Float
默認的長度與小數點都是0
。學習
這是測試的結果:
float
默認能精確到6位有效數字!
這是MySQL
官方文檔對float
和double
的描述:測試
官方文檔並無說
MySQL
是如何存儲浮點數的,因此若是沒有去讀過其源代碼,全部的博客都只是猜測。
目前大多數人認爲MySQL
內部是採用IEEE 754
進行存儲的,IEEE 754 - 維基百科。優化
IEEE二進制浮點數算術標準(IEEE 754)是20世紀80年代以來最普遍使用的浮點數運算標準,爲許多CPU與浮點運算器所採用。
以32
位的單精度浮點數爲例:spa
與平常所說的科學計數法相似。
由於底數是有效數字,因此第一位確定是1
,因此這個1
不進行存儲,因此雖然是23
位的底數,可是實際的底數位數實際上是24
位,含有一個隱含的1
。
雙精度與此相似,一個符號位,指數位爲11
,尾數爲52
位,合計64
位。
假設是用MySQL
是用IEEE 754
標準存儲的浮點數。
用單精度存儲129364.57
,其二進制爲11111100101010100.1001000111101011100001010001111011
。
正數:符號位爲0
。
指數位爲:00010000
(十進制中的16
)。
去掉第一個1
,保留23
位,底數爲:11111001010101001001000
。
因此最後的結果是11111100101010100.1001000
,轉換爲十進制爲:129364.5625
。
可是實際的MySQL
存儲後的結果爲129365
,因此猜測要麼MySQL
就是否是按IEEE 754
存儲的,要麼就是按這個存儲的可是內部爲了數據庫的性能等或其餘的優化對數據進行了處理。
這裏我這裏更傾向於第二種,畢竟IEEE 754
是一種國際標準,沒有理由不遵照。