コンピューターが10進数を2番目の整数として保存しないのはなぜですか?


24

分母が2 ^ xの解以外のものである場合、コンピューターは小数の保存に問題があります。これは、小数の後の最初の桁が1/2の価値があり、2番目の1/4が1/4(または1 /(2 ^ 1)と1 /(2 ^ 2))などの価値があるためです。

コンピューターが数の小数部分を別の整数として格納できたのに、なぜあらゆる種類の丸めエラーに対処するのか(したがって正確ですか?)

私が考えることができる唯一のことは、小数の繰り返し(10を基数とする)を扱うことですが、それに対するエッジソリューションが存在する可能性があります(現在の無限大のように)。


8
float / double型とは対照的に、decimal型の格納方法を調べる必要があります。
Oded

9
それがより正確である方法がわからない。小数点以下の最初の桁は1/10で、2番目の1/100などです。さらに正確な丸め問題が発生するのはどうですか(1/3をどのように表しますか)。唯一の違いは、正確に表現できる値です。
マーティンヨーク

17
10進浮動小数点(これは、2を参照しているものですが、もっと厄介な表現です)は、2進浮動小数点よりも不正確ではありません。唯一の違いは、どの値を表現できないかであり、10進数システムに慣れているため、10進数バージョンのエラーに気づきません。そして、どちらも、すべての有理数と無理数を表すことはできません。

1
結局のところ、それは効率に帰着します。コンピュータはバイナリであり、このバイナリ表現で動作する回路はそれほど複雑ではありません。これの重要性は今日多少低下しているかもしれませんが、これは非常に重要な時期でした。また、コンピューター上に(有限の空間に)数値を保存するために選択した表現は、表現できる値の有限セットを持ち、それらはすべていくつかの入力で丸め誤差を示します。仮数と指数を使用した一般的な浮動小数点形式は、2つの整数を使用した場合よりもはるかに広い範囲を提供します。
ミンダーミンダー

1
浮動小数点の丸めエラーの原因は何ですか?」という質問への回答で参照されいる記事をいくつか読むことを強くお勧めします。参照シリーズの最後の記事の詳細で更新したばかりです。特に、なぜ固定小数点が浮動小数点ブルーを治さないのかを見てください。
マークブース

回答:


35

実際にそれを行う数字のモードがあります。

Binary-coded Decimal(BCD)算術では、10を基数としてコンピューターが動作します。これに遭遇することはめったにありません。スペースを浪費するからです。そのスペースに16個の値。(遅くなることもありますが、ハードウェアアクセラレーションで問題なく動作するBCD数学を使用することは可能です。)これは、実際、ほとんどの計算機が行うこととまったく同じであり、デスクトップコンピューターで昼食を食べる5ドルのカシオでは決して発生しない特定の丸め問題が発生する理由です。

あなたが取ることができる他のルートは、有理数を使用することです-つまり、整数として保存された分子と分母です。これは実際にはほぼすべての言語で利用可能であり、正確であり、すべてをネイティブバイナリ形式で保存できます。問題は、1日の終わりに、ユーザーが463/13や35や8/13のような分数を見たくないことです。彼らは35.615を見たいと思っています...そしてあなたがそこに着いた瞬間、あなたはすべての典型的な問題に直面します。さらに、この形式はさらに多くのスペースを必要とし、浮動小数点演算よりもかなり遅くなる可能性があり、デフォルトではこの形式を使用するコンピューターはありません。

だから:コンピュータはあなたが望むことをすることができますが、それは遅いし、それはスペースを浪費するので、本当に必要なときにだけそれをします。残りの時間、浮動小数点の速度とスペースの節約は、より良いトレードオフです。


BCD段落の4バイト(バイトではない)を意味しませんか?

3
もう1つのオプションは固定小数点演算です。整数は、数値の場合の小数部を表します。たとえば、お金の値の保存(小数またはパーセンテージを含む計算なし)は、1は$ 0.01を表します。
-mattnz

1
@mattnz:True-固定小数点は有理数の特殊なケースです。
ジョンパーディ

素晴らしい、計算機がそれをしたことを知りませんでした。
SomeKittens

3
3番目のオプションがあります。C#は、どのようにのように、小数点の指数で浮動小数点decimal実装されます。stackoverflow.com/a/5019178/174335は、それは小数点以下の桁のない個々の表現がないようBCDではありません、それはポイントを固定していません。
ジョレン

