问题
Why Oracle is not using Bankers rule (the rounding method)?
回答1:
Accurate decimal arithmatic is a large and complex subject.
Google 'mike colishaw decimal rounding' if you want to read the ahem Oracle on the subject.
Basically there are many rounding schemes which are possible:-
Round everthing down - the default in most languages including C as Oracle is written in C this is probably why they do this.
Round everything up - rarely seen but occasionally needs to be implemented because of obscure market and tax rules.
Basic Half Rounding - anything above .5 rounds up everything else rounds down.
Generous Half Rounding - anything below .5 rounds down everthing else rounds up.
Bankers Rounding - Even numbers follow the Basic Half Rounding rule, odd numbers the Generous Half Rounding rule. This is rarely seen in actual banks which prefer rounding up if the moneys coming thier way and rounding down when its going the clients way.
ORACLE NUMBER is actually a pretty good Decimal Arithmatic implementation and is accurate as far as it goes.
回答2:
Oracle has implemented round half away from zero:
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>
Why don't they change it to Bankers' Rounding? Well, for most purposes round half away from zero is good enough. Plus there's that old fallback, changing it would likely break too much of the existing codebase - Oracle's own as well as all their customers.
回答3:
Old thread, but someone may still need this. Oracle's binary floats and binary doubles follow the banker's rounding rule when rounding to a whole number. So you can use that. It's ugly but it works:
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
The multiply and divide by 100 are necessary in this example. I haven't been able to figure out the specifics of the behavior, but select round(to_binary_float(price), 2) for some decimal, price, does not seem to consistently round up or down by the same rules. I have found, however, that rounding to a whole number consistently gives me what I need.
回答4:
You can always implement your own function for banker's rounding as described here.
回答5:
Banker's rounding round's 0.5 to 0: it round's towards even numbers.
来源:https://stackoverflow.com/questions/1292616/oracle-bankers-rule