为什么Oracle没有使用Bankers rule(舍入方法)?
答案 0 :(得分:11)
精确的十进制算术是一个庞大而复杂的主题。
如果你想阅读关于这个话题的甲骨文,可以使用谷歌“mike colishaw decimal rounding”。基本上有很多可能的舍入方案: -
圆形向下 - 大多数语言的默认值,包括C,因为Oracle是用C语言编写的,这可能是他们这样做的原因。
全面解决所有问题 - 很少见,但由于市场和税收规则模糊,偶尔需要实施。
基本的半舍入 - 任何高于.5的任何事情都会向上舍入其他所有事情。
慷慨的半舍入 - 任何低于.5向下的东西都会向上舍入。
银行家舍入 - 偶数遵循基本半舍入规则,奇数是慷慨的半舍入规则。在实际的银行中很少见到这种情况,如果货币流向客户方式,那么这些银行更愿意进行整理。
ORACLE NUMBER实际上是一个非常好的Decimal Arithmatic实现,并且就其而言是准确的。
答案 1 :(得分:4)
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>
为什么不将它改为银行家的舍入?好吧,对于大多数用途而言离零一半就足够了。此外,还有旧的后备,改变它可能会破坏现有代码库的太多 - 甲骨文自己以及所有客户。
答案 2 :(得分:2)
旧线程,但有人可能仍然需要这个。当舍入到整数时,Oracle的二进制浮点数和二进制双精度符合银行家的舍入规则。所以你可以使用它。这很难看,但它有效:
given : price = 2.445 SQL> select round(to_binary_float(price * 100)) / 100 as price_rounded from dual; price_rounded ------------- 2.44 given : price = 2.435 SQL> select round(to_binary_float(price * 100)) / 100 as price_rounded from dual; price_rounded ------------- 2.44
在此示例中,乘以除以100是必要的。我无法弄清楚行为的具体细节,但选择round(to_binary_float(price),2)对于某些小数,价格,似乎不会按照相同的规则一致向上或向下舍入。然而,我发现,对整数进行舍入始终能够满足我的需要。
答案 3 :(得分:1)
如here所述,您可以随时为银行家舍入实现自己的功能。
答案 4 :(得分:1)
银行家的四舍五入为0.5比0:它是朝着偶数的方向发展。