2016-06-07 23 views
0

第一:我是一個MySql新手,它看起來像我在這裏失去了重要的東西。MySQL(MariaDB)浮點可視化:爲什麼值被舍入到數百或數千?

在MySQL數據庫中,我的float值範圍從單位到數十億。 我花了幾天試圖理解爲什麼他們都表現出與設置爲0不太顯著的人不超過6顯著數字:

即:

select `field` from `table`; 
(instead of X -> i get Y) 
    1 -> 1 
    12 -> 12 
    123 -> 123 
    1234 -> 1234 
    12345 -> 12345 
    123456 -> 123456 
    1234567 -> 1234570 
    12345678 -> 12345700 
    123456789 -> 123457000 

只能用一個「絕招」我在什麼地方找到我可以讀取實際值:

select `field`+0.0 from `table`; 

我的問題:這個(imho)奇怪行爲背後的基本原理是什麼?它在文檔中描述的地方在哪裏? 我發現完全不直觀,我沒有看到真正的價值(當然近似根據IEEE規範)與正常的選擇*,但我需要的伎倆......我在這裏錯過了什麼?

+0

請問您可以展示[mcve],例如從表創建到數據選擇複製/粘貼一個完整的MySQL會話?如果在那裏的輸出格式允許演示這個問題,甚至可能用[sqlfiddle](http://sqlfiddle.com)來演示? – eggyal

+0

@eggyal,這裏是最簡單的例子:http://sqlfiddle.com/#!9/352bf/1/0 從ID6開始,結果取整爲6個有意義的密碼。問題是,默認情況下,「select *」我通常會看到四捨五入的值,而不是真正的值... 我假設有一個命令來設置數據庫使用「真實」的值,但不能理解這個奇怪的開發者選擇的原因是什麼? –

+0

剛剛嘗試過SQLfiddle:使用_double_而不是_float_完美工作。 –

回答

2
  • FLOAT具有24位,或log10(224)(超過7)數字,意義:12345678.910存儲在FLOAT作爲1011110001100001010011112(這是1234567910)。當顯示爲十進制時,客戶端知道對於某些,從第8位開始的所有內容都是肯定是false precision(因爲FLOAT只能存儲7位精度的十進制數字)。因此它丟棄剩餘部分,留下12345680

  • DOUBLE具有53個比特,或log10(253)(幾乎16)位數,意義:12345678.910存儲在DOUBLE101111000110000101001110.111001100110011001100110011012作爲(這是12345678.9000000003710)。當顯示爲十進制時,客戶端知道對於某些,從第16位開始的所有內容都是肯定是false precision(因爲DOUBLE只能存儲15位十進制精度)。因此它丟棄剩下的部分,留下12345678.9000000

當添加+0.0,MySQL的第一注塑FLOAT高達DOUBLE

+0

謝謝@eggyal。當我收到你的回答時,我正在寫同樣的東西。問題在於我忽略了IEEE754的表示。 即使用+0.0強制執行雙重轉換,我也讀取了額外的密碼,但是因爲它們已被保存爲浮點數,當然不精確。 謝謝。 –

+0

@AlexPoca:其實,有趣的是,你似乎(不必要地)在路上丟失了一個十進制數字。雖然FLOAT的尾數只佔用了23位的存儲空間,但最重要的位並沒有明確存儲,因此實際上我的答案中有24位(或7位數)意義。如果只有23位的重要性,將沒有足夠的信息來保證第七位的正確性 - 因此人們也不得不放棄這一點。看來,十進制轉換錯誤地假設23而不是24位:一個錯誤。 – eggyal

+0

@AlexPoca:[I stand corrected](http://stackoverflow.com/q/29510356)。 – eggyal

0

根據IEEE754,我忽略了float和double的表示,這就是解決這個謎題的方法。 FLOAT(32位)具有23位的尾數(8百萬個可能的值=> 6個有意義的數字),其餘9位用於符號和指數。 DOUBLE(64位)具有52位的尾數(一些4.5e15可能的值=> 14有意義的數字)。

這意味着Mysql不能顯示不存在的內容(在我的情況下FLOAT大數字)並填充「隨機」無效數字零。