解释为什么 (7.8/39) = .2 不会 return 导致 where 子句

Explaining why (7.8/39) = .2 does not return results in a where clause

所以我知道为什么 (7.8/39)=.2 不会 return 导致 SQL 中的 where 子句,而 ROUND((7.8/39),1)=.2 会return 结果,但我不知道如何向与我一起工作的人清楚地解释它,我想为他们提供一些阅读的东西,然后我告诉他们这不会作为他们 where 子句的一部分。

谢谢你,

贾拉尔

这是由于 floating point arithmetic。这可能很难解释,如果你不只是 "get" 它。

我从哪里开始?整数很容易用 CPU 理解的位来表示。因此,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 和 yyy 为整数。例如,0.25 是 1 * 2^(-2)。 “1”和“-2”可以准确表示。

这适用于 近似值 的数字。问题是 0.25 可以精确表示。但是 0.24 和 0.26 不能。他们最终涉及到一些复杂的数字。 0.2 也是如此——这是您要表示的数字。

发生的事情是你写 0.2,它表示为 0.00110011001(比方说)。但是当你进行计算时,它最终是 0.00110011000。哦。最后一点发生了变化,所以它实际上更像是 0.19997(好吧,在实践中多了一点 '9')。这些值并不完全相等。

寓意:不要对浮点数使用相等。这些数字可能看起来相同,但在一些微不足道的二进制小数位上有所不同。

我试过 "Vertica Analytic Database v9.3.1-0" 作为 SELECT VERSION() returns:

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)