2016-08-19 73 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