トピック 71 / 91· ソフトウェア工学とデジタル提供
通貨安全なコスト集計
多数の金額項目(月次請求書、拠点別コスト、複数年の予算影響額など)を通常の2進浮動小数点数(f64)で合計すると、小さな表現誤差が蓄積します。ほとんどの10進小数(たとえば$1,234.56)は2進浮動小数点では正確に表現できないためです。個々の誤差は微小ですが、数百から数千の項目を数年にわたって合計する大きなモデルでは、1セントの何分の一かだけずれることがあり、そのずれは加算の順序に依存するため再現できません。正確な10進(または整数の最小単位)演算で行う通貨の集計は正確に合計され、会計システムや複式簿記が1セント単位まで一致しなければならないことと整合します。
なぜ重要か
これは文書化が進んだ、基本的なソフトウェアバグの一類型です。Goldbergの1991年のACM Computing Surveys論文「What Every Computer Scientist Should Know About Floating-Point Arithmetic」は、2進浮動小数点がほとんどの10進の金額を正確に表現できない理由と、それらを多数合計すると誤差が複合する理由についての標準的な参考文献です。ヘルスエコノミクスやNHSの財務モデルは、日常的に多くの年と多くのコスト区分を合計します。総所有コストと予算影響分析はどちらも、複数年の期間にわたって大量のf64コスト項目を集計します。モデルが1セント単位で一致しなければならない場合、つまり手計算で合計を再計算する監査が同一の数値を得なければならない場合、演算自体が浮動小数点ではなく正確な10進でなければなりません。
数式
素朴な集計: 合計 = Σ f64(項目_i) — 順序依存のずれ
通貨安全な集計: 合計 = Σ Decimal(項目_i) — 正確で再現可能
割合調整(たとえば予備費バッファ)の適用:
調整後 = 合計 × 乗数 — 正確なDecimalの結果で、通貨の最小単位の
指数より多くの小数桁を持つことがある
丸め後 = 丸め(調整後, 通貨指数, 丸めルール) — 丸めルール(四捨五入のhalf-up対
銀行家丸めのhalf-even)は明示する必要がある
2段階の規律に注目してください。正確なDecimalの金額に乗数を掛けると、通貨が実際に使う桁数より多くの小数桁が生じることがあります(たとえば、小数2桁の金額に小数2桁の乗数を掛けると小数3桁になります)。その中間的な精度は自動的には丸められません。明示的な丸めステップと明記された丸めルールだけが、それを通貨の実際の最小単位の指数まで下げます。
計算例
$1,234.56の月次請求書12件を正確な10進演算で合計します。$1,234.56 × 12 = $14,814.72、ちょうどです。これに対し、f64リテラル1234.56をIEEE-754倍精度で12回合計すると、加算の順序によっては1セントの何分の一かずれることがあります。これは実在する文書化されたバグの一類型であり、正確な10進のMoney演算で作られたモデルにとっては問題になりません。
次に、この$14,814.72の合計に標準的な予算影響の予備費バッファ5%(乗数1.05)を適用します。$14,814.72 × 1.05 = $15,555.456で、乗算が正確であり通貨の小数2桁に自動的には丸められないため、小数3桁になります。これを銀行家丸め(half-even)で小数2桁に明示的に丸めると、ちょうど**$15,555.46**になります。
ソフトウェア工学との関連
これは「金融ソフトウェアはfloatではなくDecimalを使う」という考え方の背景にある、直接的で基本的な教訓です。このリポジトリの総所有コストと予算影響分析のモジュールに明確に結びついており、これらは現在どちらも通常の浮動小数点のコストを合計しています。正確さの議論は、それらのモデルをすぐに移行することを求めるものではありませんが、システムがいつ1セント単位で一致しなければならず、したがって金額の演算に2進浮動小数点を使ってはならないかを正確に示しています。合計(ではなく分割)をセントを失わずに行うという対になる問題については、セント単位で正確なコスト配分も参照してください。
落とし穴
- 途中で
floatに変換すること: 計算の途中で金額を浮動小数点数に取り出すこと(一部のMoneyライブラリは、この変換メソッドを明示的な警告として「lossy」のような名前にしています)は、その時点より後のすべての計算について、正確さの保証を黙って捨てることになります。 - 「Decimalは遅すぎて気にする価値がない」: 財務報告では生のスループットではなく正確さと監査可能性が重要であるにもかかわらず、正確な10進演算を不要なオーバーヘッドとして退けること。
- 丸めルールを明記せずに予備費の割合を適用すること: half-upとhalf-even(銀行家丸め)では最後の1セントが変わることがあります。丸めの規約自体が、明記された監査可能な選択でなければなりません。この丸めステップが適用される数値の典型である、予備費と楽観バイアスの調整に関するHM Treasuryのグリーンブックのガイダンスについては、費用便益分析を参照してください。
出典
- Fowler M. "Patterns of Enterprise Application Architecture." Addison-Wesley, 2002 —
Moneyパターン。 - Goldberg D. "What Every Computer Scientist Should Know About Floating-Point Arithmetic." ACM Computing Surveys, 1991.
- HM Treasury, The Green Book — 予算影響モデリングのための楽観バイアスと予備費のガイダンス. https://www.gov.uk/government/publications/the-green-book-appraisal-and-evaluation-in-central-government/the-green-book-2020