MYSQL 如何在内部表示浮点数?



我遇到了这个问题,其中在浮点列中插入像 1234567这样的数字会导致四舍五入的值为 1234570

我知道这是由于浮点精度,但让我感到困惑的是,如果我使用上面的浮点列进行一些计算,那么它使用实际值 (1234567(。

如果我只在列上使用 Select 语句,它会给出舍入值, 但是如果我将其转换为十进制或对其执行一些计算,它会使用实际值进行

。所以我的问题是是什么让MySQL像这样?

编辑:

例如:

select cast(1234567 as float), cast(1234567 as float) + 1

返回:

1234570 1234568

这是一个数据库<>小提琴。

您关于浮点精度的问题并不仅限于MySQL,对于任何数据库或编程语言来说,它都是一个有效且类似的问题。 底线是,由于浮点数在内部表示的方式,它们并不精确,用浮点数完成的算术也不精确。

如果您需要精确的精度,那么您应该使用精确的类型,例如NUMERICDECIMAL.

根据配方,我们可以在您的小提琴中获取数据类型,它显示(我在 8.0.20/FreeBSD/i386 上运行它(:

netch@localhost [test]> create temporary table t1 select cast(1234567 as float), cast(1234567 as float) + 1, cast(12345678 as float) + 1;
netch@localhost [test]> show create table t1;
+-------+---------------------------------------------------------------------->
| Table | Create Table                                                         >
+-------+---------------------------------------------------------------------->
| t1    | CREATE TEMPORARY TABLE `t1` (
`cast(1234567 as float)` float NOT NULL DEFAULT '0',
`cast(1234567 as float) + 1` double NOT NULL DEFAULT '0',
`cast(12345678 as float) + 1` double NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+-------+---------------------------------------------------------------------->
1 row in set (0.00 sec)

因此,其规则类型在一种情况下会导致float,在另一种情况下会导致double。 1234567 完全以浮点数表示,但是,请参阅下面的截断。

实验表明,CAST(AS float(在标记为浮点数时提供浮点数64浮点值(C中double(,但只有在最终放入存储的数据库单元时,实际值才会切入浮点数32。但是,对于"+",浮点数在添加之前转换为双精度,这在另外运算符类型结果中表示,因此,自动创建会公开double。但是,如果声明的类型保持浮点数,MySQL 不仅将其截断为 float32 - 它还将其四舍五入为 6 个默认可打印的数字:(

我在MySQL文档中找不到这些细节(要么省略了,要么我对这种文档风格的挖掘技能很差(,但是这种方法(除了剪切到文本形式(至少符合应用于C/C++的常识性方式。它们允许在放置到输出变量之前具有更广泛的浮点值中间表示形式。

因此CAST()8.0 是新的(5.7 不支持floatdouble在强制转换中(,这可能是过于原始的实现。请随时向MySQL开发人员投诉,以推进到适当的方式。

最新更新