端数処理:六つのルールとその代償

端数処理は、算数の中でも議論の余地がない分野のように思えるかもしれません。試しに一つの値を選んで、六つのルールがそれぞれどう違う結果を出すか見てみましょう。次に、同じ数を一度ではなく二段階に分けて丸め、答えがどう変わるか確かめてみてください。

インタラクティブシミュレーションを読み込んでいます...

偶数への丸めは、正確なルールではなく偏りのないルールである 🖖

値が二つの隣り合う数のちょうど中間に位置するとき、どのルールも正解にはなり得ません。問題は、どちらの方向へ間違えるかということです。学校で習うルールは常に上へ向かいます。これは教えるのも確認するのも簡単ですが、その代償として毎回同じ方向へ間違えることになります。境界上の値ばかりの列を読み込んで、四捨五入を適用してみてください。合計は値一つにつき半分ずつ、真の値から上へずれていきます。2,000 個の値なら 1,000、6,400 個なら 3,200 も大きくなります。そこにはばらつきが一切ありません。決して変化しないルールには、ランダムな要素が何もないからです。偶数への丸めは、中間の値を偶数の隣接値へ送ります。そのため 2.5 は 2 に下がりますが、3.5 は 4 に上がります。意図的に操作されていない列全体で見れば、この動きが交互に起こるため、誤差は積み重なることなく相殺されます。IEEE 754 がこれを浮動小数点演算の標準とし、多くの会計基準がこれを求めるのは、単一の値に対する正確さが理由ではありません。一つの数字だけを見れば、かえって不正確になることもあります。多くの数値を扱ったときに偏りが出ないこと。それこそがまったく別の特性であり、大量のデータを扱う際に重要になるのです。

二段階の丸めは、一度の丸めとは異なる操作である 🖖

2.45 を整数に丸めてみましょう。小数点以下の部分は半分より小さいため、答えは 2 です。では、これを二段階で行ってみます。小数第一位に丸めると、2.45 は境界値となり 2.5 になります。そして 2.5 を整数に丸めると 3 です。どちらの操作もルールには従っていますが、答えは異なります。ここで起きたのは、最初の丸めが存在しない境界値を人工的に作り出してしまったということです。元の値は中間点より確実に下にありましたが、一段階経ることでぴったり境界上になり、二段階目ではどちらか当て推量するしかなくなってしまったのです。小数第二位までのあらゆる値を 1,000 まで調べてみると、この途中経過のせいで 5.00% の値において答えが変わってしまいます。小数第二位が 45 から 49 までの値すべて、つまり 100 個に 5 個の割合です。通貨の換算や税金の計算、あるいは単位の連続した変換において、どこで丸めを行うかが厳密に指定されるのはこのためです。誰も計算そのものを疑っているわけではありません。「最後に丸める」ことと「段階ごとに丸める」ことは、同じ見かけをした全く異なる計算だからなのです。

偏った誤差は要素数とともに大きくなり、公平な誤差はその平方根とともに大きくなる 🖖

列の内容を境界値に切り替えて、長さを伸ばしてみてください。四捨五入は真っ直ぐな線を描きます。すべての値が同じ方向へ半分ずつ寄与するため、乖離は永遠に要素数の半分のまま、ばらつきはありません。偶数への丸めは、少し上がっては下がり、ゼロを横切って反対側へ抜けるという、さまようような線を描きます。2,000 種類の異なる列で測定した場合、その振る舞いの典型的な大きさは要素数の平方根の半分になります。100 個の値なら約 5、1,600 個なら 20、6,400 個なら 40 です。これこそがランダムウォークの特徴であり、実用上の違いのすべてでもあります。6,400 個の値において、偏ったルールは 3,200 ずれるのに対し、公平なルールは約 40 のずれで済みます。片方は要素数そのものと同じように成長し、もう一方はその平方根のように成長するため、行が追加されるたびに両者の比率は広がり続けるのです。一般的な数値の列に切り替えても、これと同じことが静かに起きています。そこでは境界値は珍しく、1,000 個中 11 個しかありません。したがって乖離の大部分は通常の丸めから生じており、どちらのルールも真の値である 98,351.63 から約 8 以内の範囲に収まります。次に同じ列に対して切り捨てを試すと、486 不足します。切り捨ては境界値からだけでなく、ほぼすべての値から少しずつ何かを奪い取っていくからです。

