倍精度浮動小数点形式(FP64またはfloat64とも呼ばれる)は、コンピュータのメモリ内で通常64ビットを占める浮動小数点数形式であり、浮動小数点を使用して幅広い数値範囲を表現します。
単精度演算の範囲や精度が不十分な場合は、倍精度演算を選択することができます。
IEEE 754規格では、64 ビットの 2 進数形式は正式にはbinary64と呼ばれています。IEEE 754-1985ではdoubleと呼ばれていました。IEEE 754 では、32 ビットの 2 進数単精度や、最近では 10 進数表現 (10進浮動小数点数) など、その他の浮動小数点形式も規定されています。
浮動小数点データ型を提供した最初のプログラミング言語の1つはFortranでした。IEEE 754-1985が広く採用される以前は、浮動小数点データ型の表現と特性は、コンピュータメーカーとコンピュータモデル、そしてプログラミング言語の実装者の決定に依存していました。例えば、GW-BASICの倍精度浮動小数点データ型は、64ビットMBF浮動小数点形式でした。
倍精度バイナリ浮動小数点数は、単精度浮動小数点数よりも表現範囲が広いため、パフォーマンスと帯域幅のコストは高いものの、PCで一般的に使用されている形式です。一般的には単にdoubleと呼ばれています。IEEE 754規格では、binary64は次のように規定されています。
符号ビットは数値の符号を決定します(この数値がゼロの場合も符号付きになります)。
指数部は、0から2047までの11ビット符号なし整数で、バイアス形式です。指数値が1023の場合は、実際のゼロを表します。指数は-1022から+1023までの範囲になります。これは、-1023(すべて0)と+1024(すべて1)の指数が特別な数値用に予約されているためです。
53ビットの仮数精度は、15~17桁の有効小数点精度(2 −53 ≈ 1.11 × 10 −16)を提供します。最大15桁の有効小数点数を持つ10進数文字列をIEEE 754倍精度形式に変換して通常の数値にし、その後同じ桁数の10進数文字列に再変換すると、最終結果は元の文字列と一致するはずです。IEEE 754倍精度数を少なくとも17桁の有効小数点数を持つ10進数文字列に変換し、その後倍精度表現に再変換すると、最終結果は元の数値と一致する必要があります。[ 1 ]
フォーマットは、仮数部が暗黙的に値 1 の整数ビットを持つように記述されます (特殊データを除く。指数エンコーディングについては後述)。メモリフォーマットには仮数部 (F) の 52 ビットが現れるため、全体の精度は 53 ビット (約 16 桁の 10 進数、53 log 10 (2) ≈ 15.955) となります。ビットの配置は次のとおりです。
![]()
与えられたバイアス指数を持つ、与えられた 64 ビット倍精度データが取る実際の値 52ビットの小数部は
または
2 52 =4,503,599,627,370,496 と 2 53 =9,007,199,254,740,992 の間では、表現可能な数値は整数のみです。次の範囲、2 53から2 54までは、すべてが 2 倍されるため、表現可能な数値は偶数になります。逆に、前の 2 51から 2 52までは、間隔は 0.5 です。
2 nから2 n +1の範囲の数値に対する間隔の割合は2 n −52です。したがって、数値を最も近い表現可能な数値に丸める際の最大相対丸め誤差 (機械のイプシロン) は 2 −53です。
指数部の11ビット幅により、 10⁻³⁰⁸から10³⁰⁸までの数値を15~17桁の精度で表現できます。精度を犠牲にすることで、サブノーマル表現では 約5 × 10⁻³²⁴までのさらに小さな値も表現できます。
倍精度バイナリ浮動小数点指数は、オフセットバイナリ表現を使用してエンコードされ、ゼロオフセットは1023です。これは、IEEE 754規格では指数バイアスとも呼ばれます。このような表現の例としては、次のものがあります。
指数とには特別な意味があります。000167ff16
000000000002=は符号付きゼロ( F = 0 の場合) および正規化されていない数( F ≠ 0 の場合)を表すために使用されます。00016111111111112=は∞ ( F = 0 の場合) およびNaN ( F ≠ 0 の場合)を表すために使用されます。7ff16ここで、Fは仮数の小数部分です。すべてのビットパターンは有効な符号化です。
上記の例外を除き、倍精度浮動小数点数全体は次のように表されます。
非正規数(e = 0)の場合、倍精度浮動小数点数は次のように表されます。
多くのプロセッサはすべての種類のデータ (整数、浮動小数点) にリトルエンディアン ストレージを使用していますが、浮動小数点数がビッグエンディアン形式で表現され、整数がリトルエンディアン形式で表現されるハードウェア アーキテクチャがいくつかあります。[ 2 ]倍精度浮動小数点数に混合エンディアン浮動小数点表現を持つARMプロセッサがあります。2 つの 32 ビット ワードはそれぞれリトルエンディアンで格納されますが、最上位ワードが先に格納されます。VAX 浮動小数点では、リトルエンディアンの16 ビット ワードがビッグエンディアンの順序で格納されます。ネットワーク標準表現のない浮動小数点形式が多数存在するため、XDR標準では表現としてビッグエンディアンの IEEE 754 を使用しています。そのため、広く普及しているIEEE 754浮動小数点標準でエンディアンが指定されていないのは奇妙に思えるかもしれません。[ 3 ]理論的には、これは、あるマシンで書き込まれた標準 IEEE 浮動小数点データでも、別のマシンでは読み取れない可能性があることを意味します。しかし、最新の標準コンピュータ(IEEE 754を実装しているもの)では、浮動小数点数と整数のエンディアンは同じであると安全に想定できるため、データ型に関係なく変換は簡単です。ただし、特殊な浮動小数点フォーマットを使用する小型組み込みシステムの場合は、話は別です。
0 01111111111 0000000000000000000000000000000000000000000000000000 2 ≙ 3FF0 0000 0000 0000 16 ≙ +2 0 × 1 = 1
0 01111111111 00000000000000000000000000000000000000000000000000001 2 ≙ 3FF0 0000 0000 0001 16 ≙ +2 0 × (1 + 2 −52 ) ≈ 1.0000000000000002220(1より大きい最小の数)
0 01111111111 0000000000000000000000000000000000000000000000000010 2 ≙ 3FF0 0000 0000 0002 16 ≙ +2 0 × (1 + 2 −51 ) ≈ 1.0000000000000004441(1より大きい数の中で2番目に小さい数)
0 10000000000 00000000000000000000000000000000000000000000000000000 2 ≙ 4000 0000 0000 0000 16 ≙ +2 1 × 1 = 2
1 10000000000 0000000000000000000000000000000000000000000000000000 2 ≙ C000 0000 0000 0000 16 ≙ −2 1 × 1 = −2
0 10000000000 10000000000000000000000000000000000000000000000000000 2 ≙ 4008 0000 0000 0000 16 ≙ +2 1 × 1.1 2 = 11 2 = 3
0 10000000001 00000000000000000000000000000000000000000000000000000 2 ≙ 4010 0000 0000 0000 16 ≙ +2 2 × 1 = 100 2 = 4
0 10000000001 010000000000000000000000000000000000000000000000000000 2 ≙ 4014 0000 0000 0000 16 ≙ +2 2 × 1.01 2 = 101 2 = 5
0 10000000001 10000000000000000000000000000000000000000000000000000 2 ≙ 4018 0000 0000 0000 16 ≙ +2 2 × 1.1 2 = 110 2 = 6
0 10000000011 01110000000000000000000000000000000000000000000000000 2 ≙ 4037 0000 0000 0000 16 ≙ +2 4 × 1.0111 2 = 10111 2 = 23
0 01111111000 1000000000000000000000000000000000000000000000000000 2 ≙ 3F88 0000 0000 0000 16 ≙ +2 −7 × 1.1 2 = 0.00000011 2 = 0.01171875 (3/256)
0 00000000000 00000000000000000000000000000000000000000000000000001 2 ≙ 0000 0000 0000 0001 16 ≙ +2 −1022 × 2 −52 = 2 −1074 ≈ 4.9406564584124654 × 10 −324 (最小の正のサブノーマル数)
0 00000000000 11111111111111111111111111111111111111111111111111111 2 ≙ 000F FFFF FFFF FFFF 16 ≙ +2 −1022 × (1 − 2 −52 ) ≈ 2.2250738585072009 × 10 −308 (最大の異常数)
0 00000000001 00000000000000000000000000000000000000000000000000000 2 ≙ 0010 0000 0000 0000 16 ≙ +2 −1022 × 1 ≈ 2.2250738585072014 × 10 −308 (最小の正の正規数)
0 11111111110 11111111111111111111111111111111111111111111111111111 2 ≙ 7FEF FFFF FFFF FFFF 16 ≙ +2 1023 × (2 − 2 −52 ) ≈ 1.7976931348623157 × 10 308 (最大の通常の数)
0 00000000000 00000000000000000000000000000000000000000000000000000 2 ≙ 0000 0000 0000 0000 16 ≙ +0 (正のゼロ)
1 00000000000 00000000000000000000000000000000000000000000000000000 2 ≙ 8000 0000 0000 0000 16 ≙ −0 (負のゼロ)
0 11111111111 0000000000000000000000000000000000000000000000000000 2 ≙ 7FF0 0000 0000 0000 16 ≙ +∞ (正の無限大)
1 11111111111 0000000000000000000000000000000000000000000000000000 2 ≙ FFF0 0000 0000 0000 16 ≙ −∞ (負の無限大)
0 11111111111 00000000000000000000000000000000000000000000000000001 2 ≙ 7FF0 0000 0000 0001 16 ≙ NaN (x86 や ARM などのほとんどのプロセッサでは sNaN)
0 11111111111 10000000000000000000000000000000000000000000000000001 2 ≙ 7FF8 0000 0000 0001 16 ≙ NaN (x86 や ARM などのほとんどのプロセッサでは qNaN)
0 11111111111 111111111111111111111111111111111111111111111111111111 2 ≙ 7FFF FFFF FFFF FFFF 16 ≙ NaN (NaN の別のエンコード)
0 01111111101 0101010101010101010101010101010101010101010101010101 2 ≙ 3FD5 5555 5555 5555 16 ≙ +2 −2 × (1 + 2 −2 + 2 −4 + ... + 2 −52 ) ≈ 0.33333333333333331483 (1/3 に最も近い近似値)
0 10000000000 1001001000011111101101010100010001000010110100011000 2 ≙ 4009 21FB 5444 2D18 16 ≈ 3.141592653589793116 (π に最も近い近似値)
qNaNとsNaNのエンコーディングはIEEE 754で完全に規定されておらず、プロセッサに依存します。x86ファミリーやARMファミリーなどのほとんどのプロセッサは、仮数フィールドの最上位ビットを使用して静かなNaNを示します。これはIEEE 754で推奨されている方法です。PA -RISCプロセッサは、ビットを使用してシグナリングNaNを示します。
デフォルトでは、1 / 3は単精度のように切り上げではなく切り捨てを行います。これは、仮数のビット数が奇数であるためです。
さらに詳しく説明すると:
16進数表現3FD5 5555 5555 5555 16が与えられた場合、 符号 = 0 指数 = 3FD 16 = 1021 指数バイアス = 1023(定数;上記参照) 分数 = 5 5555 5555 5555 16 値 = 2 (指数 − 指数バイアス) × 1.分数 – ここで分数を小数に変換してはいけないことに注意してください = 2 −2 × (15 5555 5555 5555 16 × 2 −52 ) = 2 −54 × 15 5555 5555 5555 16 = 0.333333333333333314829616256247390992939472198486328125 約1/3
倍精度浮動小数点変数を使用すると、通常は単精度浮動小数点変数を使用する場合よりも処理速度が遅くなります。特に問題となるコンピューティング分野の1つは、GPU上で実行される並列コードです。たとえば、NvidiaのCUDAプラットフォームを使用する場合、倍精度での計算は、ハードウェアによっては、単精度での計算に比べて完了までに2~32倍の時間がかかることがあります。[ 4 ]
さらに、多くの数学関数(例:sin、cos、atan2、log、exp、sqrt)は、正確な倍精度結果を得るためにより多くの計算を必要とするため、処理速度が遅くなります。
倍精度浮動小数点数は、多くのプログラミング言語でさまざまな方法で実装されています。動的精度のみを持つプロセッサ(SSE2非対応のx86プロセッサ、または互換性のためにSSE2を使用しない場合など)で、拡張精度がデフォルトで使用されている場合、ソフトウェアが一部の要件を満たすことが困難になる場合があります。
C と C++ は、多種多様な算術型を提供しています。倍精度は標準では必須ではありませんが ( IEEE 754 算術を扱うC99のオプションの付属書 F を除く)、ほとんどのシステムでは、double型は倍精度に対応しています。ただし、デフォルトで拡張精度を持つ 32 ビット x86 では、一部のコンパイラが C 標準に準拠していないか、算術演算で二重丸めが発生する可能性があります。[ 5 ]
Fortranにreal64はいくつかの整数型と実数型があり、 Fortranの組み込みモジュールからアクセスできる64ビット型はiso_fortran_env倍精度に対応します。
Common Lisp は、SHORT-FLOAT、SINGLE-FLOAT、DOUBLE-FLOAT、LONG-FLOAT の型を提供します。ほとんどの実装では、SINGLE-FLOAT と DOUBLE-FLOAT が他の型に適切な同義語として提供されています。Common Lisp は、IEEE 754 に従って、浮動小数点アンダーフローとオーバーフロー、および不正確な浮動小数点例外を捕捉するための例外を提供します。ANSI 規格では無限大と NaN は規定されていませんが、いくつかの実装ではこれらを拡張機能として提供しています。
Javaバージョン 1.2 より前では、すべての実装が IEEE 754 に準拠している必要がありました。バージョン 1.2 では、x87などのプラットフォームの中間計算でより高い精度を実現できるようになりました。そのため、厳密な IEEE 754 計算を強制するためにstrictfp修飾子が導入されました。厳密な浮動小数点演算は Java 17で復活しました。[ 6 ]
ECMAScript標準で規定されているように、JavaScriptにおけるすべての算術演算は倍精度浮動小数点演算を使用して行われるべきである。[ 7 ]
JSONデータ形式は数値をサポートしており、その精度や範囲に制限はありません。ただし、RFC 8259では、IEEE 754 binary64数値が広く実装されているため、JSON処理の実装はbinary64が提供する以上の精度や範囲を期待しない限り、良好な相互運用性を実現できると助言しています。[ 8 ]