我遇到了这个问题,在float列中插入一个像1234567这样的数字会导致1234570的舍入值。
我知道这是由于浮点精度造成的,但让我困惑的是,如果我使用上面的浮点列进行一些计算,那么它将使用实际值(1234567)。
如果我只是在列上使用select语句,它会给出舍入值,但是如果我将它转换为decimal或对它执行一些计算,它会使用实际值。
所以我的问题是,是什么让mysql这样做的?
编辑:
例如:
select cast(1234567 as float), cast(1234567 as float) + 1
退货:
1234570 1234568
这是一把小提琴。
2条答案
按热度按时间k4emjkb11#
关于浮点精度的问题并不仅仅局限于mysql,它对于任何数据库或编程语言都是一个有效且类似的问题。归根结底,由于浮点数在内部的表示方式,它们并不精确,用浮点数进行的运算也不精确。
如果您需要精确的精度,那么应该使用精确的类型,例如
NUMERIC
或者DECIMAL
.gev0vcfq2#
根据配方,我们可以在您的fiddle中获得数据类型,它显示(我在8.0.20/freebsd/i386中运行):
所以它的规则类型会导致
float
在一个案例中double
在另一种情况下。1234567用float表示,但是,请参见下面的截断。实验表明,cast(as float)提供float64浮点值(
double
在c)标记为float,但实际值仅在最后放入存储的db单元时切为float32。但是,对于'+',float在加法之前被转换为double,这在加法运算符类型result中表示,因此,自动创建将公开double
. 但如果声明的类型仍然是float,mysql不仅会将其截断为float32,还会将其舍入为6个默认的可打印数字:(我在mysql文档中找不到这些细节(要么省略了,要么我对这种文档样式的挖掘技巧不好),但这种方法(除了剪切成文本形式)至少符合应用于c/c++的常识方式。它们允许在放置到输出变量之前有更广泛的浮动值中间表示。
像这样的
CAST()
是8.0的新功能(5.7不支持float
以及double
在cast中),这可能是太原始的实现。请随时向mysql开发人员投诉,以提高到一个适当的模式。