全プロセスの詳細解説

  1. 真の合計が98,351.63である1,000の金額の最も近い整数への丸め 7 ステップ

    ある店舗で、1,000 個の金額をそれぞれ最も近い整数に丸めて合計します。真の合計額は 98,351.63 です。それぞれのルールを適用した場合の丸められた合計を計算し、店舗がどのルールを使うべきか判断してください。

    1. 列の計算に入る前に、ルールを明確にしておきましょう。2.5 で考えてみます。四捨五入はこれを 3 にします。偶数への丸めはこれを 2 にします。2 が偶数の隣接値だからです。

    2. 偶数への丸めが常に切り下げるわけではなく、交互に切り替わることを確認してください。3.5 はどちらのルールでも 4 になります。今度は上にある値が偶数だからです。

    3. さて、列について考えます。1,000 個の金額のうち、ちょうど境界上に位置するのは 11 個だけです。つまり二つのルールは 989 個の値において一致しており、違いが出るとしても最大で 11(境界値一つにつき 1 ずつ)になります。

    4. 丸められた値を合計します。四捨五入では 98,360 となり、真の値より 8.37 大きくなります。偶数への丸めでは 98,354 となり、2.37 大きくなります。両者の間の 6 の差は、先ほどの 11 個の境界値から生じたものです。

    5. その乖離の大部分は境界値によるものではありません。それは通常の丸めによるものであり、1,000 個の一般的な数値であれば、どちらに転ぶ可能性もほぼ同じです。ノイズではなくルールの本質を見るために、列を境界値だけに切り替えてみましょう。すべての値が境界値の場合、四捨五入は 500 大きくなり、偶数への丸めの誤差は 6 になります。

    6. 比較のために、元の列で切り捨てを試してください。結果は 97,866 となり、486 不足します。切り捨ては境界値からだけでなく、ほぼすべての値から少しずつ何かを奪い取っていくため、乖離が積み重なるのに境界値を必要としません。

    7. したがって、どのルールを使うべきかは、何を守りたいかによって決まります。一枚のレシートであれば、どちらのルールでも構いませんし、その差が半分を超えることはありません。しかし帳簿全体で見れば、偏った方向を持たないルールだけが、合計を本来あるべき場所に留めておくことができます。

    解答

    四捨五入では 98,360、偶数への丸めでは 98,354、切り捨てでは 97,866 となり、真の値は 98,351.63 です。 この店舗は偶数への丸めを使うべきです。個々の金額においてより正確だからではありません(実際、悪くなることもあります)。その誤差に特定の方向性がなく、結果として積み重ならないからです。四捨五入は、境界値に遭遇するたびに例外なく上方向へ半分ずつ間違えていくのです。

  2. 1.005 を小数第 2 位へ、そして境界のようで境界でない値 7 ステップ

    1.005 を小数第 2 位に丸めてください。それを入力したとき機械が実際に保持している値を求め、そのうえで 1.00 と答える表計算ソフトが間違っているのかどうかを判断しましょう。

    1. 小数として見れば境界値です。1.005 は 1.00 からも 1.01 からも等距離にあるので、四捨五入は上へ送り、パネルは 1.01 と表示します。

    2. しかし機械が保持しているのは小数ではありません。倍精度数は 2 のべき乗の和であり、0.005 は 200 分の 1、その分母には 2 のどのべき乗でも供給できない 5² が含まれています。2 進展開は終わりません。

    3. 格納されるのは最も近い倍精度数であり、それは 1.005 より約 1.07 × 10⁻¹⁶ 下にあります。厳密に比べればこれはまったく境界値ではなく、四捨五入なら 1.00 へ下ろすことになります。

    4. この差は、比較のために値をスケールした瞬間に見えるようになります。1.005 × 100 は 100.49999999999999 であり、その小数部は 0.5 に 1.42 × 10⁻¹⁴ だけ届きません。

    5. ここでの丸めが吸い付くのはそのためです。0.5 から機械語で 8 ステップ以内にあるものはすべて 0.5 として扱われ、この大きさではその窓幅が 1.79 × 10⁻¹³、先ほどの差の 10 倍以上あります。パネルは、2 進数が投げかけた問いではなく、あなたが小数について投げかけた問いに答えているのです。

    6. この許容幅はただではなく、その代償は列が示します。.005 で終わる 1,000 個の値がそれぞれ 100 分の 1 の半分ずつ押し上げられ、合計は真の値より 5.00 高くなります。偶数への丸めは同じ境界値を振り分け、誤差は 0.07 に収まります。

    7. 残る二つのプリセットは種類が違います。2.5 と 12.5 は 2 進で厳密に表せるので、紙の上だけでなく機械の中でも境界値であり、許容幅は一切関与しません。「ちょうど半分」とは、あなたが入力した小数の性質であって、機械の中まで生き延びるのは本当に半分である半分だけなのです。

    解答

    1.01 です。そして 1.00 と答える表計算ソフトは、自分が保持している数については正しく、あなたが入力した数については間違っています。 格納された値は 1.005 より 1.07 × 10⁻¹⁶ 下にあるため、厳密な比較が境界値を見ることは決してありません。読み手が期待する場所へ答えを戻しているのは、あの吸い付きです。どんな丸め規則も、その下にある問題そのものは直せません。お金は整数のセント、あるいは十進型に置くべきです。そこでは 1.005 は 1.005 であり、この問い自体が起こりません。

学習の道すじ

数を書き下すということ

参考文献 (2)

例題

  • 境界上の値 - 2.5 は 2 と 3 のちょうど中間に位置し、ルールによって結果が分かれます。四捨五入は 3 としますが、偶数への丸めは 2 になります。数値を 3.5 に変えてみると、どちらも 4 で一致します。そこでは 4 が偶数の隣接値だからです。偶数への丸めは切り捨てをひいきしているわけではありません。交互に切り替わっているのです。
  • 二段階の丸め - 2.45 を整数に丸めると 2 です。しかし、まず小数第一位に丸めると 2.5 になり、その 2.5 を整数に丸めると 3 になります。どちらの段階でもルールは守られていますが、答えは異なります。
  • バグに見える例 - 1.005 を小数第二位に丸めると 1.01 になるはずです。ところが JavaScript や Python に計算させると、どちらも 1.00 と答えます。これは 1.005 が 1.005 そのものとして保存されているわけではなく、ほんのわずかに小さい値として扱われているためです。実際、1.005 に 100 を掛けると 100.49999999999999 になります。このツールが 1.01 と答えられるのは、完全な一致を判定するのではなく、許容誤差を設けて境界値を探しているからにほかなりません。
  • 長い列 - 6,400 個の値が並び、そのすべてがちょうど境界上にあります。四捨五入はすべての値を同じ方向へ丸めるため、合計は 3,200 も大きくなります。例外なく、一つの値につき半分ずつずれるからです。この列に対して偶数への丸めを使うと、最終的な誤差はわずか 1 に留まります。