38

小数を格納する方法は多数あり、それぞれに長所と短所があります。

浮動小数点は、間違いなく最も一般的な形式です。これは、符号、仮数、および符号付き2を底とする指数を整数にエンコードし、それらを多数のビットにパックすることによって機能します。たとえば、32ビットの仮数0.5(としてエンコード0x88888888)と32ビットの符号付き指数+30x00000003)を使用して、デコードして4.00.5 * 2 ^ 3)。浮動小数点数はハードウェアに実装されているため高速であり、その精度は絶対サイズでスケーリングされます。つまり、数値が小さいほど絶対精度が高くなり、相対丸め誤差は絶対サイズで一定になります。フロートは、長さ、音圧レベル、光レベルなど、連続領域からサンプリングされた値に優れており、そのため、一般的にオーディオおよび画像処理、統計分析および物理シミュレーションで使用されます。最大の欠点は、正確ではないことです。つまり、丸め誤差が生じやすく、すべての小数を正確に表すことができません。すべての主流のプログラミング言語には、何らかの浮動小数点があります。

固定小数点十分に大きい整数を使用し、小数部のためにビットの一部を暗黙的に予約することにより機能します。たとえば、24.8ビットの固定小数点数では、整数部(符号を含む)に24ビット、小数部に8ビットを予約しています。その数を8ビットだけ右シフトすると、整数部分が得られます。固定小数点数は、ハードウェアの浮動小数点ユニットが一般的でないか、少なくとも対応する整数よりもはるかに遅い場合によく使用されていました。固定小数点数は、正確さの点では多少扱いやすいですが(理由付けが簡単な場合のみ)、他のすべての点で浮動小数点数に劣ります-精度が低く、範囲が狭く、余分なため暗黙のシフトの計算を修正するには演算が必要です。今日の固定小数点演算は、浮動小数点演算よりも遅いことがよくあります。

