(完了)IEEE 浮動小数点エラーを理解するチュートリアル

サポートが終了した KB の内容についての免責事項

この記事は、マイクロソフトがサポートを提供しなくなった製品について記述しています。 したがって、この記事は「現状のまま」で提供され、更新されることはありません。

概要

浮動小数点の計算は、多くのプログラマが混乱する複雑なトピックです。以下のチュートリアルは、浮動小数点エラーが発生する可能性がプログラミングの状況とその回避方法を認識するのに役立ちます。実際のコンパイラのバグではなく、固有の浮動小数点演算の制限が原因で発生するケースを認識することでく必要があります。

詳細

10 進数とバイナリ番号システム

通常、底 10 のものをカウントします。情報は完全に任意です。人が底 10 を使用して従来の唯一の理由は、棚卸の便利なツールになっている、10 本の指であります。


10 進数 (基数 10) で番号 532.25 は、以下を意味します。

   (5 * 10^2) + (3 * 10^1) + (2 * 10^0) + (2 * 10^-1) + (5 * 10^-2)
500 + 30 + 2 + 2/10 + 5/100
_________
= 532.25


バイナリ番号システム (2) では、各列は、10 ではなく 2 の累乗を表します。たとえば、数 101.01 は、次を意味します。

   (1 * 2^2) + (0 * 2^1) + (1 * 2^0) + (0 * 2^-1) + (1 * 2^-2)
4 + 0 + 1 + 0 + 1/4
_________
= 5.25 Decimal


Pc で整数を表現する方法

整数に小数部がないため、そのコンピューターの表現は浮動小数点値の方がよりもはるかに簡単に。パーソナル コンピューター (Pc) での通常の整数は、符号を示す最上位ビットを 2 バイト (16 ビット)。長整数型は、4 バイト長です。正の値は、単純なバイナリ番号です。次に例を示します。

    1 Decimal = 1 Binary
2 Decimal = 10 Binary
22 Decimal = 10110 Binary, etc.


ただし、負の整数は、2 の補数スキームを使用して表されます。2 の補数表現の負の数を取得するには、数値の絶対値のバイナリ表現を行うとすべてのビットを反転し、1 を追加します。次に例を示します。

   4 Decimal = 0000 0000 0000 0100
1111 1111 1111 1011 Flip the Bits
-4 = 1111 1111 1111 1100 Add 1


-1 に注意してください 10 進数 = Basic が論理 true として-1 を処理する理由を説明する 2 進法で、1111 1111 1111 1111 (すべてのビット = 1)。これは、ない別の演算子とビットごとの論理比較の結果です。多くの場合 Basic では、ときにプログラムを行う多くの論理比較の下のコードを使用すると便利です。これにより、読みやすさが大幅に支援します。

   CONST TRUE = -1
CONST FALSE = NOT TRUE


メモの 2 つの任意の組み合わせを追加することによって通常のバイナリ算術演算子を使用して数値を補完するには、正しい結果が生成されます。

浮動小数点の複雑さ

すべて 10 進の整数は、バイナリ整数で正確に表現します。ただし、これは小数値の場合は true ではありません。実際には、10 進で合理的ではないすべての番号もされません、基数が 10 より小さいと、システムの合理性のあります。


バイナリ、具体的には、のみ小数、フォーム p と q、q が 2 の整数乗をで表すことができる正確に表せる、有限数のビットを持つ。


0.0001 の 10 進数などの一般的なもの小数は、バイナリで正確に表示できません。(0.0001 は 104 ビットのピリオドで繰り返しバイナリ分数です)


理由は単純な例では、次のようにこれについて説明します。

   SUM = 0
FOR I% = 1 TO 10000
SUM = SUM + 0.0001
NEXT I%
PRINT SUM ' Theoretically = 1.0.


として 1.000054 を印刷出力します。0.0001 を 2 進法で表現するうえで小さなエラーは、合計値に反映されます。


同じ理由で、常に注意が必要非常に実際の数値の比較を行う場合。次の使用例は、一般的なプログラミング エラーを示しています。

   item1# = 69.82#
item2# = 69.20# + 0.62#
IF item1# = item2# then print "Equality!"


