You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL 5.7.14中FLOAT与DOUBLE类型WHERE条件比较结果差异

浮点数精度差异导致的查询结果不一致问题解析

这是一个典型的二进制浮点数精度特性引发的问题,我来帮你拆解背后的原因和可行的解决办法:

核心原因

1. 二进制浮点数的本质局限

FLOAT和DOUBLE都属于二进制浮点类型,它们无法精确存储所有十进制小数(比如0.1、0.6这类数值)。因为这些十进制数转换为二进制时是无限循环的,数据库只能存储它们的近似值,而非精确值。

2. FLOAT与DOUBLE的精度差异

  • FLOAT是单精度浮点数(32位存储),有效精度约为6-7位十进制数;
  • DOUBLE是双精度浮点数(64位存储),有效精度约为15-17位十进制数。

当你插入78.60时,虽然字段定义了(6,2)(强制插入时四舍五入到2位小数),但底层存储的仍是近似值:FLOAT的近似误差更大,而DOUBLE的误差极小,肉眼几乎不可见。

3. 比较时的类型转换问题

你设置的变量@priceValue=78.6默认是DOUBLE类型。当与FLOAT字段比较时,MySQL会把FLOAT的近似值转换为DOUBLE,但这个转换后的数值和原始的78.6(DOUBLE类型)存在微小差异,导致精确等于(=)的判断不成立;而DOUBLE字段存储的近似值与78.6(DOUBLE类型)的差异足够小,被判定为相等。

你可以执行以下查询验证实际存储的近似值:

SELECT 
  price_val_float, 
  CAST(price_val_float AS DECIMAL(10,8)) AS float_actual_value,
  price_val_double, 
  CAST(price_val_double AS DECIMAL(10,8)) AS double_actual_value
FROM test;

你会看到price_val_float对应的float_actual_value可能是78.59999847这类近似值,而price_val_double的double_actual_value会更接近78.60000000。

解决办法

1. 改用定点数类型(推荐)

如果是存储金额、价格这类需要精确计算的场景,优先使用DECIMAL类型(定点数),它可以精确存储十进制小数,完全避免浮点数的精度问题。

修改表结构的语句:

ALTER TABLE test 
  MODIFY price_val_float DECIMAL(6,2),
  MODIFY price_val_double DECIMAL(6,2);

2. 范围比较替代精确等于

如果必须使用浮点数,不要用=进行精确比较,而是判断数值是否在一个极小的误差范围内(比如±0.001,根据你的精度需求调整):

SELECT * FROM test WHERE ABS(price_val_float - @priceValue) < 0.001;

3. 统一比较时的数据类型

将变量转换为与字段相同的类型后再比较,不过这种方法仍依赖浮点数的近似特性,可靠性不如前两种:

SELECT * FROM test WHERE price_val_float = CAST(@priceValue AS FLOAT);

内容的提问来源于stack exchange,提问作者Alpesh Jikadra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:56:21