10進数型は、浮動小数点数または固定小数点数によく似ていますが、10進数システムを想定しています。つまり、指数(暗黙的または明示的)は2の累乗ではなく10の累乗をエンコードします。たとえば、10進数はの仮数23456との指数をエンコードでき、-2これは次のように展開されます234.56。10進数は、算術演算がCPUに組み込まれていないため、浮動小数点よりも低速ですが、10進数を含むすべての場合に理想的であり、明確に定義されたスポットで丸めが発生し、それらの数値が正確である必要があります-財務計算、スコアボードなど。一部のプログラミング言語には10進数型が組み込まれています(C#など)。他のプログラミング言語では、それらを実装するためにライブラリが必要です。小数は繰り返しのない小数を正確に表すことができますが、その精度は浮動小数点数の精度よりも優れているわけではありません。小数を選択するということは、小数システムで正確に表現できる数値の正確な表現を取得することを意味します(floatが2進小数を正確に表現できるように)。

有理数は、分子と分子を格納し、通常、ある種のbignum整数型(コンピューターのメモリ制約が許す限り大きくなる可能性のある数値型)を使用します。これは、1/3またはのような数字を正確にモデル化できる束の中の唯一のデータ型であり、3/17それらに対する操作と同様です-他のデータ型とは異なり、有理数は次のようなものに対して正しい結果を生成します3 * 1/3。数学は非常に簡単ですが、効率的なファクタリングアルゴリズムを考案するのはかなり困難です。一部のプログラミング言語には、合理的な型が組み込まれています(Common Lispなど)。合理性の欠点には、遅いこと(多くの操作で端数の削減とコンポーネントの因数分解が必要)、多くの一般的な操作は実装が困難または不可能であり、ほとんどの実装ではこれが発生すると合理性がフロートに低下します(たとえば、sin()合理的に)。

BCD(Binary Coded Decimal)は、「ニブル」(4ビットのグループ)を使用して個々の数字をエンコードします。ニブルは16個の異なる値を保持できますが、10進数には10個しか必要ないため、ニブルごとに6個の「不正な」値があります。10進数と同様に、BCD番号は10進数とまったく同じです。つまり、10進数で実行される計算は、ペンと紙を使用して行った場合と同じように機能します。BCDの算術規則はやや不格好ですが、長所は、文字列への変換が他の形式の一部よりも簡単であるということです。これは、組み込みシステムのようなリソースの少ない環境で特に興味深いものです。

文字列、はい、普通の古い文字列も、小数を表すために使用できます。技術的には、これはBCDと非常によく似ていますが、明示的な小数点があり、10進数ごとに1バイトを使用します。そのため、この形式は無駄です(256の可能な値のうち11のみが使用されます)が、BCDよりも解析および生成が簡単です。さらに、使用される値はすべて「疑わしくなく」、無害で、プラットフォームに中立であるため、文字列エンコードされた数値は問題なくネットワーク上を移動できます。文字列に対して直接行われている算術演算を見つけることは一般的ではありませんが、可能ですが、実行すると、他の10進形式(10進およびBCD)と同じように10進正確になります。


固定小数点表現には仮数が含まれないため、32ビット固定小数点は32ビット浮動小数点よりも正確です。
ハン

4
@han:格納する数値のサイズに依存します。浮動小数点数は(大体)数値の大きさに関係なく同じ精度を提供しますが、固定小数点は、格納する数値がその範囲に完全に適合する場合にのみ完全な精度を提供します。
レオ

@han必ずしもではありませんが、両方とも2 ^ 32個の異なる値を表すことができます。提示される情報に関係なく、伝達される情報の量は同じです。ただし、範囲と精度は密接に関係しているため、特定の範囲では固定小数点演算がより正確になる可能性があります。使用できる制限がわかっている場合、厄介なランダムな丸めの問題を回避します。
zxcdw

@han:同じ精度(またはほぼ)を持っています。違いは、固定小数点数の場合、精度(1つの数値から後続の離散ステップのサイズなど)は整数と同様に一定であるのに対して、浮動小数点数では絶対値でほぼ線形に増加することです-浮動小数点数数値1.0は、数値10,000,000.0よりも精度が高い(およそ100万倍)。
-tdammers

6

浮動小数点数は広大な範囲の値を表します。これは、値が事前にわからない場合に非常に役立ちますが、妥協点です。1/10 ^ 100を2番目の整数で表現しても機能しません。

一部の言語(および一部のライブラリ)には他の特性があります。Lispは伝統的に無限精度の整数を持っています。Cobolには、固定小数点の10進数による計算があります。

問題のあるドメインに適した番号表現を選択する必要があります。


1

固定小数点数を記述しているように聞こえます。

数値の小数部分を別の場所に保存することは、2倍の長さの単一のスペースを作成し、2つの別々の半分に小数部分全体を保存することとまったく同じです。つまり、数値を整数として保存することと同じですが、小数点以下のスペースの固定数を単純に仮定します。

通常、重要なのは有効数字であるため、浮動小数点数は科学表記法のバイナリバリエーションを使用して保存されます。他にも多くの方法があります。固定小数点の10進数は、たとえば通貨の値を保存するために一般的に使用されます。この場合、精度は特定の整数位までは重要ですが、必要な10進数の桁数は変化しません。


1

これはBCDと呼ばれますが、本当に必要な場合は引き続き使用できると思います。ただし、次のような価値はありません。

  1. 64ビット浮動小数点で丸めエラーが発生することはほとんどありません
  2. 算術演算が複雑で非効率的になります
  3. 4ビットごとに6つの値を無駄にします

BCD数学は、初期の8ビットマイクロプロセッサシステムで多く使用されていました。実際、人気のあるマイクロプロセッサー(6502)では、BCDでの加算と減算は、バイナリーと同じようにバイトごとに高速です。ビデオゲームでは、スコアを保持するためにBCD数学が頻繁に使用されました。1,000,000ポイントでラップするスコアには特別な処理はありません。代わりに、「99 99 99」に1を追加すると、「00 00 00」とキャリーが無視されます。BCDでスコアを追加する際の余分なオーバーヘッドは、バイナリ値を表示可能な形式に変換するコストと比較するとごくわずかです。
supercat

1

簡単な答えは、浮動小数点は科学計算用に設計されたということです。指定された有効桁数(最大)の数値を格納できます。これは、ほとんどの科学計算での精度の測定方法と密接に適合します。

科学的な計算がハードウェアサポートから最も利益を得るものである傾向があるため、それは主にハードウェアでサポートされる傾向があります。たとえば、金融計算は他の形式で行われることがよくありますが、金融ソフトウェアは通常、実際の計算をほとんど行わないため、必要な形式はソフトウェアでのみサポートされていますが、ほとんどの金融ソフトウェアではパフォーマンスが完全に適切なままです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.