web-dev-qa-db-ja.com

コンピュータが小数を2番目の整数として格納しないのはなぜですか?

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

コンピュータが数値の小数部分を別の整数として格納した可能性があるのに、なぜすべての種類の丸め誤差に対処するのですか(したがって正確ですか?)

私が考えることができる唯一のことは、(10進数で)繰り返される小数を扱うことですが、それに対するEdgeソリューションがあった可能性があります(現在、無限にあります)。

25
SomeKittens

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

2進化10進数(BCD)の計算では、コンピューターの処理が10進数で行われます。これに遭遇する理由はめったにありません。これはスペースを浪費するためです。数値の個々の桁には最低4ビットが必要ですが、コンピューターは最大でその空間に16個の値。 (これも遅くなる可能性がありますが、ハードウェアアクセラレーションによるBCD演算が正常に機能する可能性があります。)これは実際、ほとんどの計算機が行うことです。そのため、デスクトップコンピュータで昼食をとる$ 5のカシオに決して当たらないような特定のクラスの丸め問題があります。

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

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

35

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

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

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

Decimal型は、浮動小数点数または固定小数点数とほとんど同じように機能しますが、10進法を想定しています。たとえば、10進数は、仮数を_23456_および指数を_-2_にエンコードでき、これは_234.56_に展開されます。 10進数は、算術がCPUに組み込まれていないため、浮動小数点よりも低速ですが、10進数を含むすべての数値に正確であることが必要な場合に理想的です。スコアボードなど。一部のプログラミング言語には10進数型が組み込まれています(C#など)。その他のプログラミング言語では、それらを実装するためにライブラリが必要です。小数は繰り返しのない小数を正確に表すことができますが、その精度は浮動小数点数の精度よりも優れているわけではないことに注意してください。小数を選択することは、10進法で正確に表すことができる数値の正確な表現を取得することを意味するだけです(フロートが2進分数を正確に表すことができるのと同じように)。

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

[〜#〜] bcd [〜#〜](2進化10進数)は、「ニブル」(4ビットのグループ)を使用して個々の数字をエンコードします。ニブルは16の異なる値を保持できますが、10進数では10しか必要ないため、ニブルごとに6つの「不正な」値があります。小数と同様に、BCD数は小数で正確です。つまり、小数で実行される計算は、ペンと紙を使用した場合と同じように機能します。 BCDの算術ルールはやや不格好ですが、有利な点は、文字列への変換が他のいくつかのフォーマットよりも簡単であることです。これは、組み込みシステムなどの低リソース環境で特に興味深いものです。

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

38
tdammers

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

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

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

6
ddyer

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

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

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

科学的な計算がハードウェアサポートから最も恩恵を受けるものである傾向があるため、ハードウェアでサポートされる傾向があります。一例として、財務計算は他の形式で行われることが多いですが、金融ソフトウェアは通常、必要な形式がソフトウェアでのみサポートされていても、ほとんどの金融ソフトウェアで完全に十分なパフォーマンスを維持できるほど十分な実際の計算を行いません。

1
Jerry Coffin

fixed-point 数値を記述しているようです。

数値の小数部分を別の場所に格納することは、2倍の長さの単一のスペースを作成し、2つの半分に全体と小数部分を格納することとまったく同じであることを覚えておいてください。言い換えれば、それは整数として数値を格納することと同じですが、単に固定数の小数スペースを想定しています。

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

1
tylerl