代码之家  ›  专栏  ›  技术社区  ›  Adam

mysql将float转换为double时有效数字的处理问题

  •  0
  • Adam  · 技术社区  · 6 年前

    我将数据从一个表插入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))

    但当我这么做的时候

    UPDATE data2 SET value = 14867199700 WHERE id = 133025046;
    

    双倍 值被接受。

    尽管我花了好几个小时尝试解决这个问题,但我还没有找到解决方案,尽管它的性质有限。我可以看出这个问题困扰着所有的技术,不仅仅是MariaDB或数据库,所以我可能只是在某个地方错过了答案。Stackoverflow正在拼命地尝试用我以前没有见过的新建议功能来指导解决方案,但不幸的是,它们没有帮助,就像其他建议的答案一样。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Rick James diyism    6 年前

    你的测试用例有缺陷。您正在输入十进制数字,而不是测试 只是 FLOAT DOUBLE .

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

    文字,带小数位: UPDATE tbl SET double_col = 123.456 由于从小数点到小数点的四舍五入,数字会被弄乱 双倍 . 同上 float_col

    孔号文字: UPDATE tbl SET double_col = 14867199700 浮动 ,它将四舍五入到24位,因此无法准确存储。你失去了精确性 关于 7位有效数字 浮动 16年 . 本例中的文字有9个有效数字(在忽略后面的零之后)。

    你呢 考虑 浮动 双倍 成为 . 你不应该为了平等而比较;你不知道是什么把最后一点的值弄乱了。

    另外,您不应该试图猜测MySQL何时在中执行表达式 DECIMAL 双倍 .

    而且,请记住,除法通常是不精确的,因为四舍五入到一些位数或小数。

    14864199700的“尾数”是

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

    双倍 精确到14864199700。这个 浮动 丢失了指向的位。

    你可以和这样的人一起玩 https://gregstoll.dyndns.org/~gregstoll/floattohex/