解释为什么(7.839)=.2不返回where子句的结果。

问题描述 投票:0回答:1

所以我知道为什么(7.839)=.2在SQL中的where子句中不会返回结果,而ROUND((7.839),1)=.2会返回结果,但我不知道如何向我的同事解释清楚,我想给他们提供一些可以阅读的东西,而不是我告诉他们那不会作为where子句的一部分。

谢谢你。

贾拉勒

sql vertica
1个回答
3
投票

这是由于 浮点算术. 如果你不 "明白 "的话,这可能很难解释。

我从哪里开始呢? 整数很容易用CPU能理解的位数来表示,所以,00000101被解释为5--而且正是5--因为它是2^2+2^0。 所以,00000101被解释为5--而且正是5--因为它是2^2+2^0。

然而,这对数字的小数部分并不适用。为了解决这个问题,计算机科学家发明了两种形式的数字。 一种是我个人认为的BCD(二进制编码十进制),但数据库称之为 decimalnumeric. 每个数字都是一个数字。 一个数字只需要4位,所以这看起来像。

0011    0001    1111     0000     1001
   3       1       .        0        9

这正好代表31. 09. 只要继续增加位数。 注意:这是概念性的。 确切的实现可能会有所不同。

第二种方法是指数记数法。 即:xxx * 2^ yyy,其中xxx和yy是整数。 例如,0.25就是1*2^(-2)。 "1 "和"-2 "可以准确地表示。

这对以下情况很有效 近似值 的数字。 问题是,0.25可以准确地表示。 但0.24和0.26不能。 它们最终会涉及一些复杂的数字。 0.2也是如此--这就是你要表示的数字。

发生的情况是,你写0.2,它被表示为0.00110011001(比如)。 但是当你进行计算时,它最终变成了0.00110011000。 哦,是这样的。 最后那个位子变了,所以其实更像0.19997(嗯,实际操作中多了点'9')。 数值并不完全相等。

寓意是:不要在浮点数字上使用平等。 这些数字可能看起来是一样的,但在一些二进制的小数位上却不同。


0
投票

我在我的 "Vertica Analytic Database v9.3.1-0 "上试了一下,作为我的 SELECT VERSION() 回报:

select (7.8/39)=.2 as is_it_true

returns:

is_it_true

true

为了确保并避免任何浮点问题,请尝试将两个等价操作数转换为相同的类型。

select (7.8/39)::NUMERIC(5,1) = .2::NUMERIC(5,1)

© www.soinside.com 2019 - 2024. All rights reserved.