Excel で浮動小数点演算の結果が正しくない場合がある

文書翻訳 文書翻訳
文書番号: 78113 - 対象製品
この記事は、以前は次の ID で公開されていました: JP78113
すべて展開する | すべて折りたたむ

目次

概要

この資料では、Microsoft Excel での浮動小数点数の格納方法および計算方法について説明します。丸めやデータの切り捨てに伴って、一部の数値または数式の結果に影響が及ぶ場合があります。

概要

Microsoft Excel では、浮動小数点数の格納および計算は、IEEE 754 の規格に沿って設計されています。IEEE とは、Institute of Electrical and Electronics Engineers の略で、コンピューターのソフトウェアおよびハードウェアの標準規格を策定している国際的な団体です。IEEE 754 規格は、2 進コンピューターでの浮動小数点数の格納方法について定めたもので、きわめて広く採用されています。この規格が広く利用されているのは、浮動小数点数を適度な容量の領域に格納でき、計算を比較的高速に実行できるという理由からです。IEEE 754 規格は、Intel、Motorola、Sun の各プロセッサや MIPS プロセッサなど、浮動小数点演算を実装する今日の PC ベースのマイクロプロセッサほぼすべてにおいて、浮動小数点ユニットおよび数値データ プロセッサで使用されています。

数値を格納するときには、すべての数や分数が、対応する 2 進数で表現されます。たとえば、1/10 という分数は、10 進法では 0.1 と表現できるのに対し、同じ数を 2 進数で表現すると、次のような循環 2 進数になります。
0001100110011100110011 (以下繰り返し)
この数値は、上記のように無限に繰り返され、有限量の領域では表現できません。したがって、この数値が格納されるときには、約 -2.8E-17 で丸められます。

しかし、IEEE 754 規格には若干の制約があります。大きく分けると、次の 3 つの制約です。
  • 最大/最小の制限
  • 精度
  • 循環 2 進数

詳細

最大/最小の制限

処理できる数の最大値と最小値は、どのコンピューターにも必ずあります。数値が格納されるメモリのビット数は有限であるため、格納できる最大値または最小値も有限です。Excel の場合、格納できる最大値は 1.79769313486232E+308、格納できる正の最小値は 2.2250738585072E-308 です。

