Main Content

浮動小数点数

MATLAB® では、浮動小数点数が倍精度または単精度のいずれかの形式で表わされます。既定は倍精度ですが、簡単な変換関数を使用して任意の数値を単精度に変換することができます。

倍精度浮動小数点

MATLAB では、倍精度に関する IEEE® Standard 754 に従って、倍精度 (double) データ型が作成されます。double として保存されるすべての値には 64 ビットが必要で、以下の表の形式を使用します。

ビット

使用方法

63

符号 (0 = 正、1 = 負)

6252

1023 でバイアスされた指数部

510

数値 1.f の端数部分 f

単精度浮動小数点

MATLAB では、単精度に関する IEEE Standard 754 に従って、単精度 (single) データ型が作成されます。single として保存されるすべての値には 32 ビットが必要で、以下の表の形式を使用します。

ビット

使用方法

31

符号 (0 = 正、1 = 負)

3023

127 でバイアスされた指数部

220

数値 1.f の端数部分 f

MATLAB では、32 ビットで single 型の数値が保存されるので、64 ビットを使用する double 型の数値より必要メモリが少なくなります。ただし、single 型の数値は、保存する場合の使用ビットが少ないので、double 型の数字より精度が低くなります。

浮動小数点データの作成

約 3.4 x 10 38 より大きい、あるいは約 -3.4 x 10 38 より小さい値を保存するには、倍精度を使用します。これら 2 つの範囲の間にある数に対しては、倍精度または単精度のいずれかを使用することができますが、必要なメモリは単精度の方が少なくて済みます。

倍精度データの作成

MATLAB では既定の数値型が double であるため、簡単な代入ステートメントを使用して double を作成できます。

x = 25.783;

関数 whos により、MATLAB で x に保存したばかりの double 型の値のために、1 行 1 列の配列が作成されたことが示されます。

whos x
  Name      Size                   Bytes  Class

  x         1x1                        8  double

x が浮動小数点数であることを確かめたい場合は、isfloat を使用します。この関数は、入力が浮動小数点数の場合、logical 1 (true) を返し、それ以外の場合、logical 0 (false) を返します。

isfloat(x)
ans =

  logical

   1

数値データ、文字または string、logical データを、MATLAB 関数 double で倍精度に変換できます。この例では、符号付きの整数を倍精度の浮動小数点に変換します。

y = int64(-589324077574);          % Create a 64-bit integer

x = double(y)                      % Convert to double
x =
  -5.8932e+11

単精度データの作成

MATLAB では既定の設定により、数値データが double として保存されるため、単精度数値を作成するには変換関数 single を使用しなければなりません。

x = single(25.783);

関数 whos からは、変数 x の属性が構造体で返されます。この構造体の bytes フィールドは、xdouble として保存する場合には 8 バイト必要であるのに対し、single として保存する場合は、4 バイトだけで済むことを示します。

xAttrib = whos('x');
xAttrib.bytes
ans =
     4

数値データ、文字または string、logical データを、関数 single で単精度に変換できます。この例では、符号付きの整数を単精度の浮動小数点に変換します。

y = int64(-589324077574);          % Create a 64-bit integer

x = single(y)                      % Convert to single
x =

  single

 -5.8932e+11

浮動小数点数の算術演算

この節では、浮動小数点数の算術演算で使用できるデータ型について説明します。

倍精度の演算

基本的な算術演算は、double 型、および次のその他のデータ型に実行できます。1 つ以上のオペランドが整数 (スカラーまたは配列) の場合、double のオペランドはスカラーでなければなりません。特に注意書きがなければ、結果は double 型になります。

  • single — 結果は次の型になります。 single

  • double

  • int* または uint* — 結果は、整数オペラントと同じデータ型をもちます。

  • char

  • logical

この例は、char 型と double 型のデータに算術演算を行います。結果は double 型になります。

c = 'uppercase' - 32;

class(c)
ans =
   double

char(c)
ans =
   UPPERCASE

単精度の演算

single 型、および次のその他のクラスに、基本的な算術演算を実行できます。結果は、常に single 型になります。

  • single

  • double

  • char

  • logical

この例では、7.5 は既定の double 型で、結果は single 型です。

x = single([1.32 3.47 5.28]) .* 7.5;

class(x)
ans =
   single

浮動小数点クラスの最大値と最小値

doublesingle クラスでは、データ型で表現可能な最大値と最小値が存在します。

倍精度値の最大と最小

MATLAB の関数 realmax と関数 realmin は、double データ型で表現可能な最大値および最小値を返します。

str = 'The range for double is:\n\t%g to %g and\n\t %g to  %g';
sprintf(str, -realmax, -realmin, realmin, realmax)

ans =
The range for double is:
   -1.79769e+308 to -2.22507e-308 and
    2.22507e-308 to  1.79769e+308

realmax より大きい値、または -realmax より小さい値には、正と負の無限値がそれぞれ代入されます。

realmax + .0001e+308
ans =
   Inf

-realmax - .0001e+308
ans =
  -Inf

単精度値の最大と最小

MATLAB の関数 realmax と関数 realmin は、引数 'single' を使用して呼び出すと、single データ型で表現可能な最大値および最小値を返します。

str = 'The range for single is:\n\t%g to %g and\n\t %g to  %g';
sprintf(str, -realmax('single'), -realmin('single'), ...
    realmin('single'), realmax('single'))

ans =
The range for single is:
	-3.40282e+38 to -1.17549e-38 and
	 1.17549e-38 to  3.40282e+38

