Redshift ROUND 函数在某些情况下不舍入?

Posted

技术标签:

【中文标题】Redshift ROUND 函数在某些情况下不舍入?【英文标题】:Redshift ROUND function doesn't round in some cases? 【发布时间】:2021-01-28 18:54:51 【问题描述】:

我可以找到一种解决方法,但这确实很烦人,而且我肯定会遗漏一些东西。 Redshift 的 ROUND 函数不会四舍五入到指定的小数位数。

例如,

select round(cast(176 as float)/cast(492 as float),4) as result;

上面的 select 语句将返回 0.35769999999999996。

但是,这个声明:

select round(cast(229 as float)/cast(491 as float),4) as result;

... 将返回 0.4664。

为什么?我可以解决这个问题,但似乎它应该可以工作并且只返回四位小数。

【问题讨论】:

229/491 = 0.46639511201。 . . Redshift 中的答案在我看来是正确的。 【参考方案1】:

如果您的问题是所有这些 9999,那么问题是浮点表示。转换为小数得到定点精度:

select round(cast(176 as float)/cast(492 as float), 4)::decimal)10, 4) as result;

【讨论】:

确实有效。我想我认为这是 ROUND 的替代品。您的解决方案不需要 ROUND。我只是假设 ROUND 有一个错误,但我觉得很奇怪。感谢您的建议。 @MarkEvans 。 . . ROUND() 很好。问题在于浮点表示,这很棘手——但很少需要。 我真的很好奇 ROUND() 怎么样?不是讽刺。它不应该返回一个四舍五入到指定小数位的数字吗?甚至一个类型的浮动?许多值确实返回到四舍五入到 4 位,但分散在那些不是。这是 ROUND 的预期行为?出于我的目的, ROUND 对于文档描述的内容没有用处。我正在转换为十进制类型。 只需从 ROUND 上的 AWS 页面添加此内容:“支持 INTEGER、DECIMAL 和 FLOAT 数据类型。”【参考方案2】:

详细阐述 Gordon 的回答 -

所以你写了一些简单得离谱的代码,比如说:

0.1 + 0.2

得到了一个非常出乎意料的结果:

0.30000000000000004

因为在内部,计算机使用的格式(二进制浮点)根本无法准确表示像 0.1、0.2 或 0.3 这样的数字。

在编译或解释代码时,您的“0.1”已经四舍五入到该格式中最接近的数字,这会在计算发生之前导致一个小的舍入误差。

我可以做些什么来避免这个问题?

这取决于你在做什么样的计算。

如果您确实需要将结果精确地相加,尤其是在使用金钱时:使用 decimal 数据类型。 如果您只是不想看到所有这些额外的小数位:只需在显示结果时将结果格式化为固定的小数位数。

无耻地盗取自:Floating Point

【讨论】:

以上是关于Redshift ROUND 函数在某些情况下不舍入?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 MISRA-C 在某些情况下不允许隐式扩展类型?

为啥回顾中的有限重复在某些情况下不起作用?

在某些情况下不调用 UIGestureRecognizerState.Ended

UIImageView autoresizingmask 在某些情况下不起作用

前缀计算器——在某些情况下不起作用——C++

多个 OpenGL 纹理在某些情况下不起作用?