倍精度浮動小数点形式( 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浮動小数点形式でした。
IEEE 754 倍精度バイナリ浮動小数点形式: binary64
倍精度バイナリ浮動小数点は、パフォーマンスと帯域幅のコストにもかかわらず、単精度浮動小数点よりも範囲が広いため、PC でよく使用される形式です。これは通常、単にdoubleとして知られています。IEEE 754 標準では、binary64 を次のように指定しています。
符号ビットは、数値の符号を決定します (この数値が 0 の場合も符号付きになります)。
指数フィールドは、バイアス形式の 0 から 2047 までの 11 ビットの符号なし整数です。指数値 1023 は実際のゼロを表します。指数 -1023 (すべて 0) と +1024 (すべて 1) は特別な数のために予約されているため、指数の範囲は -1022 から +1023 になります。
53 ビットの有効桁精度は、15 ~ 17 桁の有効 10 進数精度 (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) になります。ビットは次のように配置されます。
与えられたバイアス指数 と52ビット小数部 を持つ64ビット倍精度データによって想定される実数値は、
または
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 −308から 10 308までの数値を 15~17 桁の精度で表現できます。精度を犠牲にして、非正規表現では 5 × 10 −324程度までのさらに小さな値も表現できます。
指数エンコーディング
倍精度バイナリ浮動小数点指数は、ゼロ オフセットが 1023 であるオフセット バイナリ表現を使用してエンコードされます。これは、IEEE 754 標準では指数バイアスとも呼ばれます。このような表現の例は次のとおりです。
指数とには特別な意味があります。
000167ff16
000000000002= は符号付きゼロ(F = 0の場合)および非正規数(F ≠ 0の場合)を表すために使用されます。00016111111111112= は∞ ( F = 0の場合) とNaN ( F ≠ 0の場合)を表すために使用されます。7ff16
ここで、F は仮数の小数部です。すべてのビット パターンは有効なエンコードです。
上記の例外を除いて、倍精度数全体は次のように記述されます。
非正規数(e = 0)の場合、倍精度数は次のように記述されます。
エンディアン
倍精度の例
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) では、正確な倍精度結果を得るためにより多くの計算が必要となり、そのため速度が遅くなります。
整数値の精度の制限
- −2 53から2 53 (−9,007,199,254,740,992 から 9,007,199,254,740,992) までの整数を正確に表現できます。
- 2 53から 2 54 = 18,014,398,509,481,984 までの整数は、2 の倍数 (偶数) に丸められます。
- 2 54から 2 55までの整数= 36,028,797,018,963,968 は 4 の倍数に丸められます。
- 2 nから 2 n +1までの整数は 2 n −52の倍数に丸められます。
実装
多くのプログラミング言語では、double は次のようにさまざまな方法で実装されています。SSE2のない(または互換性のためにSSE2が使用されていない) x86などの動的精度のみを備え、拡張精度がデフォルトで使用されるプロセッサでは、ソフトウェアが一部の要件を満たすのが困難な場合があります。
C および C++
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]
JavaScript
ECMAScript標準で規定されているように、JavaScriptにおけるすべての演算は倍精度浮動小数点演算を使用して実行されるものとする。[7]
翻訳
JSONデータエンコード形式は数値をサポートしており、数値表現が準拠しなければならない文法ではエンコードされた数値の精度や範囲に制限はありません。ただし、RFC 8259では、IEEE 754 binary64数値が広く実装されているため、binary64が提供する以上の精度や範囲を期待しない場合は、JSONを処理する実装によって良好な相互運用性を実現できるとアドバイスしています。[8]
ラストとジグ
RustとZigにはデータ型がありますf64。[9] [10]
注釈と参考文献
- ^ William Kahan (1997 年 10 月 1 日). 「IEEE 標準 754 バイナリ浮動小数点演算の現状に関する講義ノート」(PDF)。p. 4。2012年 2 月 8 日時点のオリジナルよりアーカイブ(PDF) 。
- ^ Savard, John JG (2018) [2005]、「浮動小数点形式」、quadibloc、2018-07-03にオリジナルからアーカイブ、2018-07-16に取得
- ^ 「pack – リストをバイナリ表現に変換する」。2009年2月18日時点のオリジナルよりアーカイブ。2009年2月4日閲覧。
- ^ 「Nvidia の新しい Titan V は、1 つのチップで 110 テラフロップスを実現」。Tom 's Hardware。2017年 12 月 8 日。2018年 11 月 5 日閲覧。
- ^ 「バグ 323 – 最適化されたコードで奇妙な浮動小数点結果が生成される」gcc.gnu.org。 2018 年 4 月 30 日時点のオリジナルよりアーカイブ。 2018 年4 月 30 日閲覧。
- ^ Darcy, Joseph D. 「JEP 306: 常に厳密な浮動小数点セマンティクスの復元」。2021年9月12日閲覧。
- ^ ECMA-262 ECMAScript 言語仕様(PDF) (第 5 版)。Ecma International。p. 29、§8.5数値型。2012年 3 月 13 日のオリジナルからアーカイブ(PDF) 。
- ^ Bray, Tim (2017 年 12 月)。「JavaScript Object Notation (JSON) データ交換フォーマット」。インターネット エンジニアリング タスク フォース。2022年 2 月 1 日閲覧。
- ^ 「データ型 - Rustプログラミング言語」. doc.rust-lang.org . 2024年8月10日閲覧。
- ^ 「ドキュメント - Zigプログラミング言語」ziglang.org . 2024年8月10日閲覧。