これは、印刷できない」等値!「69.82 (バイナリ) では若干異なることへ代入結果値を、バイナリで正確に表現できないため、式から生成される値よりもします。実際には、常にいくつかのトレランスを許可するようにこのような比較をコーディングする必要があります。次に例を示します。

   IF (item1# < 69.83#) AND (item1# > 69.81#) then print "Equal"


「等しい」を印刷します。

IEEE 形式番号

QuickBasic の MS-DOS では、バージョン 3.0 には、MBF (マイクロソフトのバイナリ浮動小数点) のバージョンと、数値演算コプロセッサを持つコンピューターの IEEE (米国電気および電子工学のエンジニア) バージョンが同梱されています。MS-DOS 用の QuickBasic、バージョン 4.0 以降では IEEE のみ使用します。マイクロソフトでは、次の 3 つの主な理由の現在のバージョンの基本的な浮動小数点の値を表すための IEEE 規格を選択します。

  1. IEEE 形式を使用して、数値演算コプロセッサ インテルを使用する基本をできるようにします。Intel 80 x 87 シリーズのコプロセッサは、マイクロソフトのバイナリ形式の数値で使用できません。
  2. Interlanguage の Basic、C、Pascal、FORTRAN、および MASM の間での呼び出しを簡単にするには。それ以外の場合、変換ルーチンは、数値型の値を送信する 1 つの言語を使用する必要があります。
  3. 一貫性を持たせます。IEEE は、C と FORTRAN コンパイラの標準的な受け入れられている業界です。
倍精度の IEEE と MBF の表現を簡単に比較を次に示します。

               Sign Bits   Exponent Bits   Mantissa Bits
--------- ------------- -------------
IEEE 1 11 52 + 1 (Implied)
MBF 1 8 56


IEEE と MBF 浮動小数点表現、クエリで、マイクロソフト サポート技術情報の次の単語の違いの詳細については。

   IEEE and floating and point and appnote


IEEE に専用の広い範囲の値を表すには、指数部をより多くのビットがあることに注意してください。MBF の幅の狭い範囲内でより正確にできるように複数の仮数部のビットがあります。

一般的な浮動小数点数の概念

バイナリ浮動小数点システムが有限数の正確な形式の浮動小数点値のみを表すことを認識する非常に重要です。その他のすべての値は、最も近い表現可能な値で近似する必要があります。IEEE 規格では、「最も近い」の表現可能な値に値を丸める方法を指定します。MS-DOS 用の QuickBasic は、標準をサポートし、IEEE の規則に従って丸めます。


また、IEEE で表すことができる数値が非常に広い範囲に広がっていることに注意してください。番号の行に、それらを想像してくださいことができます。1.0、-1.0 に近い表現可能な数値の高密度があるが、0 または無限大の方向へ移動すると数が少ないとします。


計算の技術のように設計は、IEEE 規格の目的は、正確性を最大化する (取得する限り、実際に近い数値)。有効桁数は、表現する桁数を意味します。標準の IEEE は、数値の小数部の精度と許容範囲内での精度の両方を保持するために使用するビットの数と指数部に専用のビット数のバランスを取るしようとします。

IEEE の詳細

浮動小数点数は、[指数] の 2 進の指数は、次の形式で表されます。

   X =  Fraction * 2^(exponent - bias)


[分数] は、先頭のビットが 1 では常にあるので、指数が調整するために正規化された番号の正規化小数部分です。この方法では、必要はありませんが保存され、し、精度の 1 つ以上のビットを取得します。これは、黙示的な理由です。考えることができますこの、科学的表記法のようなバイナリ形式を除く、小数点の左側に 1 桁の数字に指数を操作する最初のビットは 1, 1 と 0 のみがあるように常に指数を操作できます。


[バイアス] は、負の指数を格納することを避けるために使用するバイアス値です。


バイアスは、単精度の数値は、127、倍精度の数値 (10 進) 1023 です。


値がすべて 0 に等しいし、すべて 1 (バイナリ) は、特殊なケースを表現するために予約されています。その他の特殊なケースも、さまざまなエラー状態を示すにはあります。

単精度の例

2 = 1 * 2 ^1 = 0100 0000 0000 0000.0000 0000 = 4000 0000 の 16 進数
注意してください符号のビット 0、格納された指数は、128、または 100 0000 1 を加えた 127 は、2 進法で 0 です。格納された仮数 (1.) 000 0000.0000 0000 であり、黙示的な業界をリードする 1 およびバイナリ ポイント、ので、実際の仮数は 1。

-2 =-1 * 2 ^1 = 1100 0000 0000 0000.0000 0000 は = C000 0000 の 16 進数
符号ビットが設定されている点を除いて、-2 の場合も同じです。これは、すべての IEEE 形式の浮動小数点数に当てはまります。

4 = 1 * 2 ^2 = 0100 0000 1000 0000.0000 0000 = 4080 0000 の 16 進数
同じ仮数部、指数部が 1 つ増加 (129、またはバイナリ形式の 100 0000 1 は、バイアスをかけた値です。

6 = 1.5 * 2 ^2 = 0100 0000 1100 0000.0000 0000 40C 0 0000 の = 16 進数
指数は同じ、仮数部半分でより大きいです--ことは (1) 100 0000.バイナリ分数は、これ以降は、1-1/2 0000 0000、(小数部の桁の値は 1/2、1/4、1/8 などです。)。

1 = 1 * 2 ^0 = 0011 1111 1000 0000.0000 0000 = 3F80 0000 の 16 進数
2 の他の累乗として同じ指数は、仮数部は、127、または 011 1111 1 に 2 つより 1 小さい値です。

.75 = 1.5 * 2 ^-1 = 0011 1111 0100 0000.0000 0000 = 3F40 0000 の 16 進数
バイアスされた指数は、126、011 1111 0 のバイナリ、仮数は (1) 100 0000.0000 0000 は、1-1/2。

2.5 = 1.25 * 2 ^1 = 0100 0000 0010 0000.0000 0000 = 4020 0000 の 16 進数
いる点を除き、2 と同じ 1/4 を表すビットは設定、仮数部の。

0.1 = 1.6 * 2 ^-4 = 0011 1101 1100 1100.1100 1101 = 3DCC CCCD の 16 進数
1/10 は、バイナリでは反復小数です。仮数 1.6 だけよりは、バイアスされた指数は 1.6 を 16 で割ることの質問 (10 進数の 123 は、2 進法での 011 1101 1 です)。実際の指数は、123-127 = - 4 は、2 * *-4 = 1/16 が乗算する係数であることを意味します。ストアド仮数は最後のビットで丸めに注意してください。これは、表す数をできる限り正確に表現する試みです。(理由その 1/10 と 1 と 100 がバイナリで正確に表現可能な 1/3 は 10 進数で正確に表現する方法に似ています)。

0 = 1.0 * 2 ^-128 = すべて 0 - 特別なケースです。

その他の一般的な浮動小数点エラー

以下は、一般的な浮動小数点エラーです。

  1. 丸め誤差


    2 進数のビットのすべてを計算に使用できない場合、このエラーが発生します。


    例: 0.9900 に 0.0001 (単精度) を追加します。


    0.0001 の 10 進数としてを表されます。
    (1) 10100011011011100010111 * 2^(-14+Bias) (バイナリの先頭の 0 秒 13!)
    0.9900 としてを表されます。
    (1.)11111010111000010100011 * 2^(-1+Bias)
    今すぐにこれらの数値を実際に追加するには、10 進数 (バイナリ) ポイントを配置する必要があります。必要がありますこの Unnormalized。結果の追加です。
           .000000000000011010001101 * 2^0  <- Only 11 of 23 Bits retained
    +.111111010111000010100011 * 2^0
    ________________________________
    .111111010111011100110000 * 2^0


    丸めエラーは、コンピューターによってはラウンド追加するためにシフトするためこの呼び出されます。他のユーザーだけで切り捨てます。丸め誤差が考慮すべき重要な追加または 2 つの非常に異なる値を乗算するときにします。
  2. ほぼ等しい値を引いて 2
           .1235
    -.1234
    _____
    .0001


    これは正規化されます。元番号は、4 つの有効桁数には、結果が 1 つだけの有効桁数に注意してください。
  3. オーバーフローやアンダー フロー


    これは、結果が大きすぎる、またはデータ型で表現するのには小さすぎる場合に発生します。
  4. クオンタイズのエラー


    これは、浮動小数点の標準で正確な形式で表すことができないこれらの番号で発生します。
  5. 非常に小さな数値で除算しました。


    これは「0 除算」エラーが発生することができます。 または次の例のように、不正な結果が得られます。
          A = 112000000
    B = 100000
    C = 0.0009
    X = A - B / C


    ここでは X の MS-DOS 用の QuickBasic、900000 の正しい答えではなく 888887、値を持つファイルです。
  6. 出力エラー


    このエラーは、出力関数は、使用している値を変更するときに発生します。
プロパティ

文書番号:42980 - 最終更新日: 2017/02/01 - リビジョン: 1

フィードバック