gpt4 book ai didi

mysql - MySQL 中的 float

转载 作者:行者123 更新时间:2023-11-29 17:16:06 25 4
gpt4 key购买 nike

所以我有 2 个不同的查询,并且都有一个 float 作为标准。一个在应该返回的时候不返回任何内容,另一个返回正确的值。

SELECT *
FROM filters
WHERE hole = 0.7

仅返回

SELECT *
FROM filters
WHERE ek = 66

返回

'143987', '1', '14', '45', '0.7', '66', '0'

如预期的 0.7。

但是以下

SELECT *
FROM needles
WHERE needle_dia = 2.5

返回

'2', 'H1004', '300', '2.5', '2040173', '2040177'

我已经检查过它们都具有完全相同的类型 - 无符号 FLOAT,非非空,默认表达式 NULL。

这有什么原因吗?

我知道可以使用 DECIMAL 代替 FLOAT,但我宁愿避免它。

最佳答案

由于浮点编号系统是不连续的、不精确的,并且无法准确表示某些值 ( for example, 0.7 ),因此永远不应该比较浮点值是否相等。您应该始终使用 BETWEEN 表达式,并用合适的错误值将其括起来:

WITH cteEpsilon AS (SELECT 0.0001 AS EPSILON FROM DUAL)
SELECT *
FROM filters f
CROSS JOIN cteEpsilon e
WHERE 0.7 BETWEEN f.hole - e.EPSILON
AND f.hole + e.EPSILON

正如您在问题中所指出的,更好的选择是使用精确的数字类型,例如 DECIMAL。

<小时/>

“什么?!?”,你说? “证明它!!!”

好吧,很公平。让我们看一个简单的小程序,声明几个浮点常量,然后比较它们:

#include <stdio.h>

float f = 0.7;
double d = 0.7;

int main()
{
if(f == d)
printf("Equal\n");
else
printf("Not equal\n");

printf("f = %60.50f\nd = %60.50f\n", f, d);
}

现在 - 无需运行它或查看隐藏的盒子 - 预测输出并将您的预测写在一张纸上。

完成了吗?好的。编译并运行时,上面会产生:

不等于
f = 0.69999998807907104492187500000000000000000000000000
d = 0.69999999999999995559107901499373838300000000000000

没错 - 这里我们有两个常量,都指定为 0.7,并且它们彼此不相等。

这里的问题是,无论我们选择什么精度,0.7 都不能完全表示为 IEEE-754 浮点值。这里的常量具有不同的精度 - 一个是 4 字节浮点值(类型 float ),第二个是“ double ”浮点值(类型 double ),并且由于每个值的精度不同,结果值也不同。 (现在房间后面的聪明人说,“是的,但如果你使用整数,他们总是会正确比较”。不,聪明人 - 将常量更改为 1234567890 并看看会发生什么。)你的编译器会这样做最好能产生最接近 0.7 的近似值,但该近似值仍然不等于 0.7,并且与用于存储该值的变量的精度不同。这并不意味着 IEEE-754 坏了,你的计算机坏了,或者宇宙有一扇通往糖果乐园的 secret 活门。 (糟糕!:-) 这意味着 float 比乍一看要复杂得多。我建议阅读以下内容以开始了解发生这种情况的原因:

What Every Computer Scientist Should Know About Floating-Point Arithmetic

The Floating Point Gui.de

Why Are Floating Point Numbers Inaccurate

Floating-Point Numbers: Issues and Limitations

Why Floating-Point Numbers May Lose Precision

关于mysql - MySQL 中的 float ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51612028/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com