为什么 Oracle 不使用银行家规则(四舍五入法)?
5 回答
精确的十进制算术是一门庞大而复杂的学科。
如果您想阅读有关该主题的 ahem Oracle,请使用 Google 'mike colishaw decimal rounding'。
基本上有许多可能的舍入方案:-
四舍五入——包括 C 在内的大多数语言中的默认值,因为 Oracle 是用 C 编写的,这可能就是他们这样做的原因。
汇总所有内容 - 很少见,但由于市场和税收规则模糊不清,偶尔需要实施。
基本半舍入 - 任何高于 0.5 的内容都会向上舍入,其他所有内容都会向下舍入。
慷慨的半舍入 - 任何低于 0.5 的东西都会向下舍入,否则会向上舍入。
银行家四舍五入 - 偶数遵循基本半舍入规则,奇数遵循慷慨半舍入规则。这在实际银行中很少见,如果资金流向他们更喜欢四舍五入,而当资金流向客户时则四舍五入。
ORACLE NUMBER 实际上是一个非常好的十进制算术实现,并且就它而言是准确的。
Oracle 已经从零开始实施了一半:
SQL> select round(22.5) from dual
2 /
ROUND(22.5)
-----------
23
SQL> select round(23.5) from dual
2 /
ROUND(23.5)
-----------
24
SQL> select round(-23.5) from dual
2 /
ROUND(-23.5)
------------
-24
SQL> select round(-22.5) from dual
2 /
ROUND(-22.5)
------------
-23
SQL>
他们为什么不将其更改为银行家四舍五入?好吧,对于大多数目的,距离零大约一半就足够了。另外还有那个旧的后备,改变它可能会破坏太多现有的代码库——甲骨文自己的以及他们所有的客户。
旧线程,但有人可能仍然需要这个。Oracle 的二进制浮点数和二进制双精度数在舍入为整数时遵循银行家的舍入规则。所以你可以使用它。它很丑,但它有效:
给定:价格 = 2.445 SQL> select round(to_binary_float(price * 100)) / 100 as price_rounded from dual; price_rounded ------------- 2.44 给定:价格 = 2.435 SQL> select round(to_binary_float(price * 100)) / 100 as price_rounded from dual; price_rounded ------------- 2.44
在这个例子中,乘以 100 和除以 100 是必要的。我无法弄清楚行为的细节,但是对于一些小数,价格选择 round(to_binary_float(price), 2) 似乎并没有按照相同的规则始终向上或向下舍入。然而,我发现,四舍五入始终可以满足我的需求。
您始终可以按照此处所述实现自己的银行家舍入函数。
银行家四舍五入的 0.5 到 0:它向偶数四舍五入。