IEEE 754 に準拠している部分

  • アンダーフロー: アンダーフローは、生成された数値が小さすぎて表現できない場合に発生します。IEEE でも Excel でも、その結果は 0 です (ただし、IEEE には -0 の概念があるのに対し、Excel にはありません)。
  • オーバーフロー: オーバーフローは、数値が大きすぎて表現できない場合に発生します。この場合、Excel では、独自の特別な表現 (#NUM!) を使用します。

IEEE 754 に準拠していない部分

  • 非正規化数: 非正規化数は指数 0 で示されます。その場合には、数値全体が仮数に格納され、この仮数には先頭の暗黙の 1 はありません。この結果、精度が下がります。そして、数値が小さくなるほど、精度はさらに下がります。この範囲で最も小さい方の値には、1 桁の精度しかありません。
    例: 正規化数では、先頭に暗黙の 1 があります。仮数が 0011001 と表現される場合、正規化数は、先頭にある暗黙の 1 によって、10011001 となります。一方、非正規化数では、先頭に暗黙の 1 がないため、非正規化数は変わらず 0011001 となります。この場合、正規化数の精度は 8 桁 (10011001) であるのに対し、非正規化数の精度は 5 桁 (11001) で、先頭のゼロは意味のない桁となります。

    非正規化数は基本的に、通常の下限値より小さい数値を格納できるようにするための代替手段です。これは規格のオプション部分で、マイクロソフトはこれを実装していません。非正規化数は、その本質上、精度が可変であるためです。この結果、計算に有意の誤差が入り込む可能性があります。
  • 正の無限大/負の無限大: 無限大は 0 による除算で発生します。Excel では無限大はサポートされていません。0 による除算の場合は、代わりに #DIV/0! エラーになります。
  • 非数 (NaN): NaN は、無効な演算 (たとえば、無限大/無限大、無限大 - 無限大、-1 の平方根など) を表す目的で使用されます。NaN を使用すると、無効な演算の後もプログラムが処理を続行できます。Excel では、NaN の代わりに、#NUM! や #DIV/0! などのエラーが直ちに生成されます。

精度

浮動小数点数は、65 ビットの範囲内に 2 進数で格納され、符号、指数、および仮数という 3 つの部分に分かれています。
元に戻す全体を表示する
符号 1 ビット指数 11 ビット暗黙 1 ビット仮数 52 ビット
符号部には数値の符号 (正または負) が格納され、指数部には数値に掛ける 2 の累乗を示す値が格納され (2 の最大の累乗は +1,023、最小の累乗は -1,022)、仮数部には実際の数値が格納されます。仮数の格納領域は有限であるため、隣り合った浮動小数点数どうしの差の小ささ (つまり精度) には限度があります。

仮数と指数はそれぞれ別個の構成要素として格納されます。この結果、扱う対象の数値 (仮数) のサイズに応じて、取り得る精度に幅が生じる可能性があります。Excel の場合、格納できる数値は 1.79769313486232E308 〜 2.2250738585072E-308 ですが、15 桁の精度の範囲内でのみ表現できます。この制限は、IEEE 754 規格に厳密に従ったことの直接的な結果によるものであり、Excel の制限ではありません。このレベルの精度は、他のスプレッドシート プログラムでも同様に見られます。

浮動小数点数は次の形式で表現されます。exponent は 2 進指数です。
X = Fraction * 2^(exponent - bias)
Fraction は正規化された数値の小数部分です。正規化するのは、先頭ビットが常に 1 になるように指数が調整されているためです。こうすると、先頭ビットは格納の必要がなくなり、精度が 1 ビット増えます。暗黙ビットが存在するのはこのためです。これは、科学的記数法の指数表記において、小数点の左側が 1 桁となるように指数を操作するのと同様です。ただし、2 進数の場合は、1 と 0 しかないため、先頭ビットが 1 となるように指数を操作することは常に可能です。

Bias は、負の指数を格納する必要性を避けるために使用するバイアス値です。バイアスは、単精度の数値では 127、倍精度の数値では 1,023 (10 進) です。Excel では、数値は倍精度で格納されます。

非常に大きな数値の使用例

新しいブックに次のように入力します。
A1: 1.2E+200
B1: 1E+100
C1: =A1+B1
セル C1 の結果は 1.2E+200 という値になります。セル A1 と同じ値です。実際に、IF 関数を使用して、セル A1 と C1 を、たとえば IF(A1=C1) のように比較すると、結果は TRUE になります。これは、15 桁の精度で格納するという IEEE の仕様によるものです。上記の計算を格納できるようにするには、少なくとも 100 桁の精度が必要になります。

非常に小さな数値の使用例

新しいブックに次のように入力します。
A1:  0.000123456789012345
B1:  1
C1: =A1+B1
セル C1 の結果は、1.000123456789012345 ではなく、1.00012345678901 という値になります。これは、15 桁の精度で格納するという IEEE の仕様によるものです。上記の計算を格納できるようにするには、少なくとも 19 桁の精度が必要になります。

精度の誤差を修正する

Excel には、丸め誤差を補正するための基本的な方法が 2 つ用意されています。1 つは ROUND 関数、もう 1 つはブックの [表示桁数で計算する] オプションです。

方法 1: ROUND 関数

次の例では、先ほどのデータを使用し、ROUND 関数で数値を強制的に 5 桁にしています。このようにすることにより、結果を他の値と正しく比較することができます。
A1: 1.2E+200
B1: 1E+100
C1: =ROUND(A1+B1,5)
結果は 1.2E+200 になります。
D1: =IF(C1=1.2E+200, TRUE, FALSE)
結果は値 TRUE になります。

方法 2: 表示桁数で計算

場合によっては、[表示桁数で計算する] オプションを使用して、丸め誤差による影響を回避できる場合があります。このオプションを使用すると、ワークシートの各数値が、表示されている値に強制的に変更されます。このオプションを有効にするには、次の手順を実行します。
  1. Excel 2003 以前のバージョンでは、[ツール] メニューの [オプション] をクリックします。
  2. [計算方法] タブの [表示桁数で計算する] チェック ボックスをオンにします。
  1. Excel 2007 では、Microsoft Office ボタンをクリックし、[Excel のオプション]、[詳細設定] を順にクリックします。
  2. [次のブックを計算するとき] セクションで目的のブックを選択し、[表示桁数で計算する] チェック ボックスをオンにします。
  1. Excel 2013 および 2010 では、[ファイル]、[オプション]、[詳細設定] カテゴリを順にクリックします。
  2. [次のブックを計算するとき] セクションで目的のブックを選択し、[表示桁数で計算する] チェック ボックスをオンにします。

たとえば、小数点以下の桁数が 2 桁の表示形式を選択した後で、[表示桁数で計算] オプションを有効にした場合、ブックを保存するときに、小数 3 桁目以降の正確さがすべて失われます。このオプションは、すべてのワークシートを含む、アクティブなブックに影響します。このオプションを元に戻しても、失われたデータは復元できません。このオプションを有効にする前に、ブックを保存することをお勧めします。

循環 2 進数および結果がゼロに近い計算

2 進数での浮動小数点数の格納には、混乱を招く問題がもう 1 つあります。10 進数では繰り返しのない有限の値として表現されるのに、2 進数では無限に繰り返される数値として表現される場合があるということです。典型的な例が、値 0.1 やその類例です。これらの数値は、基数 10 ではきちんと表現されますが、2 進数で表現すると、仮数に格納したときに次のような循環 2 進数となります。
000110011001100110011 (以下繰り返し)
IEEE 754 規格では、どのような数値に対しても、特別な規定はありません。仮数に格納できる分が格納され、残りは切り捨てられます。この結果、格納時には、約 -2.8E-17 (0.000000000000000028) という誤差が生じます。

0.0001 のような、10 進ではごく普通の小数でも、2 進数では正確に表現できません (0.0001 は周期 104 ビットの循環 2 進小数です)。これは、分数 1/3 を 10 進数では正確に表現できない (0.33333333333333333333 という循環小数になる) のと似ています。

Microsoft Visual Basic for Applications による、次の簡単な例を見てください。
Sub Main()
MySum = 0
For I% = 1 To 10000
MySum = MySum + 0.0001
Next I%
Debug.Print MySum
End Sub
前述と同じ理由により、この結果は 0.999999999999996 と出力されます。0.0001 を 2 進数で表現するときの小さな誤差が原因で、合計値にも影響があります。

負数の和を求める例

  1. 新しいブックに次のように入力します。
    A1: =(43.1-43.2)+1
  2. セル A1 を右クリックし、[セルの書式設定] をクリックします。[表示形式] タブの [分類] で [指数] をクリックします。[小数点以下の桁数] を 15 に設定します。
0.9 ではなく 0.899999999999999 と表示されます。(43.1-43.2) が先に計算され、-0.1 が一時的に格納されるため、その格納に伴う誤差が計算に影響を及ぼしています。

値がゼロに達する例

  1. Excel 95 以前で、新しいブックに次のように入力します。
    A1: =1.333+1.225-1.333-1.225
  2. セル A1 を右クリックし、[セルの書式設定] をクリックします。[表示形式] タブの [分類] で [指数] をクリックします。[小数点以下の桁数] を 15 に設定します。
Excel 95 では、0 ではなく -2.22044604925031E-16 と表示されます。

一方、Excel 97 では、この問題の修正を試みる最適化が導入されています。加算または減算の結果がゼロになるか、またはゼロに非常に近い値になる場合、Excel 97 以降では、オペランドを 2 進数に変換したりその逆の処理を行ったりした影響で生じた誤差が補正されます。上記の例を Excel 97 以降で実行すると、正しく 0 (指数表記では 0.000000000000000E+00) と表示されます。 詳細については、以下のサポート技術情報番号をクリックしてください。
172911 非常に大きな指数または非常に小さな指数で 10 を累乗すると誤った結果が返される
214373 非常に大きな指数または非常に小さな指数で 10 を累乗すると誤った結果が返される
浮動小数点数と IEEE 754 規格の詳細については、次の Web サイトを参照してください。
http://www.ieee.org

http://steve.hollasch.net/cgindex/coding/ieeefloat.html

関連情報

このエラーを回避する方法の詳細については、以下のサポート技術情報番号をクリックしてください。
214118 浮動小数点数の演算における丸め誤差を修正する方法
注意 : これは、マイクロソフトのサポート組織内で直接作成された "緊急公開" の資料です。 この資料には、確認中の問題に関する現状ベースの情報が記載されています。 情報提供のスピードを優先するため、資料には誤植が含まれる可能性があり、予告なしに随時改定される場合があります。 その他の考慮事項については、使用条件を参照してください。

プロパティ

文書番号: 78113 - 最終更新日: 2013年2月26日 - リビジョン: 2.0
この資料は以下の製品について記述したものです。
  • Microsoft Excel 2013
  • Microsoft Excel 2010
  • Microsoft Office Excel 2007
  • Microsoft Office Excel 2003
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Excel 97 Standard Edition
  • Microsoft Excel 95 Standard Edition
  • Microsoft Excel 2011 for Mac
  • Microsoft Office Excel 2008 for Mac
  • Microsoft Excel 2004 for Mac
  • Microsoft Excel X for Mac
  • Microsoft Excel 2001 for Mac
  • Microsoft Excel 98 for Macintosh
キーワード:?
kbinfo KB78113
Microsoft Knowledge Base の免責: Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。

フィードバック

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com