Правило Oracle Bankers

Почему Oracle не использует правило банкиров (метод округления)?


person Madhu    schedule 18.08.2009    source источник
comment
Я предполагаю, что вы действительно имеете в виду: - Почему десятичная арифметика с использованием типа данных NUMBER в базе данных ORAACLE не использует схему половинного округления, известную как Bankers Rounding.   -  person James Anderson    schedule 18.08.2009
comment
Потому что у Oracle больше денег, чем у большинства банкиров, и не вижу смысла прислушиваться к их советам?   -  person skaffman    schedule 18.08.2009
comment
посоветоваться с банкиром... звучит опасно!   -  person lexu    schedule 19.08.2009


Ответы (5)


Точная десятичная арифметика - большой и сложный предмет.

Google 'Майк Колишоу десятичное округление', если вы хотите прочитать кхм Оракул по этому вопросу.

В основном существует множество схем округления, которые возможны:

Округлите все в меньшую сторону - по умолчанию для большинства языков, включая C, поскольку Oracle написан на C, возможно, поэтому они так и делают.

Соберите все в кучу - редко встречается, но иногда необходимо реализовать из-за неясных рыночных и налоговых правил.

Базовое половинное округление — все, что выше 0,5, округляется в большую сторону, все остальное округляется в меньшую сторону.

Щедрое половинное округление — все, что меньше 0,5, округляется вниз, все остальное округляется вверх.

Округление банкиров — четные числа следуют основному правилу округления до половины, нечетные числа — правилу щедрого округления до половины. Это редко можно увидеть в реальных банках, которые предпочитают округлять деньги, если они приходят к ним, и округлять в меньшую сторону, когда они идут к клиентам.

ORACLE NUMBER на самом деле является довольно хорошей реализацией десятичной арифметики и точен, насколько это возможно.

person James Anderson    schedule 18.08.2009

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.

person APC    schedule 18.08.2009

Тема старая, но может кому пригодится. Двоичные числа с плавающей запятой и двойные числа 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) для некоторого десятичного числа, цена, похоже, не всегда округляется вверх или вниз по одним и тем же правилам. Однако я обнаружил, что округление до целого числа постоянно дает мне то, что мне нужно.

person Caleb Mathis    schedule 09.05.2012

Вы всегда можете реализовать собственную функцию округления банкира, как описано здесь.

person Dirk Vollmar    schedule 18.08.2009

Округление банкира от 0,5 до 0: оно округляется до четных чисел.

person Eamon Nerbonne    schedule 18.08.2009
comment
К сожалению, я объяснил округление от 0,5 до 1. ОП не упомянул об этом. Исправлено сейчас. - person Thilo; 18.08.2009