四捨五入

二進法だから四捨五入に誤差が出る??

ボーランド社の Turbo Pascal という言語製品を購入したことがあります。1980年代後半だったと記憶します。たしか、5インチのFD一枚にマニュアルが本が一冊ついてきたと思います。NEC PC-9801シリーズ用でMS-DOS上で動くものでした。当時N88-BASIC(86)でプログラムを書いていましたが、行番号から自由になりたい、if文に書ける命令が1行だけというのを何とかしたいという思いで、次の言語を探していたときでした。

とりあえず、足し算をして平均を求めると、2.5の四捨五入が 2 になってしまいます。今ふりかえると、「ちょうど真中は偶数へ丸める」という丸め方式だったのだろうと思います。当時はそんなことを知らず、取次ぎ元へ質問の手紙を書きました。当時のことですので、メールなんてのはありませんし、長距離の電話で面倒な話は無理と思ったからです。

担当からの答えは、「二進法で計算しているから誤差が出る。BCD演算もできるがパフォーマンスからお勧めできない」というものでした。

ツッコミどころ満載です。まず、営業としては「パフォーマンスは落ちるけどBCDを使うことを検討してください」だろうと思います。私としては「二進法だから」を議論したかったので、結局BCDはやってみませんでしたが偶数へ丸める方式が原因ならこれでも解決しなかったと思われます。

そもそも10進小数の中で0.5は正確に2進小数にすることができる数です。2進にすることで不正確になることはありません。

マニュアルに四捨五入と書いてある限り、2.5が 3 にならないのはおかしい。どう考えてもこの説明は納得いかず、食い下がったのですが、わかってはもらえませんでした。

四捨五入はroundの訳として疑わずに書いただけなのでしょう。だれも気づいていなかったわけです。

偶数への丸めに出会う

私が偶数へ丸める方式を知ったのは2010年あたりで、経緯は覚えていないのですが、何かのプログラム言語で四捨五入の関数の書き方をネット検索していて目にしたのだと思います。

偶数へ丸めるというのは、数値を近い方に切り上げ、または切り捨てするという所は四捨五入と同じです。しかし(とりあえずわかりやすく整数にするというところを例にして)、0.5というちょうど真中の値の場合には偶数の方に丸めるという所が四捨五入と異なります。

1.5は 2 になりますが、2.5も 2 になります。3.5は 4 になりますが、4.5も 4 になります。

さらに調べて驚いたことには、日本工業規格でも定められていたということです。その時の記憶では JIS Z 8401で 偶数への丸めが規則Aとして定められ、四捨五入に相当なものが規則Bとして定められていて、規則Aが望ましいとありました。今回改めてhttp://www.jisc.go.jpから JIS Z8401:1999 を閲覧すると、「規則Bが用いられることもある。」とトーンダウンしています。

一般にはどっち

JISにも「この規格は、鉱工業において用いる...」とありますので一般社会の習慣である四捨五入について何かを言うつもりはないとは思うのですが、国際規格に一致した規格を作成するという意図で ISO 31-0 基礎として作ったとも書いてありますので、高校までのどこかで触れられるべきことかなと思います。

私は学校で教えられた記憶がありません。指導要領まで調べてはいませんが、たぶん教えることにはなっていないと思います。大学で実験実習の数値処理で誤差の扱いを学んだ時にも触れられませんでした。高校の理科で実験結果の有効数字の扱い方を教えてきましたが、四捨五入以外の丸めに触れた資料に出会うこともありませんでした。

ISOになっているということで、諸外国の四捨五入の習慣がちょっと気になります。英語では偶数への丸めは bankers' rounding (銀行家の丸め)とも呼ばれていて、この名前が実務的な仕事に就いている一般的な人という意味ならば一般的に知られているという事だし、銀行家という特殊な人たちが使うやりかたという意味ならば、一般人は知らないという事になるでしょう。

いろいろ捜してみたのですが、なかなか見つかりません。

ありました、Java API の解説の中 java.math の Enum RoundingMode の説明です。

https://docs.oracle.com/javase/7/docs/api/java/math/RoundingMode.html

"HALF_UP"(これが四捨五入相当)に"Note that this is the rounding mode commonly taught at school."とあります。"HALF_EVEN"(これが偶数丸めに相当)には" It is sometimes known as "Banker's rounding," and is chiefly used in the USA."とあります。chiefly used がどの程度かはやっぱりわかりませんが、commonly taught at school は具体的です。一般人は四捨五入を習うという事でよいのではないでしょうか。

プログラム言語では、偶数への丸め、表計算などの一般向けソフトウェアは四捨五入となっているようではあります。表計算などではロケールにより国別対応になっていないとも限らないのですが、まぁ大丈夫でしょう。

プログラム言語では注意が必要です。javascriptやPHP,最近のpythonの動きなどを見ても一般人がプログラム言語を使う機会が増えています。