mysql将float转换为double

时间:2018-09-29 18:52:46

标签: mysql mariadb rounding

我正在将数据从一个表插入到MariaDB数据库的另一个表中,第一个表中的列为FLOAT,第二个表中的列为DOUBLE。数据可以具有任意大小,精度和小数位的值。

这是我进行直接复制时这些值会发生什么:

INSERT INTO data2 (value) SELECT value FROM data1

为这些值赋予随机的额外有效数字:

FLOAT in data1           DOUBLE in data2
-0.000000000000454747    -0.0000000000004547473508864641
-122.319                 -122.31932830810547
14864199700              14864220160

CAST(value AS DECIMAL(65,30))生成与上面col 2完全相同的值,除了我看到尾随零。

但是我刚刚做

UPDATE data2 SET value = 14867199700 WHERE id = 133025046;

接受DOUBLE值。

是否必须将所有值导出到SQL脚本并重新导入它们?有没有更好的方法?

尽管花了很多时间尝试解决这个问题,但尽管性质有限,但我离解决方案还差得很远。我可以看到这是困扰所有技术的问题,而不仅仅是MariaDB或数据库,因此我可能只是在某个地方错过了答案。 Stackoverflow拼命尝试使用我以前从未见过的新建议功能来指导解决方案,但不幸的是,它们与其他建议的答案一样没有帮助。

1 个答案:

答案 0 :(得分:1)

您的测试用例有缺陷。您正在输入小数位数,而不是测试{em>只是 FLOATDOUBLE的传输。

UPDATE tbl SET double_col = float_col将始终复制完全相同的值。这是因为DOUBLE表示形式是FLOAT表示形式的超集(53 VS 24位精度;等等)。

带小数位的字母:UPDATE tbl SET double_col = 123.456将使数字不正确,因为从十进制四舍五入到DOUBLEfloat_col的同上。而且,错误的结果会有所不同!

孔号文字:UPDATE tbl SET double_col = 14867199700将被精确存储。但是,如果将相同的文字放入FLOAT中,则会将其舍入为24位,因此无法准确存储。对于FLOAT,您失去了 about 7个有效数字的准确性;对于DOUBLE,您失去了 about 16个有效数字。此示例中的文字有9个有效数字(忽略尾随零)。

那只是噩梦中的一部分。

必须FLOATDOUBLE视为近似。你永远不应该为了平等而比较。您不知道值的最后一位可能是什么问题。

此外,您不应尝试猜测MySQL何时将在DECIMAL而非DOUBLE中执行表达式。

并且要记住,由于四舍五入到一些位数或小数,除法通常是不精确的。

14864199700的“尾数”是

    1.10111010111111001101100 (binary of FLOAT : 24 bits including 'hidden' leading bit)
    1.1011101011111100110110000000101000000000000000000000 (binary of DOUBLE)
                                  ^ ^  (lost in FLOAT)

每一个都乘以2的相同乘方。DOUBLE精确地为14864199700。FLOAT丢失了所指向的位。

您可以在https://gregstoll.dyndns.org/~gregstoll/floattohex/上玩这样的游戏

信不信由你,事情以前一直很糟。由于四舍五入的错误,将向人们收取0.00美元的费用。或应为1 + 1的结果显示为1.99999999。