
四捨五入とは、数値を近似値、より便利な値に調整するプロセスであり、多くの場合、より短く簡潔な表現が使用されます。例えば、$23.4476を$23.45に、分数312/937を1/3に、式√2を1.414に置き換えるなどです。
丸めは、元の値よりも報告や伝達が容易な値を得るためによく行われます。また、計算された数値、測定値、または推定値の正確な報告が誤解を招くのを防ぐためにも重要です。例えば、123456と計算された値が、その誤差が数百単位以内であることが分かっている場合は、通常「約123500」と表現する方が適切です 。
一方、正確な数値を丸めると、報告される結果に多少の丸め誤差が生じます。多くの計算を報告する場合、特に整数または固定小数点演算で2つの数値を割る場合、平方根、対数、正弦などの数学関数を計算する場合、または有効桁数が固定された浮動小数点表現を使用する場合、丸めはほぼ避けられません。一連の計算において、これらの丸め誤差は通常蓄積され、特定の悪条件の場合には結果が意味をなさなくなる可能性があります。
超越関数の正確な丸めは困難です。なぜなら、切り上げか切り捨てかを決定するために計算しなければならない余分な桁数を事前に知ることができないからです。この問題は「表作成者のジレンマ」として知られています。
丸めは、物理量を数値またはデジタル信号でエンコードする必要がある場合に発生する量子化と多くの類似点があります。
波線イコール記号(≈)は、9.98 ≈ 10のように、正確な数値を丸めるために使用されることがあります。この記号は1892年にアルフレッド・ジョージ・グリーンヒルによって導入されました。[ 1 ]
丸め方法の理想的な特性は次のとおりです。
通常、1 つの方法ですべての理想的な特性を満たすことは不可能であるため、さまざまな丸め方法が存在します。
一般的な規則として、丸めはべき等性[ 2 ]を有する。つまり、一度数値を丸めた後、同じ精度で再度丸めても値は変化しない。また、丸め関数も単調である。つまり、2つの数値を同じ絶対精度で丸めても、順序は入れ替わらない(ただし、同じ値になる可能性はある)。離散的な範囲の一般的なケースでは、これらは区分定数関数である。
典型的な丸めの問題は次のとおりです。
| 丸め問題 | 入力例 | 結果 | 丸め基準 |
|---|---|---|---|
| 無理数を分数で近似する | π | 22/7 | 1桁の分母 |
| 有理数を分母が小さい分数で 近似する | 399 / 941 | 3/7 | 1桁の分母 |
| 分数を分数小数で近似する | 5/3 | 1.6667 | 小数点以下4桁 |
| 小数を桁数の少ない1で 近似する | 2.1784 | 2.18 | 小数点以下2桁 |
| 10進整数を末尾にゼロが続く整数で 近似する | 23217 | 23200 | 有効数字3桁 |
| 科学的記数法を使用して大きな小数整数を近似する | 300999999 | 3.01 × 10 8 | 有効数字3桁 |
| 指定された量の倍数で値を近似する | 48.2 | 45 | 15の倍数 |
| 有限の実数の集合のそれぞれを整数で近似し、丸められた数の合計が丸められた数の合計と等しくなるようにする[ nb 1 ] | | {0, 0, 1} | 丸められた要素の合計は、丸められた要素の合計に等しい |
最も基本的な丸め方法は、任意の数値を整数に置き換えることです。以下の丸めモードはすべて、抽象的な単一引数の「round()」手続きの具体的な実装です。これらは真の関数です(乱数を使用するものを除く)。
これら4つの方法は、元の数値xから丸められた値yへの変位がすべて同じ限界値(0、+∞、または-∞ )に近づくか離れるかするため、整数への有向丸めと呼ばれます。有向丸めは区間演算で使用され、金融計算でしばしば必要となります。
xが正の場合、切り捨てはゼロ方向への切り捨てと同じであり、切り上げはゼロから遠い方向への切り上げと同じです。xが負の場合、切り捨てはゼロから遠い方向への切り上げと同じであり、切り上げはゼロ方向への切り上げと同じです。いずれの場合も、xが整数であれば、yはxです。
多くの計算が連続して行われる場合、四捨五入の方法の選択は結果に非常に大きな影響を与える可能性があります。有名な例として、 1982年にバンクーバー証券取引所が設定した新しい指数があります。この指数は当初1000.000(小数点以下3桁の精度)に設定されていましたが、市場は上昇しているように見えたにもかかわらず、22ヶ月後には約520まで下落しました。この問題は、指数が毎日何千回も再計算され、常に小数点以下3桁に切り捨て(切り捨て)られていたため、四捨五入の誤差が蓄積されたことに起因していました。同期間について、切り捨てではなく最も近い千分の一に四捨五入して指数を再計算したところ、指数値は524.811から1098.892に修正されました。[ 3 ]
以下の例では、sgn( x )は元の数値xに適用された符号関数を指します。
切り捨て(または切り捨て値を取る、または負の無限大に向かって丸める)ことができます。 yはx を超えない最大の整数です。
たとえば、23.7 は 23 に丸められ、-23.2 は -24 に丸められます。
また、切り上げる(または上限を取る、あるいは正の無限大に向かって丸める)こともできます。yはxより小さくない最小の整数です。
たとえば、23.2 は 24 に丸められ、-23.7 は -23 に丸められます。
ゼロに向かって丸める(または切り捨てる、あるいは無限大から遠ざかる方向に丸める)こともできます。 yは 0 から x まで(0 とxを含む)の範囲内でxに最も近い整数です。つまり、 y は小数点以下の桁を除いた xの整数部分です。
たとえば、23.7 は 23 に丸められ、-23.7 は -23 に丸められます。
ゼロから離れる方向に丸める(または無限大に丸める)こともできます。 yは、 xが0 からyまで(両端を含む)になるように0 に(またはそれと同等に、xに)最も近い整数です。
たとえば、23.2 は 24 に丸められ、-23.2 は -24 に丸められます。
これら6つの方法は、最も近い整数への丸めと呼ばれます。数値xを最も近い整数に丸めるには、 xが2つの整数のちょうど中間にある場合、つまりxの小数部がちょうど0.5である場合に、何らかのタイブレークルールを適用する必要があります。
0.5 の小数部分がなければ、最も近い値に丸める方法で導入される丸め誤差は対称的になります。つまり、切り捨てられるすべての小数 (0.268 など) に対して、同じ量だけ切り上げられる補小数 (つまり、0.732) が存在します。
均一に分布した小数部を持つ多数の固定小数点数の集合を丸める場合、小数部が0.5の値を除いたすべての値による丸め誤差は、統計的に互いに補正されます。つまり、丸められた数値の期待値(平均)は、集合から小数部が0.5の値を除いた元の数値の期待値と等しくなります。
実際には、浮動小数点数が一般的に使用されますが、浮動小数点数は等間隔ではないため、計算上のニュアンスがさらに増します。
多くの分野で広く用いられている同点決着規則として、xの半分を切り上げる(または正の無限大方向に半分を切り上げる)という方法があります。つまり、 xの半分の値は常に切り上げられます。xの小数部がちょうど0.5の場合、y = x + 0.5となります。
たとえば、23.5 は 24 に丸められ、-23.5 は -23 に丸められます。
一部のプログラミング言語(JavaやPythonなど)では、「half up」を正の無限大に向かって半分を丸めるのではなく、ゼロから半分を遠ざけるという意味で使用します。[ 4 ] [ 5 ]
この方法では、 2 の補数や同様の表現 における丸め方向を決定するために 1 桁をチェックするだけで済みます。
より一般的な切り上げではなく、切り下げ(または負の無限大方向への切り上げ)を行うこともできます。xの小数部がちょうど0.5の場合、y = x − 0.5となります。
たとえば、23.5 は 23 に丸められ、-23.5 は -24 に丸められます。
一部のプログラミング言語(JavaやPythonなど)では、「half down」を負の無限大に向かって半分を丸めるのではなく、ゼロに向かって半分を丸めるという意味で使用します。[ 4 ] [ 5 ]
従来のゼロから半分だけ切り捨てるのではなく、ゼロに向かって半分だけ切り捨てる(または無限大から半分だけ切り捨てる)こともできます。xの小数部がちょうど0.5の場合、xが正であればy = x − 0.5、xが負であればy = x + 0.5となります。
たとえば、23.5 は 23 に丸められ、-23.5 は -23 に丸められます。
この手法では、正の値と負の値を対称的に扱うため、元の数値が正か負かの確率が同じであれば、全体として正負のバイアスが生じません。ただし、ゼロに向かうバイアスは依然として存在します。
一般的に教えられ、使用されている、タイブレークのルールである、半分をゼロから遠ざける(または半分を無限大に丸める)こともできます。つまり、 xの小数部分がちょうど 0.5 の場合、xが正であればy = x + 0.5となり、xが負であればy = x − 0.5 となります。
たとえば、23.5 は 24 に丸められ、-23.5 は -24 に丸められます。
この方法は、丸められる値に符号付き絶対値表現を使用するコンピュータではより効率的です。なぜなら、切り上げか切り下げかを判断する際に、最初の省略桁のみを考慮すればよいからです。この方法は単純であるため、 有効数字に丸める際によく使用されます。
この方法は商用丸めとも呼ばれ、正と負の値を対称的に扱うため、元の数値が正または負の確率で等しい場合、全体として正負のバイアスが生じません。ただし、ゼロから離れたバイアスは依然として存在します。
これは、追加の精度桁や金額の符号とは関係なく、最初の小数桁だけを考慮することで簡単に説明できるため、通貨換算や価格の丸め(金額が最初にユーロのセントなどの通貨の最小の重要な区分に変換されるとき)によく使用されます(金額の支払い側と受け取り側の間の厳密な同等性のため)。
半分を偶数に丸めることもできます。これは、正負のバイアスやゼロに向かうバイアス、ゼロから離れるバイアスのないタイブレークルールです。この規則によれば、 xの小数部が0.5の場合、yはxに最も近い偶数になります。したがって、例えば23.5は24になり、24.5も同様です。しかし、-23.5は-24になり、-24.5も同様です。この関数は、入力が大部分が正か大部分が負かに関わらず、大部分が偶数でも大部分が奇数でもない限り、丸められた数値の合計における期待誤差を最小化します。
最近似丸め法のこの変種は、収束丸め、統計学者丸め、ダッチ丸め、ガウス丸め、奇偶丸め、[ 6 ]または銀行家丸め[ 7 ]とも呼ばれます。
これは、 IEEE 754演算でバイナリ浮動小数点形式の結果に 使用されるデフォルトの丸めモードです。
偏りを排除することで、 1 次元のランダム ウォークのように、独立した数値を繰り返し加算または減算すると、誤差が線形ではなく、演算回数の平方根に比例して増加する傾向がある丸められた結果が得られます。
しかし、このルールは、オッズよりもイーブンの確率を高めることで、分布を歪めます。そのため、このルールは、分布よりも合計が重要な状況に使用されます。
半分を奇数に丸めることもできます。これは、半分を偶数に丸めるのと同様のタイブレークルールです。この方法では、xの小数部が0.5の場合、yはxに最も近い奇数になります。したがって、例えば23.5は23になり、22.5も同様です。また、-23.5は-23になり、-22.5も同様です。
この方法は、丸められる数値がほぼ偶数でもほぼ奇数でもない限り、正負のバイアスやゼロに向かうバイアス、ゼロから離れるバイアスもありません。また、奇数の確率を偶数よりも高くするため、元の分布を歪めるという「半分を偶数に丸める」という性質も持っています。これは、イギリスが通貨を10進法化した際に、銀行残高計算に使用された方法です[ 8 ]。
このバリアントは、指数範囲が限られている浮動小数点数のスケールの拡大を避けたい場合を除いて、計算ではほとんど使用されません。round half to evenでは、非無限数は無限大に丸められ、小さな非正規化値は通常の非ゼロ値に丸められます。実質的には、このモードは同数については既存のスケールを維持することを優先し、偶数基数の数値体系(2進数や10進数など) では可能な限り範囲外の結果を避けます。
あまり知られていない方法の一つは、小数部が0.5の数値を四捨五入する際に、方向を交互に変えることです。それ以外の数値は、最も近い整数に切り上げられます。小数部が0.5の場合は、切り上げと切り下げを交互に行います。つまり、小数部が0.5に初めて遭遇した場合は切り上げ、2回目に遭遇した場合は切り下げ、というように繰り返します。あるいは、最初の小数部0.5の丸めは、乱数シードによって決定することもできます。「切り上げ」と「切り下げ」は、正の無限大に近づく、または正の無限大から離れる、あるいは0に近づく、または0から離れるという、互いに反対の丸め方法のことです。
0.5 の小数部の発生が、発生の「カウント」の再開よりも大幅に多い場合、実質的にバイアスフリーとなります。バイアスがゼロであることが保証されているため、数値を合計または平均化する場合に役立ちます。
xの小数部が0.5 の場合、x + 0.5とx − 0.5の間でy を等確率でランダムに選択します。それ以外の場合は、最も近い整数に丸められます。
偶数への丸めや奇数への丸めと同様に、このルールは基本的に全体的な偏りがなく、y値が偶数と奇数の間でも公平です。交互タイブレークに比べて優れている点は、0.5の小数部における最後の丸め方向を「記憶」する必要がないことです。
次のように、負の無限大に向かって最も近い整数と正の無限大に向かって最も近い整数のいずれかに丸める処理は、近さに依存する確率で確率的丸めと呼ばれ、平均的には偏りのない結果が得られます。[ 9 ]
たとえば、1.6 は確率 0.4 で 1 に丸められ、確率 0.6 で 2 に丸められます。
確率的丸めは、丸め関数では決して実現できないほどの精度を実現できます。例えば、0から始めて0.3を100回加算し、その都度その加算の合算値を丸めるとします。通常の丸めでは結果は0になりますが、確率的丸めでは期待される結果は30となり、これは丸めを行わない場合と同じ値です。これは、学習で低精度演算を反復的に使用する可能性がある機械学習において有用です。 [ 9 ]確率的丸めは、1次元ディザリングを実現する方法でもあります。
| 価値 | 関数型メソッド | ランダム化手法 | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 有向丸め | 最も近い値に丸める | より短い精度に備えるためのラウンド | 交互タイブレーク | ランダムタイブレーク | 確率論的 | ||||||||||||
| 下(−∞に向かって) | 上(+ ∞に向かって) | 0に向かって | 0から離れて | 半分下(−∞方向) | ハーフアップ(+ ∞方向) | 0に向かって半分 | 0から半分離れたところ | 半分から均等に | 半分から奇数 | 平均 | SD | 平均 | SD | 平均 | SD | ||
| +2.8 | +2 | +3 | +2 | +3 | +3 | +3 | +3 | +3 | +3 | +3 | +2 | +3 | 0 | +3 | 0 | +2.8 | 0.04 |
| +2.5 | +2 | +2 | +2 | +2.505 | 0 | +2.5 | 0.05 | +2.5 | 0.05 | ||||||||
| +2.2 | +2 | +2 | +2 | +2 | 0 | +2 | 0 | +2.2 | 0.04 | ||||||||
| +1.8 | +1 | +2 | +1 | +2 | +1 | +1.8 | 0.04 | ||||||||||
| +1.5 | +1 | +1 | +1 | +1.505 | 0 | +1.5 | 0.05 | +1.5 | 0.05 | ||||||||
| +1.2 | +1 | +1 | +1 | +1 | 0 | +1 | 0 | +1.2 | 0.04 | ||||||||
| +0.8 | 0 | +1 | 0 | +1 | +0.8 | 0.04 | |||||||||||
| +0.5 | 0 | 0 | 0 | +0.505 | 0 | +0.5 | 0.05 | +0.5 | 0.05 | ||||||||
| +0.2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +0.2 | 0.04 | ||||||||
| −0.2 | −1 | 0 | −1 | −1 | −0.2 | 0.04 | |||||||||||
| −0.5 | −1 | −1 | −1 | −0.495 | 0 | −0.5 | 0.05 | −0.5 | 0.05 | ||||||||
| −0.8 | −1 | −1 | −1 | −1 | 0 | −1 | 0 | −0.8 | 0.04 | ||||||||
| −1.2 | −2 | −1 | −1 | −2 | −1.2 | 0.04 | |||||||||||
| −1.5 | −2 | −2 | −2 | −1.495 | 0 | −1.5 | 0.05 | −1.5 | 0.05 | ||||||||
| −1.8 | −2 | -2 | −2 | −2 | 0 | −2 | 0 | −1.8 | 0.04 | ||||||||
| −2.2 | −3 | −2 | −2 | −3 | −2 | −2.2 | 0.04 | ||||||||||
| −2.5 | −3 | −3 | −3 | −2.495 | 0 | −2.5 | 0.05 | −2.5 | 0.05 | ||||||||
| −2.8 | −3 | −3 | −3 | −3 | 0 | −3 | 0 | −2.8 | 0.04 | ||||||||
最も一般的な丸め方は、整数に丸めることです。または、より一般的には、ある増分の整数倍に丸めることです。たとえば、10分の1秒の整数倍、100分の1ドルの整数倍、1/2インチまたは1/8インチの整数倍、12または1000の整数倍などに丸めます。
一般に、数値x を指定された正の値mの倍数に丸めるには、次の手順に従います。
たとえば、x = 2.1784ドルをセント単位 (つまり、0.01 の倍数) に丸めるには、 2.1784 / 0.01 = 217.84を計算し、それを 218 に丸めて、最後に218 × 0.01 = 2.18 を計算する必要があります。
あらかじめ決められた有効桁数に丸める場合、増分mは丸める数値 (または丸められた結果) の大きさによって決まります。
増分mは通常、数値を表すのに用いられる記数法における有限の分数です。人間に表示する場合には、通常は10進記数法(つまり、mは1/1000や25/100のように、10の累乗の整数倍)を指します。デジタルコンピュータに保存される中間値の場合、 mは2の累乗の整数倍であること が多いです。
任意の実数値から整数値を返す抽象関数「round()」には、整数への丸めのセクションで少なくとも12個の異なる具体的な定義が示されています。抽象関数「roundToMultiple()」はここで正式に定義されていますが、多くの場合、増分値として暗黙の値m = 1が使用され、その後、同様に12個の異なる具体的な定義を持つ、同等の抽象関数「roundToMultiple()」に簡約されます。
指定された累乗に丸めることは、指定された倍数に丸めることとは大きく異なります。たとえば、コンピューティングでは、数値を 2 の整数累乗に丸める必要があることがよくあります。一般に、正の数x を1 以外の 正の数bの累乗に丸める手順は次のとおりです。
倍数への丸めに適用される多くの注意事項は、累乗への丸めにも適用されます。
音楽の半音階「十二音」では、 3 ⁄ 2は2 7/12 ( 5度)に丸められ、 4 ⁄ 3は2 5/12 ( 4度)に丸められ、5 ⁄ 4は2 4/12 (長3度)に丸められ、6 ⁄ 5は2 3/12 (短3度)に丸められ、9 ⁄ 8は2 2/12 (減3度)に丸められます。
このタイプの丸めは、対数スケールへの丸めとも呼ばれ、指定されたべき乗への丸めの一種です。対数スケールでの丸めは、量の対数を取り、対数スケール上の最も近い値に通常の丸めを行うことで実現されます。
例えば、抵抗器は対数スケールで推奨値とともに提供されます。特に、10%の精度を持つ抵抗器の場合、公称値は100、120、150、180、220など、10の倍数( E12シリーズ)に丸められます。計算の結果、165Ωの抵抗器が必要であると判明した場合、log(150) = 2.176、log(165) = 2.217 、 log(180) = 2.255となります。165の対数は180の対数に近いため、他に考慮する点がなければ、180Ωの抵抗器が第一候補となります。
値x ∈ ( a , b )がaに丸められるかbに丸められるかは、 x 2 の二乗値が積abより大きいか小さいかによって決まります。抵抗器の例では、値 165 は 180 に丸められます。これは、165 2 = 27225が150 × 180 = 27000より大きいためです。
浮動小数点演算において、丸めは与えられた値x を、指定された有効桁数を持つ値yに変換することを目的としています。言い換えれば、y はxの大きさに依存する数mの倍数である必要があります。数mは浮動小数点表現の 基数(通常は2または10)のべき乗です。
この詳細を除けば、上記で説明したすべての丸め方法は、浮動小数点数の丸めにも適用されます。このような丸めのアルゴリズムは、上記の「スケーリングされた丸め」のセクションで示されていますが、スケーリング係数は定数s = 1、基数b > 1です。
丸め結果がオーバーフローする場合、有向丸めの結果は、「ゼロから遠ざかる方向」の場合は適切な符号付き無限大、「ゼロに向かう方向」の場合は表現可能な最大の正の有限数(xが負の場合は表現可能な最小の負の有限数)となります。通常の最も近い値への丸めの場合、オーバーフローの結果は常に適切な無限大となります。
状況によっては、与えられた数x を「きれいな」分数、つまり分子mと分母nが所定の最大値を超えない最も近い分数y = m / nに丸めることが望ましい場合があります。この問題は、値を固定された10進数または2進数の桁数、あるいは所定の単位mの倍数に丸める問題とは全く異なります。この問題は、ファレイ数列、シュテルン・ブロコット木、および連分数に関連しています。
完成した木材、筆記用紙、電子部品、その他多くの製品は、通常、いくつかの標準値でのみ販売されます。
多くの設計手順では、近似値を計算し、「最も近い標準値に切り捨てる」、「最も近い標準値に切り上げる」、「最も近い標準値に丸める」などのフレーズを使用して、何らかの標準的なサイズに「丸める」方法を説明しています。[ 10 ] [ 11 ]
一連の好ましい値が対数スケール上で等間隔に並んでいる場合、任意の値に最も近い好ましい値を選択することは、スケール付き丸めの一種と見なすことができます。このような丸められた値は直接計算することができます。[ 12 ]
より一般的な丸め規則は、任意のブレークポイントで値を分割することができ、例えばデータのビン分割に使用されます。関連する数学的に形式化されたツールとして、サインポストシーケンスがあります。これは、単純な差ではなく距離の概念を使用します。例えば、シーケンスは相対誤差(パーセント誤差) が最小となる整数に丸められます。
音波などの連続信号をデジタル化する場合、個々の測定精度よりも、複数の測定による全体的な効果の方が重要です。このような状況では、通常、ディザリングと関連技術である誤差拡散法が使用されます。関連技術であるパルス幅変調は、可変デューティサイクルで電力を高速にパルス化することにより、慣性デバイスからアナログ型の出力を得るために使用されます。デルタシグマ変調は、実世界の信号とデジタル信号間の変換によく使用され、量子化(信号処理)の周波数統計を制御できます。
誤差拡散法は、誤差が平均的に最小になるように努めます。1から0への緩やかな勾配を扱う場合、最初の数項は出力が0になりますが、誤差と現在の値の合計が0.5を超えると1が出力され、その差がそれまでの誤差から差し引かれます。フロイド・スタインバーグ法は、画像をデジタル化する際によく使われる誤差拡散法です。
1次元の例として、0.9677、0.9204、0.7451、0.3091という数値が順に出現し、それぞれを0.01の倍数に丸めるとします。この場合、累積和0.9677、1.8881 = 0.9677 + 0.9204、2.6332 = 0.9677 + 0.9204 + 0.7451、2.9423 = 0.9677 + 0.9204 + 0.7451 + 0.3091は、それぞれ0.01の倍数、つまり0.97、1.89、2.63、2.94に丸められます。これらの最初の値と隣接する値の差により、目的の丸められた値が得られます: 0.97、0.92 = 1.89 − 0.97、0.74 = 2.63 − 1.89、および0.31 = 2.94 − 2.63。
モンテカルロ演算は、モンテカルロ法における手法の一つで、丸めをランダムに行う。確率的丸めはモンテカルロ演算にも用いられるが、一般的には、等確率で丸めまたは切り捨てを行う方が一般的である。繰り返し実行すると、結果はランダムな分布を示し、計算の安定性を示すことができる。[ 13 ]
整数の定義域と範囲を持つ関数の正確な値を求めるために、丸め演算を使用することができます。例えば、整数n が完全な平方数であることが分かっている場合、その平方根はn を浮動小数点値zに変換し、浮動小数点値を用いてzの近似平方根x を計算し、次にx を最も近い整数yに丸めることで計算できます。n がそれほど大きくない場合、浮動小数点値のxの丸め誤差は0.5未満となるため、丸められた値y はnの正確な平方根となります。これが、計算尺が正確な計算に使用できる 理由です。
数値を異なる精度レベルに2回連続して丸め、後者の精度の方が粗い場合、方向付けされた丸めの場合を除き、最終的な精度に1回丸める場合と同じ結果になることは保証されません。[注2 ]例えば、9.46を最も近い小数点第2位に丸めると9.5になり、次に偶数への丸めを使用して最も近い整数に丸めると10になりますが、同じ方法を使用して直接丸めると9になります。BormanとChatfield [ 14 ]は、小数点第1位に丸められたデータを整数を使用して表現された仕様限界と比較する場合の二重丸めの影響について説明しています。
1995年から1997年にかけて行われたマルティネス対オールステート事件およびセンデホ対ファーマーズ事件において、保険会社は保険料の二重切り上げは許容され、実際には義務付けられていると主張しました。米国裁判所は保険会社に不利な判決を下し、単一切り上げを確実に行うための規則を採用するよう命じました。[ 15 ]
一部のコンピュータ言語およびIEEE 754-2008規格では、単純な計算では結果を2回丸めてはならないと規定されています。これはJavaにおいて特に問題となっており、Javaは異なるマシン上でも全く同じ動作をするように設計されているため、x87浮動小数点演算でこれを実現するには特別なプログラミングテクニックを用いる必要がありました。[ 16 ] [ 17 ] Java言語は、差異が問題にならない場合は異なる結果を許容し、結果が正確に一致する必要のある場合はstrictfp修飾子の使用を義務付けるように変更されました。厳密な浮動小数点演算はJava 17で復活しました。[ 18 ]
いくつかのアルゴリズムでは、中間結果はより大きな精度で計算され、その後、最終的な精度に丸められます。中間計算に適切な丸めを選択することで、二重の丸めを回避できます。これは、最終的な丸めで中点に丸めないようにすることです (中点が正確な場合を除く)。2 進演算では、結果をゼロに向かって丸め、丸め結果が不正確な場合は最下位ビットを 1 に設定するという考え方です。この丸めはスティッキー丸めと呼ばれます。[ 19 ]同様に、中間結果が正確に表現できる場合は中間結果を返しますが、そうでない場合は奇数の有効桁を持つ最も近い浮動小数点数を返します。このため、これは奇数への丸めとも呼ばれます。[ 20 ] [ 21 ] 2 進および 10 進演算用のこのアプローチの具体的な実装は、より短い精度に備えるための丸めとして実装されています。
この丸めモードは、複数回の丸め処理後に誤った結果が生じる可能性を回避するために使用されます。これは、最後の丸め処理を除くすべての丸め処理を、より短い精度のための丸め処理(「RPSP」)を使用して実行し、最後の丸め処理のみに外部から要求されたモードを使用することで実現できます。
10進演算では、入力が正確に表現できない場合、最終桁の0と5は回避されます。最下位桁が0または1、4または5、5または6、9または0のいずれかを選択できる場合は、0または5以外の桁が選択されます。それ以外の場合は、選択は任意です。IBMは、後者の場合、より小さい桁の桁が選択されると定義しています。[ 22 ] [ 23 ] RPSPは、2回の連続する丸めの間のステップが1桁だけ小さい場合でも適用できます(たとえば、1/100に丸めた後、1/10に丸めることができます)。たとえば、整数に丸める場合、
「二重丸め」セクションの例では、9.46 を小数点 1 位に丸めると 9.4 になり、これを整数に丸めると 9 になります。
2進数演算では、この丸めは「奇数への丸め」とも呼ばれます(「半分を奇数に丸める」と混同しないでください)。例えば、1/4(2進数では0.01)に丸める場合、
2進演算で正しい結果を得るには、各四捨五入ステップで少なくとも2桁の2進数を取り除かなければなりません。そうでないと、間違った結果が出る可能性があります。例えば、
誤った中間ステップが削除されると、最終的な整数への丸めにより 3.25 が正しい値 3 に丸められます。
RPSPはIBM zSeriesおよびpSeriesのハードウェアに実装されています。Pythonモジュール「Decimal」、Tclモジュール「math」、Haskellパッケージ「decimal-arithmetic」、その他では、このモードはROUND_05UPまたはround05upと呼ばれています。
ウィリアム・M・カーハンは、超越関数を丸める際のコストが不明であることから、「テーブル作成者のジレンマ」という用語を作り出した。
オーバーフロー/アンダーフローしない2つの浮動小数点引数ごとにy w を正しく丸める計算コストがどれだけかかるかは誰にも分かりません。信頼できる数学ライブラリは、基本的な超越関数をほとんどの場合、1 ulpの半分強、ほとんどの場合1 ulp以内で計算します。なぜy wをSQRTのように1 ulpの半分以内に丸めることができないのでしょうか?それは、どれだけの計算コストがかかるか誰も知らないからです…。超越式を計算し、それを事前に割り当てられた桁数に正しく丸めるために、何桁の追加桁が必要になるかを予測する一般的な方法は存在しません。有限個の追加桁で最終的に十分であるという事実(もし真実であれば)でさえ、深い定理となるかもしれません。[ 24 ]
IEEE 754浮動小数点規格では、加算、減算、乗算、除算、積和演算、平方根演算、浮動小数点剰余演算において、無限精度演算の正しい丸め結果が得られることが保証されています。1985年規格では、より複雑な関数についてはこのような保証はなく、それらの精度はせいぜい最終ビット以内に限られていました。しかし、2008年規格では、準拠実装において、有効な丸めモードを尊重した正しい丸め結果が得られることが保証されています。ただし、関数の実装は任意です。
ゲルフォンド・シュナイダーの定理とリンデマン・ワイエルシュトラスの定理を用いると、標準的な基本関数の多くは、いくつかのよく知られた引数を除いて、超越的な結果を返すことが証明できるため、理論的な観点からは、そのような関数を正しく丸めることは常に可能です。しかし、そのような関数の実装では、正しく丸められた結果を保証する前に、所定の精度に対してどの程度の精度の結果を計算する必要があるかの制限を決定すると、多くの計算時間が必要になったり、達成できない場合があります。[ 25 ]実際には、この制限が不明な場合(または非常に大きな境界しかわかっていない場合)、実装で何らかの決定を行う必要があります(以下を参照)。ただし、確率モデルによれば、ターゲット形式の桁数の2倍に小さな定数を加えた値までの中間精度を使用すると、非常に高い確率で正しい丸めが満たされます(特殊なケースを考慮に入れた後)。
いくつかのプログラミングパッケージは正しい丸め機能を提供します。GNU MPFRパッケージは、正しく丸められた任意精度の結果を提供します。他のライブラリの中には、IEEE 754倍精度(binary64)で正しい丸め機能を備えた基本関数を実装しているものもあります。
計算桁数に関係なく、丸められた値が決して決定できない計算可能数が存在します。具体的な例を挙げることはできませんが、これは停止問題の決定不能性から生じます。たとえば、ゴールドバッハの予想が正しいが証明できない場合、次の値nを次の整数に丸めた場合の結果は決定できません。つまり、 n =1+10 − k(ただしkは 4 より大きい最初の偶数で、2 つの素数の和ではない)か、そのような数がない場合はn =1 のいずれかになります。そのような数k が存在する場合は丸められた結果は 2 になり、そうでない場合は 1 になります。ただし、予想が証明できない場合でも、丸め前の値は任意の精度で近似できます。
丸めは、数値の文字列検索に悪影響を与える可能性があります。例えば、πを4桁に丸めると「3.1416」になりますが、この文字列を単純に検索しても、「3.14159」や、πを4桁以上に丸めた他の値は見つかりません。一方、切り捨ての場合はこの問題は発生しません。例えば、πを4桁に丸めた「3.1415」を単純に文字列検索すると、 πを4桁以上に丸めた 値が見つかります。
四捨五入の概念は非常に古く、おそらく除算の概念自体よりも古いと言えるでしょう。メソポタミアで発見された古代の粘土板には、60進法の逆数と平方根の丸められた値が記された表が含まれています。 [ 41 ]円周率、年の長さ、月の長さの 丸められた近似値も古くから存在しています。60進法の例を参照してください。
1940年以来、丸め半偶数法はアメリカ規格Z25.1およびASTM規格E-29として採用されています。 [ 42 ]偏りのない丸めと統計学者の丸めという用語の由来は、かなり自明です。1906年の『確率と誤差理論』第4版で、ロバート・シンプソン・ウッドワードはこれを「コンピュータのルール」と呼びました。 [ 43 ]これは、当時、数学の表を計算する人間のコンピュータによって一般的に使用されていたことを示しています。例えば、サイモン・ニューカムが1882年頃に著した『対数とその他の数学表』では、このルールが推奨されています。[ 44 ]ルシウス・タトルが1916年に著した『計測理論』では、このルールは物理的な測定値を記録するための「普遍的に採用されたルール」と呼ばれています。[ 45 ]チャーチル・アイゼンハートは、この方法が1940年代までにデータ分析において既に「確立」されていたと指摘しました。[ 46 ]
「銀行家の丸め」という用語の起源は依然として不明瞭です。仮にこの丸め方法が銀行業務において標準的なものであったとしても、その証拠を見つけるのは極めて困難です。それどころか、欧州委員会の報告書「ユーロ導入と通貨金額の丸め」[ 47 ]の第2節では、銀行業務において丸めの標準的な方法がこれまで存在しなかったことが示唆されており、「中間」の金額は切り上げるべきであると明記されています。
1980年代まで、浮動小数点演算で使用される丸め方法は、通常ハードウェアによって固定されており、ドキュメントが不十分で、一貫性がなく、コンピュータのブランドやモデルごとに異なっていました。この状況は、IEEE 754浮動小数点規格がほとんどのコンピュータメーカーに採用されたことで変わりました。この規格では、ユーザーが複数の丸めモードを選択でき、それぞれの場合において結果の丸め方法を正確に指定できます。これらの機能により、数値計算はより予測可能になり、マシンに依存しなくなり、区間演算の効率的で一貫性のある実装が可能になりました。
現在、多くの研究は5倍または2倍に丸める傾向があります。例えば、ヨルク・バテンは、古代人の算数能力を評価するために、多くの研究で年齢重ね算法を用いています。彼はABCC指数を考案し、これにより、人口識字率を測定した歴史的資料がなくても、地域間の算数能力の比較が可能になりました。[ 48 ]
ほとんどのプログラミング言語は、小数を様々な方法で丸めるための関数や特殊な構文を提供しています。FortranやCなどの初期の数値言語では、通常は切り捨て(ゼロ方向への切り捨て)という1つの方法しか提供されていませんでした。このデフォルトの方法は、小数を整数変数に代入する場合や、小数を配列のインデックスとして使用する場合など、特定の状況では暗黙的に使用されます。その他の丸め方法は明示的にプログラムする必要がありました。例えば、正の数を最も近い整数に丸めるには、0.5を加算して切り捨てることで実装できます。
しかし、ここ数十年で、ほとんどの言語の構文と標準ライブラリは、一般的に少なくとも 4 つの基本的な丸め関数 (切り上げ、切り下げ、最も近い値、ゼロ方向) を提供するようになりました。同点決着の方法は、言語とバージョンによって異なる場合があり、プログラマが選択できる場合もあります。いくつかの言語は IEEE 754 浮動小数点標準に倣い、これらの関数を、倍精度浮動小数点引数を受け取り、同じ型の結果を返すように定義しています。その結果は、必要に応じて整数に変換できます。浮動小数点型の範囲は整数型よりも広いため、このアプローチにより、不要なオーバーフローを回避できます。PHPなどの一部の言語では、値を指定された小数点以下の桁数 (例: 4321.5678 から 4321.57 または 4300) に丸める関数が提供されています。さらに、多くの言語ではprintfまたは同様の文字列フォーマット関数が提供されており、これを使用すると、小数を、ユーザーが指定した小数点以下の桁数 (精度) に丸めた文字列に変換できます。一方、切り捨て(ゼロへの丸め)は、特に 2 つの整数値の除算の場合に、多くの言語で使用されるデフォルトの丸め方法です。
対照的に、CSSとSVGは数値や測定値の最大精度を特に定義しておらず、 DOMとIDLインターフェースでは無限精度を持つ文字列として扱われ、公開され、整数と浮動小数点値を区別しません。ただし、これらの言語の実装では通常、計算された数字を限られた精度で公開する前に、これらの数値をIEEE 754倍精度浮動小数点値に変換します(特に標準のJavaScriptまたはECMAScript [ 49 ]インターフェースバインディング内)。
一部の分野または機関では、丸めに関する標準または指示を発行しています。
1966年半ばに発行されたガイドライン[ 50 ]において、米国連邦気象調整官事務所は、気象データは最も近い端数に丸め、「端数を切り上げる」というタイブレークルールを適用することを決定しました。例えば、1.5を整数に丸めると2になり、-1.5は-1になります。それ以前のタイブレークルールは、「0から半分だけ離れた値に丸める」というものでした。
気象学者の中には、0.0度から-0.5度(含まない)までの気温を整数に丸めた値を示すために「-0」と書く人もいます。この表記法は、気温がどんなに小さくても負の符号が重要だと考えられる場合に用いられます。例えば、摂氏温度で気温を丸める場合、零下は氷点下を表します。
最も近い偶数に丸めることは、銀行もこの手法を使用しているため、「銀行型丸め」とも呼ばれます。Microsoft Pascal コンパイラ、MS-DOS オペレーティング システム ユーザーズ ガイド。Microsoft Corporation。1985 年。165ページ。
銀行型丸めは、末尾が .5 の実数を切り捨てるときに使用されます。つまり、奇数は偶数に切り上げられ、偶数は偶数に切り捨てられます。
n
が偶数の場合の誤差1/2に関する重要な事実は
、その符号が任意であり、他のすべての誤差の場合のように計算によって固定されないことです。しかし、補間値の最後の丸められた数字が、単位の半分を割り切る場合でも偶数になるというコンピュータのルールは、長期的にはこの誤差がプラスとマイナスの両方の頻度で発生することになります。
ここでは、奇数の半分が必要な場合があります。[...] このような場合に採用する良い規則は、
最も近い偶数を書き込む
こと
です
。
明らかに半分より小さい分数は切り捨て、半分より大きい分数は常に1単位分として扱うべきですが、どちらの数字が近いか不明な場合は、最も近く、かつ奇数よりも
偶数を記録する
のが一般的です。この手順が採用されている理由は、同じ量の測定を複数回連続して行う場合、記録が大きすぎる場合と小さすぎる場合とで記録が同程度に発生する可能性があるためです。そのため、複数の値を平均しても、誤差はごくわずかか、あるいは全く発生しないでしょう。