銀行丸め、ROUNDとの違いに注意

ORACLE

ORACLEの端数処理関数について、先日まとめました。その中で、ROUND関数は四捨五入であり、銀行丸めではないと記述しました。
今回の記事では、その銀行丸めについて解説していきたいと思います。

スポンサーリンク

銀行まるめとは

銀行丸めとは、端数が5より小さいなら切捨て、5より大きいならは切上げるというところまでは、通常の四捨五入と同じです。異なっているのは、5の場合の扱いです。通常の四捨五入が切上げるのに対し、銀行丸めは結果が偶数になる方に丸めます。

例をあげると、以下のようになります。

5.4⇒5(端数が5より小さい)
5.6⇒6(端数が5より大きい)
5.5⇒6(偶数になる方に丸める)
4.5⇒4(偶数になる方に丸める)

通常の四捨五入だと、4.5は5に丸めます。

銀行員が好んで使っていたことがこの名前の由来のようです。
別名「最近接偶数への丸め」、単に「偶数丸め」と呼ぶこともあります。
また、JIS規格(日本工業規格)では四捨五入よりも銀行丸めを使用する方が望ましいとしています。国が推奨しているのにも関わらず、ほとんど使われているあたりは不思議ですね。学校で習った記憶もないです。四捨五入に比べて分かりにくいのがネックなのかもしれません。

では、銀行丸めはどのような点で利点があるのか、それは端数処理後の値を合計する際の誤差が少ない点にあります。

   A   B   C(Aは端数ありの生数字、Bは四捨五入、Cは銀行丸め)
----  --  --
 0.5   1   0
 1.5   2   2
 2.5   3   2
 3.5   4   4
 4.5   5   4
====  ==  ==
12.5  15  12

端数処理をせずに合計した値と比較した場合、通常の四捨五入よりも銀行丸めの方が差が小さいのが分かります。

スポンサーリンク

ORACLEでの銀行丸めサンプル

ORACLEで銀行丸めを行うためのサンプルです。
負数も偶数に丸めています。

SQL内で使用(整数に丸める場合)
(aには対象数値項目を指定してください)

SELECT CASE WHEN MOD(ABS(a), 2) = 0.5 THEN
         TRUNC(a)
       ELSE
         ROUND(a)
       END
  FROM test_table
;

SQL内で使用(整数以外にも丸める汎用版)
(aには対象数値項目を指定、bには桁位置の指定(ROUND関数の指定と同じ)してください)

SELECT CASE WHEN MOD(ABS(a) * POWER(10, b), 2) = 0.5 THEN
         TRUNC(a, b)
       ELSE
         ROUND(a, b)
       END
  FROM test_table
;

ファンクション

CREATE OR REPLACE FUNCTION func_sample(a IN NUMBER, b IN NUMBER DEFAULT 0)
RETURN NUMBER IS
BEGIN
  IF MOD(ABS(a) * POWER(10, b), 2) = 0.5 THEN
    RETURN TRUNC(a, b);
  ELSE
    RETURN ROUND(a, b);
  END IF;
END;
/

上記ファンクション使用

SELECT a, ROUND(a), func_sample(a) FROM test_table;

         A   ROUND(A) FUNC_SAMPLE(A)
---------- ---------- --------------
       4.5          5              4
       5.5          6              6
      -4.5         -5             -4
      -5.5         -6             -6

SELECT a, ROUND(a, 1), func_sample(a, 1) FROM test_table;

         A   ROUND(A) FUNC_SAMPLE(A)
---------- ---------- --------------
      5.45        5.5            5.4
      5.55        5.6            5.6
     -5.45       -5.5           -5.4
     -5.55       -5.6           -5.6

参考(使用している関数について)

MOD:除算の余りを求める
ABS:絶対値を求める
POWER:累乗計算

ROUNDのプログラム言語やDBでの差異

ここまでORACLEの動作を見てきましたが、ROUND関数の動作はプログラム言語やDBによって異なります。
四捨五入:Java・EXCEL関数・PostgreSQL・SQLServer など
銀行丸め:C#・VBA・MYSQL など

EXCEL関数とVBAで動作が異なるのは意外です。注意が必要ですね。

まとめ

通常の四捨五入と銀行丸めは、端数が5の場合の動作が異なることについて、細かく見てきました。
5の端数処理が、ユーザーの要求と一致しているかどうか、注意してみてください。

関連

タイトルとURLをコピーしました