realmax('single') より大きい値、または -realmax('single') より小さい値には、正と負の無限値がそれぞれ代入されます。

realmax('single') + .0001e+038
ans =

  single

   Inf

-realmax('single') - .0001e+038
ans =

  single

  -Inf

浮動小数点データの精度

浮動小数点演算の計算結果が、予想した精度でない場合、コンピューターのハードウェアの制限が原因である可能性があります。おそらく、ハードウェアに完全な精度で結果を表すために十分なビットがないために、結果の端数が切り捨てられ、結果は正確でなくなったと考えられます。

倍精度数の精度

倍精度数は有限個しかないので、倍精度ストレージですべての数を表すことはできません。すべてのコンピューターにおいて、各倍精度の数と次に大きい倍精度の数の間には小さなギャップがあります。関数 eps を使用して、結果の精度を制限するこのギャップのサイズを決めることができます。たとえば、5 と次に大きい倍精度数の間隔を求めるには、次のように入力します。

format long

eps(5)
ans =
     8.881784197001252e-16

これは、5 と 5 + eps(5) の間に倍精度の数が存在しないことを示します。倍精度の計算で答えとして 5 が返された場合、この結果は eps(5) の範囲で正確であるにすぎません。

eps(x) の値は、x に依存します。この例は、x が大きくなるにつれて、eps(x) も大きくなることを示しています。

eps(50)
ans =
     7.105427357601002e-15

入力引数なしで eps を実行すると、MATLAB から eps(1)、つまり 1 と次に大きい倍精度数値の差が返されます。

単精度数の精度

同様に、任意の 2 つの単精度数間にもギャップが存在します。xsingle 型をもつ場合、eps(x) は、x と次に大きい単精度数間の間隔を返します。たとえば、

x = single(5);
eps(x)

では、以下が返されます。

ans =

  single

  4.7684e-07

この結果は eps(5) より大きいことに注意してください。単精度数は倍精度数よりも数が少ないので、単精度数間の差は、倍精度数間の差よりも大きくなります。これは、単精度演算の結果は、倍精度演算の結果よりも精度が低くなることを意味します。

double 型の数 x に対し、eps(single(x)) によって xdouble から single に変換する際に丸められる量の上限が与えられます。たとえば、倍精度数 3.14single に変換する場合、次のように丸められます。

double(single(3.14) - 3.14)
ans =
   1.0490e-07

3.14 で丸められた値は、次の数値より大きくなることはありません。

eps(single(3.14))
ans =

  single

  2.3842e-07

浮動小数点演算によくある問題の回避

MATLAB での大部分の演算は、IEEE Standard 754 に従う倍精度演算で行われます。コンピューターは数値を有限の精度 (仮数 52 ビットに対する倍精度の呼び出し) で表すだけなので、数学的にわかりにくい計算結果が生じることがあります。これらの結果は MATLAB のバグではないことに注意してください。

以下の例を使用して、これらのケースを確認してください。

例 1 — 四捨五入、あるいは予想外の結果になる場合

10 進数 4/3 は、2 進数の分数として厳密に表現することができません。このため、次の計算はゼロにはならず、eps 量が示されます。

e = 1 - 3*(4/3 - 1)

e =
   2.2204e-16

同様に、0.1 は 2 進数の数として正確には表現することができません。したがって、次のような直観的でない動作を示します。

a = 0.0;
for i = 1:10
  a = a + 0.1;
end
a == 1
ans =

  logical

   0

計算では演算の順序が重要であることに注意してください。

b = 1e-16 + 1 - 1e-16;
c = 1e-16 - 1e-16 + 1;
b == c
ans =

  logical

   0

浮動小数点数間にはギャップがあります。以下からわかるように、数が大きくなると、ギャップも大きくなります。

(2^53 + 1) - 2^53

ans =
     0

pi は実際には π ではないので、sin(pi) も正確にゼロにはなりません。

sin(pi)

ans =
     1.224646799147353e-16

例 2 — 非常に問題のある打ち消し (Catastrophic Cancellation)

ほとんど等価なオペランドどうしの減算では、予想外の打ち消しが起こることがあります。以下はスワンピング (加算を無効にする精度の損失) による打ち消しの例です。

sqrt(1e-16 + 1) - 1

ans =
     0

非常に問題のある打消しの影響を取り除くため、expm1log1p などの MATLAB 関数が使用される場合があります。

例 3 — 浮動小数点数の演算と線形代数

線形代数の問題を解く場合に、丸め、打ち消しおよびその他の浮動小数点数の特性が組み合わさって、計算結果が予想外のものになることがあります。次の行列 A は条件が悪いため、Ax = b 系が小さな摂動に敏感になるという警告が表示されます。

A = diag([2 eps]); 
b = [2; eps]; 
y = A\b; 
Warning: Matrix is close to singular or badly scaled.
         Results may be inaccurate. RCOND = 1.110223e-16.

これらは、IEEE 浮動小数点演算が MATLAB での計算にどのように影響するかを示すいくつかの例にすぎません。IEEE 754 算術演算で行われたすべての計算が影響を受けることに注意してください。これは MATLAB だけでなく、C や FORTRAN で記述されたアプリケーションを含みます。

参照

[1] Moler, Cleve. “Floating Points.” MATLAB News and Notes. Fall, 1996.

[2] Moler, Cleve. Numerical Computing with MATLAB. Natick, MA: The MathWorks, Inc., 2004.