【问题标题】:Explaining why (7.8/39) = .2 does not return results in a where clause解释为什么 (7.8/39) = .2 不返回 where 子句的结果
【发布时间】:2020-04-24 23:40:45
【问题描述】:

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

谢谢你,

贾拉尔

【问题讨论】:

  • select 7.8/32 返回什么?
  • 视觉上返回 0.2,但为了让他的代码正常工作,我让他使用 WHERE ROUND((X/Y),1)=.2 X/Y=.2 如果用于where 子句即使在 select 语句中都返回 .2。
  • 对不起...我把 32 代替了 39,编辑了主帖。漫长的一周让我的大脑筋疲力尽。

标签: sql vertica


【解决方案1】:

这是由于floating point arithmetic。如果您不只是“理解”它,这可能很难解释。

我从哪里开始?整数很容易用 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')。这些值并不完全相等。

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

【讨论】:

    【解决方案2】:

    我在我的“Vertica Analytic Database v9.3.1-0”上进行了尝试,因为我的SELECT VERSION() 返回:

    select (7.8/39)=.2 as is_it_true

    返回:

    is_it_true

    true

    为确保避免任何浮点问题,请尝试将两个相等操作数强制转换为同一类型:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-23
      • 2018-07-21
      • 2023-03-26
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多