2016-08-19 23 views
-1

這與answer有些相關。我明白浮球不是建議高精度的。但我不完全得到什麼的事情與FLOAT通過下面的結果去後,Mysql float怎麼回事?

觀察1

通過以下2個查詢返回的值返回不同的結果,

SELECT MY_FLOAT_COL FROM MY_TABLE; 

SELECT MY_FLOAT_COL*1 FROM MY_TABLE; 

可能的解釋是上述鏈接中的參考,它表示浮點數是近似值,問題是數據類型。

觀察2

的查詢

SELECT MY_FLOAT_COL*1 FROM MY_TABLE; 

SELECT MY_FLOAT_COL FROM MY_TABLE; 

返回相同的結果,當我執行使用松鼠SQL(渣),但是當通過海蒂SQL(Object Pascal中)和Python執行返回不同的結果腳本。因此,這導致了問題出現在客戶端的結論。

Mysql的Float數據類型到底發生了什麼。我試圖理解上述2個觀察。

編輯:我更關心我的觀察2。我能夠從我的觀察1中得出一些意義,但後者目前是神祕的。

+0

不同的SQL引擎不同的方式實現一些事情。你的問題是什麼? –

+0

所有的觀察結果都在同一臺服務器上。我的問題是,正如前面提到的那樣試圖使觀察有意義... – Kannan

回答

2

當您乘以1時,結果將轉換爲DOUBLE。這具有更高的精度,因此您可以在小數近似中看到誤差。您可以通過將FLOAT列分配給DOUBLE列來查看相同的結果。

CREATE TABLE `my_table` (
    `my_float_col` float, 
    `my_double_col` double 
); 
INSERT INTO my_table (my_float_col) values (1.2355); 
UPDATE my_table SET my_double_col = my_float_col; 
SELECT my_float_col, my_double_col, my_float_col * 1 FROM my_table; 
+--------------+--------------------+--------------------+ 
| my_float_col | my_double_col  | my_float_col * 1 | 
+--------------+--------------------+--------------------+ 
|  1.2355 | 1.2354999780654907 | 1.2354999780654907 | 
+--------------+--------------------+--------------------+ 

我真的不知道爲什麼它從乘法返回DOUBLE,因爲documentation說:

如果任何一個+-/*%是一個操作數實數或字符串值,結果的精度是具有最高精度的操作數的精度。

但很明顯發生了什麼事情。

+0

Barmar,我認爲案件已經用我發掘的神祕手冊頁解決了。 – Drew

+0

很高興我能夠把你放在正確的軌道上。 – Barmar

+0

總是做Barmar:p – Drew

2

正在發生的事情可以有輕微的修改Barmar的回答,我有如下解釋:

drop table if exists my_table2; 
CREATE TABLE `my_table2` (
    `my_float_col` float(18,16), -- FLOAT(M,D) 
    `my_double_col` double(18,16) 
); 
INSERT INTO my_table2 (my_float_col) values (1.2355); -- 1.2354999780654907 
UPDATE my_table2 SET my_double_col = my_float_col; 
SELECT my_float_col, my_double_col, my_float_col * 1 FROM my_table2; 
+--------------------+--------------------+--------------------+ 
| my_float_col  | my_double_col  | my_float_col * 1 | 
+--------------------+--------------------+--------------------+ 
| 1.2354999780654907 | 1.2354999780654907 | 1.2354999780654907 | 
+--------------------+--------------------+--------------------+ 

爲Barmar浮(列1)是一個C float數據類型,就像我的是。但是因爲他沒有指定精度(M,D),所以C中的內部實現仍然將它定位爲C float,我們具有相同的值,但Barmar's中卻丟失了這一事實。只是他的顯示寬度將它放大了。請注意我在下面創建的功能,可以顯示。

並查看這個幽默的MySQL手冊頁面,標題爲FLOAT and DOUBLE Data Type Representation,我認爲任何人都可以深入瞭解它。因爲無論如何,我們仍然是數學頭的:

讓我們來看看MySQL參考手冊 離開的故事。

下面的討論集中在沒有給出寬度和小數顯示 的情況。這意味着FLOAT存儲爲 ,無論C型float是什麼,REAL或DOUBLE [PRECISION]都存儲爲 ,無論C型爲double。字段長度由 MySQL代碼選擇。

所以儘管Barmar輸出的第一列,這是從來沒有在那裏爲1.2355,以及上述手冊頁和巧妙幽默地描述了頭撞的人都經歷了。

助手FCN如果感興趣:

DROP FUNCTION IF EXISTS returnFloatFromDec; 
DELIMITER $$ 
CREATE FUNCTION returnFloatFromDec(n DECIMAL(18,16)) 
returns FLOAT 
BEGIN 
    DECLARE theRet FLOAT; 
    SET theRet=n; -- note that CAST can't take a FLOAT 
    return(theRet); 
END;$$ 
DELIMITER ; 
+0

感謝您的詳細信息。但仍然無法推理我的觀察結果2. – Kannan

+0

很明顯,數據存儲爲C浮點數並且是顯示問題。上面引用的鏈接拼出來 – Drew