IEEE 754

IEEE浮動小数点演算標準IEEE 754)は、1985年に米国電気電子学会(IEEE)によって制定された浮動小数点演算技術標準です。この標準は、多様な浮動小数点実装において、信頼性と移植性を確保しながら使用することを困難にしていた多くの問題に対処しました。多くのハードウェア浮動小数点ユニットはIEEE 754標準を採用しています。

この標準では以下が定義されています。

  • 算術形式:有限数 (符号付きゼロ非正規数を含む)、無限大、および特別な「非数」値 ( NaN )で構成される2 進数および10 進数浮動小数点データのセット
  • 交換形式:浮動小数点データを効率的かつコンパクトな形式で交換するために使用できるエンコード(ビット文字列)
  • 丸め規則:算術および変換中に数値を丸めるときに満たすべき特性
  • 演算:算術形式における算術演算およびその他の演算(三角関数など)
  • 例外処理:例外的な状況の表示 (ゼロ除算、オーバーフローなど)

2008 年 8 月に発行されたIEEE 754-2008には、元のIEEE 754-1985標準のほぼすべてに加えて、IEEE 854-1987 (基数非依存浮動小数点演算) 標準が含まれています。現在のバージョンであるIEEE 754-2019は、2019年7月に発行されました。[ 1 ]これは以前のバージョンのマイナーリビジョンであり、主に明確化、欠陥の修正、および新しい推奨操作が組み込まれています。

歴史

浮動小数点演算標準のタイムライン
公式規格
1982 IEC 559:1982
1985 IEEE 754-1985
1987 IEEE 854-1987
1989 IEC 559:1989
2008 IEEE 754-2008
2011 ISO/IEC/IEEE 60559:2011
2019 IEEE 754-2019
2020 ISO/IEC 60559:2020
2029 未定

浮動小数点標準の必要性は、1960年代から1970年代にかけてのビジネスおよび科学計算業界の混乱から生まれました。IBMは、精度に関わらず常に7ビットを指数として使用する16進浮動小数点形式を採用していました。CDCおよびCrayコンピュータ、 +0と-0の値を許容する1の補数表現を使用していました。CDCの60ビットコンピュータには完全な60ビット加算器が搭載されていなかったため、整数演算は浮動小数点ユニットからの48ビット精度に制限されていました。ゼロ除算による例外処理はコンピュータごとに異なり、システム間でデータを移動することや、同じ計算を異なるシステムで繰り返すことさえ困難になることがよくありました。

浮動小数点演算に関する最初の IEEE 標準であるIEEE 754-1985 は、1985 年に発行されました。この標準では、2 進浮動小数点演算のみが対象とされていました。

7年間にわたる改訂作業を経て、Dan Zuras氏が議長を務め、Mike Cowlishaw氏が編集した新しいバージョンであるIEEE 754-2008が2008年8月に発行されました。この規格は、IEEE 754-1985(2進浮動小数点演算)およびIEEE 854-1987(基数非依存浮動小数点演算)の両方の規格に取って代わりました。この新しい規格には、元の規格​​の2進形式に加えて、2進形式1つと10進形式2つの計3つの新しい基本形式が含まれています。現在の規格に準拠するには、実装において、少なくとも1つの基本形式を算術形式と交換形式の両方として実装する必要があります。

国際規格ISO/IEC/IEEE 60559:2011 (IEEE 754-2008と同一の内容)は、ISO/IEEE PSDO協定[ 2 ] [ 3 ]に基づき、 ISO / IEC JTC 1 /SC 25を通じて採用が承認され、発行されました。[ 4 ]

2019年7月に発行された現行版IEEE 754-2019は、2015年9月に開始された改訂プロセス(議長:David G. Hough、編集者:Mike Cowlishaw)を経て、IEEE 754-2008から派生し、これを置き換えるものです。この改訂プロセスでは、主に明確化(例:totalOrder)と不具合修正(例:minNum)が行われていますが、新たに推奨される演算(例:augmentedAddition)もいくつか含まれています。[ 5 ] [ 6 ]

国際規格ISO/IEC 60559:2020(IEEE 754-2019と同一の内容)は、ISO/IEC JTC 1 /SC 25を通じて採用が承認され、発行されました。[ 7 ]

この規格の次回の改訂は2029年に予定されている。[ 8 ]

フォーマット

IEEE 754形式は「数値と記号の表現の集合」です。形式には、その集合がどのようにエンコードされるかが含まれる場合もあります。[ 9 ]

浮動小数点形式は次のように指定される。

  • 基数(基数とも呼ばれる)b。IEEE 754 では 2(2 進数)または 10(10 進数)のいずれかです。
  • 精度p ;
  • 指数範囲はeminからemaxまでで、emin = 1 − emax、または同等のemin = − ( emax − 1 ) となります (すべての IEEE 754 形式の場合)。

フォーマットは

  • 有限数は、3 つの整数で表すことができます。s は符号(0 または 1)、c は 、bを基数として表記した場合にp桁以下になる仮数部(係数または仮数とも呼ばれます) (つまり、0 からb p − 1までの範囲の整数 )、q は、eminq  +  p  − 1 ≤ emaxを満たす指数です。このような有限数の数値は、(−1) s × c × b qです。[ a ]さらに、符号付きゼロと呼ばれる 2 つのゼロ値があります。符号ビットは、ゼロが +0 (正のゼロ) か -0 (負のゼロ) かを指定します。
  • 2 つの無限大: +∞ と −∞。
  • 2 種類のNaN (not-a-number): 静かな NaN (qNaN) とシグナリング NaN (sNaN)。

例えば、b = 10、p = 7、emax = 96、emin = −95の場合、仮数は0 ≤ c ≤ を満たす。9 999 999であり、指数は−101 ≤ q ≤ 90を満たします。したがって、表現できる最小の非ゼロの正の数は 1×10 −101で、最大値は 9999999×10 90(9.999999×10 96)なので、数値の全範囲は −9.999999×10 96から 9.999999×10 96です。数 − b 1− emaxb 1− emax(ここでは −1×10 −95と 1×10 −95)は(大きさが)最小の正規数です。これらの最小数の間にある非ゼロの数は、非正規数と呼ばれます。

記憶における表現と符号化

数値によっては、複数の浮動小数点表現が可能な場合があります。例えば、b  = 10、p = 7の場合、-12.345は-12345×10 -3、-123450×10 -4、-1234500×10 -5 で表現できます。ただし、算術演算などのほとんどの演算では、結果(値)は入力の表現に依存しません。

10進形式では、任意の表現が有効であり、これらの表現の集合はコホートと呼ばれます。結果が複数の表現を持つ場合、標準規格ではコホートのどのメンバーが選択されるかが指定されます。

バイナリ形式では、表現可能な最小の指数を選択して値を正確に表現することで、表現が一意になります。また、指数は直接表現されず、表現可能な最小の指数が 1 として表現され、非正規数には 0 が使用されるようにバイアスが追加されます。指数が通常の範囲内にある数 (指数フィールドがすべて 1 でもすべて 0 でもない数) の場合、仮数の先頭ビットは常に 1 になります。したがって、先頭の 1 は、メモリ エンコードで明示的に存在するのではなく、暗黙的に存在する可能性があり、標準では、明示的に表現される仮数の部分は 0 と 1 の間になります。この規則は、先頭ビット規則暗黙のビット規則、または隠しビット規則と呼ばれます。この規則により、バイナリ形式で精度を 1 ビット追加できます。非正規数は、通常の指数範囲外の指数を持ち、最小の通常数に使用される最小の表現指数でスケールされるため、先頭ビット規則は使用できません。

複数のエンコードが可能であるため(少なくとも交換フォーマットと呼ばれるフォーマットでは)、NaNは他の情報も運ぶ可能性があります。符号ビット(意味はありませんが、一部の操作で使用される場合があります)とペイロード(NaNの発生源を示す診断情報用です)です(ただし、ペイロードにはNaNボックス化[ 10 ] [ 11 ] [ 12 ]など、他の用途もあります)。

基本形式と交換形式

この規格では、数値の基数と交換エンコードで使用されるビット数に基づいて命名された5つの基本形式が定義されています。2進浮動小数点基本形式は3つ(32、64、または128ビットでエンコード)で、10進浮動小数点基本形式は2つ(64または128ビットでエンコード)です。binary32形式binary64形式は、それぞれIEEE 754-1985単精度形式と倍精度形式です。準拠実装では、少なくとも1つの基本形式を完全に実装する必要があります。

この規格では、これらの基本フォーマットを一般化する交換フォーマットも定義されています。 [ 13 ]バイナリフォーマットでは、先頭ビットの規則が必要です。次の表は、可能な交換フォーマット(基本フォーマットを含む)のいくつかをまとめたものです。

有効数字 指数 プロパティ[ b ]
名前 通称
基数
数字[ c ]
小数点[ d ]
マックス マックスバルログ10  MAXVALMINVAL >0 (正常) MINVAL >0 (正常範囲外) 注記
バイナリ16半精度 2 11 3.31 −14 15 65504 4.816 6.10 × 10 −55.96 × 10 −8交換
バイナリ32単精度 2 24 7.22 −126 127 3.40 × 103838.532 1.18 × 10 −381.40 × 10 −45基本
バイナリ64倍精度 2 53 15.95 −1022 1023 1.80 × 10308308.255 2.23 × 10 −3084.94 × 10 −324基本
バイナリ1284倍精度 2 113 34.02 −16382 16383 1.19 × 1049324932.075 3.36 × 10 −49326.48 × 10 −4966基本
バイナリ2568倍精度 2 237 71.34 −262142 262143 1.61 × 1078,91378913.207 2.48 × 10 −789132.25 × 10 −78984交換
10進3210 7 7 −95 96 1.0 × 109797 − 4.34 × 10 −81 × 10 −951 × 10 −101交換
10進6410 16 16 −383 384 1.0 × 10385385 − 4.34 × 10 −171 × 10 −3831 × 10 −398基本
10進12810 34 34 −6143 6144 1.0 × 1061456145 − 4.34 × 10 −351 × 10 −61431 × 10 −6176基本

上記の表では、整数値は正確な値ですが、小数点表記の値(例:1.0)は四捨五入された値です。記載されている最小指数は通常の数値のものです。特殊な非正規数表現では、精度が多少低下しますが、さらに小さい(絶対値が小さい)数値を表すことができます。例えば、binary64で表現できる最小の正の数は2 −1074です。この −1074 という数値には、最小値 −1022 と、53ビットの有効数字のうち1ビットを除くすべて(2 −1022 − (53 − 1)  = 2 −1074 )が含まれます。

小数点以下の桁数とは、その形式の精度を小数点以下の桁数で表したものです。これは、桁数× log 10の基数で計算されます。例えば、binary128 は34桁の小数点以下の桁数とほぼ同じ精度です。

log 10  MAXVALは、エンコードの範囲を表す尺度です。その整数部は、小数点の前の仮数部に1桁の数字が付いた科学的記数法で出力された値の最大指数です(例:1.698 × 1038は32進数の最大値に近い9.999999 × 1096は 10 進数の最大値です32)。

バイナリ32(単精度)とバイナリ64(倍精度)形式は、現在最も一般的に使用されている2つの形式です。下の図は、ある範囲の値における両方の形式の絶対精度を示しています。この図は、数値の期待値と必要な精度に基づいて適切な形式を選択する際に役立ちます。

バイナリ32とバイナリ64の精度は10 −12~ 10 12 の範囲です

32ビット浮動小数点のレイアウトの例は次の通りです。

64 ビットのレイアウトも同様です。

拡張および拡張可能な精度形式

標準規格では、オプションとして拡張精度形式と拡張可能精度形式が規定されており、これらは基本形式よりも高い精度を提供します。[ 14 ]拡張精度形式は、より高い精度とより広い指数範囲を使用して基本形式を拡張します。拡張可能精度形式では、ユーザーが精度と指数範囲を指定できます。実装では、このような形式に対して任意の内部表現を使用できます。定義する必要があるのは、そのパラメータ(bp、およびemax)だけです。これらのパラメータは、表現できる有限数の集合(与えられた基数に対する符号、仮数、および指数の組み合わせ)を一意に記述します。

標準規格では、言語標準がサポートされる各基数bに対してpemax を指定する方法を提供することが推奨されています。[ 15 ]標準規格では、言語標準と実装が、各基数bに対してサポートされる最大の基本形式よりも高い精度を持つ拡張形式をサポートすることが推奨されています。[ 16 ] 2つの基本形式の間の精度を持つ拡張形式の場合、指数範囲は次に広い基本形式と同じでなければなりません。したがって、例えば64ビットの拡張精度2進数は、少なくとも16383の 'emax' を持つ必要があります。x87 80ビット拡張形式はこの要件を満たしています。

オリジナルのIEEE 754-1985規格にも拡張フォーマットの概念はありましたが、eminemaxの間には強制的な関係はありませんでした。例えば、Motorola 68881の80ビットフォーマット[ 17 ]emin = − emax)は、準拠した拡張フォーマットでしたが、2008年の改訂では非準拠となりました。

交換フォーマット

交換形式は、特定の形式の固定長のビット文字列を使用して浮動小数点データを交換することを目的としています。

バイナリ

2進浮動小数点数の交換には、16ビット、32ビット、64ビット、および128ビット以上の任意の32ビットの倍数[ e ]の長さの交換形式が定義されています。16ビット形式は、小さな数値(例えば、グラフィックス用)の交換または保存を目的としています。

これらのバイナリ交換形式の符号化方式は、IEEE 754-1985 の符号化方式と同じです。つまり、符号ビット、バイアスによる指数オフセットを表すw個の指数ビット、そして仮数を表すp − 1 個のビットです。kビット形式 の指数フィールドの幅は、w  = round(4 log 2 ( k )) − 13として計算されます。既存の 64 ビット形式と 128 ビット形式はこの規則に従いますが、16 ビット形式と 32 ビット形式では、この式で得られる指数ビット数 (それぞれ 3 ビットと 7 ビット) よりも多くの指数ビット (それぞれ 5 ビットと 8 ビット) が存在します。

IEEE 754-1985と同様に、バイアス指数フィールドはすべて1ビットで埋められ、無限大(後続仮数フィールド = 0)またはNaN(後続仮数フィールド ≠ 0)を示します。NaNの場合、Quiet NaNとSignaling NaNは、後続仮数フィールドの最上位ビットのみを使用して区別されます([ f ])。ペイロードは残りのビットで保持されます。

小数点

10進浮動小数点数の交換には、32ビットの任意の倍数の交換形式が定義されています。2進数交換と同様に、10進数交換形式の符号化方式は、符号、指数、および仮数を符号化します。2つの異なるビットレベルの符号化が定義されており、使用されている符号化を示す外部的なインジケータが必要になる場合があるため、交換は複雑になります。

2つのオプションにより、仮数を圧縮された10進数列(densely packed decimal)としてエンコードするか、あるいは2進整数としてエンコードすることができます。前者は標準規格のハードウェア実装に直接適しており、後者はバイナリコンピュータ上でのソフトウェアエミュレーションに適しています。どちらの場合も、エンコード可能な数値セット(符号、仮数、指数の組み合わせ)は同一であり、特殊な値(最小指数の±ゼロ、±無限大、静止NaN、シグナリングNaN)のエンコードも同一です。

丸めルール

この規格では5つの丸め規則が定義されています。最初の2つの規則は最も近い値に丸められ、その他の規則は「指示丸め」と呼ばれます。

最も近い値に丸める

  • 最も近い偶数に丸める - 最も近い値に丸めます。数値が中間にある場合は、最下位桁が偶数である最も近い値に丸められます。
  • 最も近い値に丸め、ゼロから遠い方(またはから遠い方) - 最も近い値に丸めます。数値が中間にある場合は、それより上 (正の数の場合) または下 (負の数の場合) の最も近い値に丸められます。

極端な場合、絶対値が k より厳密に小さい値は、最小または最大の有限数(値の符号によって異なります)に丸められます。この絶対値を持つ数値は同点とみなされます。この同点の選択は、指数に制限がなければ、次に表現可能な浮動小数点数であるkと の中間点として概念化できます。絶対値がkより厳密に大きい数値は、対応する無限大に丸められます。[ 18 ]bエマックスb12b1p{\displaystyle k=b^{\text{emax}}\left(b-{\tfrac {1}{2}}b^{1-p}\right)}±bエマックスbb1p{\displaystyle \pm b^{\text{emax}}(bb^{1-p})}±bエマックス+1{\displaystyle \pm b^{{\text{emax}}+1}}

「最も近い値に丸め、偶数と同数」は2進浮動小数点のデフォルトであり、10進数では推奨されるデフォルトです。「最も近い値に丸め、偶数と同数」は10進数の実装でのみ必須です。[ 19 ]

有向丸め

  • 0 の方向に丸める– ゼロの方向に丸めます (切り捨て とも呼ばれます)。
  • +∞ の方向に丸める– 正の無限大の方向への丸め (切り上げまたは天井 とも呼ばれます)。
  • −∞ の方向に丸める– 負の無限大の方向への丸め (切り捨てまたはフロアー とも呼ばれます)。
IEEE 754規則を使用して整数に丸める例
モード値の例
+11.5 +12.5 −11.5 −12.5
最も近い、偶数に等しい +12.0 +12.0 −12.0 −12.0
最も近い、ゼロから離れた +12.0 +13.0 −12.0 −13.0
0に向かって +11.0 +12.0 −11.0 −12.0
+∞に向かって +12.0 +13.0 −11.0 −12.0
−∞に向かって +11.0 +12.0 −12.0 −13.0

別途規定がない限り、浮動小数点演算の結果は、無限精度(数学的)な結果に丸め関数を適用することによって決定される。このような演算は、正しく丸められていると言われる。この要件は、正しい丸めと呼ばれる。[ 20 ]

必要な操作

サポートされている算術形式 (基本形式を含む) に必要な操作は次のとおりです。

  • 整数との間の変換[ 21 ] [ 22 ]
  • 前後の連続値[ 21 ]
  • 算術演算(加算、減算、乗算、除算、平方根、積和、剰余、最小値、最大値)[ 21 ] [ 22 ]
  • 変換(フォーマット間、文字列間の変換など)[ 23 ] [ 24 ]
  • スケーリングと(小数点以下の)量子化[ 25 ] [ 26 ]
  • 記号のコピーと操作(絶対、否定など)[ 27 ]
  • 比較と全順序付け[ 28 ] [ 29 ]
  • 数の分類(非正規数、有限数など)とNaNの検査[ 30 ]
  • ステータスフラグのテストと設定[ 31 ]

比較述語

この標準では、サポートされている算術形式で、ある浮動小数点データを別の浮動小数点データと比較するための比較述語を提供しています。[ 32 ] NaNとの比較は順序なしとして扱われます。-0と+0は等しいものとして比較されます。

全順序述語

標準規格では、サポートされている算術形式の標準メンバーの全順序を定義する述語totalOrderが提供されています。 [ 33 ]この述語は、一方の浮動小数点数が他方の浮動小数点数より小さい場合の比較述語(セクション§比較述語を参照)と一致します。主な違いは以下のとおりです。[ 34 ]

  • NaN はソート可能です。
    • NaN は、Infinity (またはその他の浮動小数点数) よりも絶対値​​が大きいものとして扱われます。(-NaN < -Infinity; +Infinity < +NaN)。
    • qNaN と sNaN は、qNaN の絶対値が sNaN よりも大きいかのように扱われます。 (−qNaN < −sNaN; +sNaN < +qNaN)
    • NaNはペイロードに従ってソートされます。IEEE 754-2008では、ペイロードが小さいNaNは絶対値が小さいものとして扱われます。IEEE 754-2019では、実装定義の順序付けが許容されます。
  • 負のゼロは正のゼロよりも小さいものとして扱われます。
  • 比較の両側が同じ浮動小数点データを参照している場合、指数が小さい方が絶対値が小さいものとして扱われます。[ 33 ]

totalOrder述語、フォーマット内のすべてのエンコーディングに全順序付けを強制するものではありません。特に、一方または両方のエンコーディングが非正規である場合など、同じ浮動小数点表現の異なるエンコーディングを区別しません。[ 33 ] IEEE 754-2019にはtotalOrderの明確化が盛り込まれています。

NaNシグナリングビットの配置に関するIEEE 754-2008勧告に従ったエンコードのバイナリ交換フォーマットの場合、比較は浮動小数点数を符号絶対値の整数に変換するもの(ペイロードの順序がこの比較と一致すると仮定)と同一であり、これはFPUを使用しないFP比較の古いトリックである。[ 35 ]

例外処理

標準では 5 つの例外が定義されており、各例外はデフォルト値を返し、例外が発生したときに発生する対応するステータス フラグを持ちます。[ g ] その他の例外処理は必要ありませんが、デフォルト以外の追加の代替手段が推奨されます ( § 代替例外処理を参照)。

5つの例外は

  • 無効な演算:数学的に定義されていない演算(例:負の数の平方根)。デフォルトではqNaNを返します。
  • ゼロ除算:有限の被演算子に対する演算は、正確に無限大の結果(例:1/0 または log(0))を返します。デフォルトでは、±無限大を返します。
  • オーバーフロー: 有限の結果が大きすぎて正確に表現できません(つまり、指数範囲が無制限の場合、指数がemaxよりも大きくなります)。デフォルトでは、最も近い値への丸めモードでは±無限大を返します(また、指定丸めモードの丸め規則に従います)。
  • アンダーフロー: 結果が非常に小さい(正常範囲外)場合。デフォルトでは、正の正規数の最小値以下の数値を返します(丸め規則に従います)。非正規数は常にアンダーフロー例外を意味しますが、デフォルトでは、結果が正確な場合はフラグは発生しません。
  • 不正確: 正確な(つまり、丸められていない)結果は正確に表現できません。デフォルトでは、正しく丸められた結果を返します。

これらは IEEE 754-1985 で定義された 5 つの例外と同じですが、ゼロ除算の例外が除算以外の演算にも拡張されています。

いくつかの10進浮動小数点実装では追加の例外が定義されているが[ 36 ] [ 37 ]、これはIEEE 754の一部ではない。

  • クランプ: 結果の指数が出力形式に対して大きすぎます。デフォルトでは、係数の末尾にゼロを追加して、指数を使用可能な最大値まで減らします。これが不可能な場合(必要な桁数が出力形式よりも多くなるため)、オーバーフロー例外が発生します。
  • 丸め: 結果の係数に必要な桁数が、出力形式が提供できる桁数を超えています。ゼロ以外の桁が切り捨てられた場合、不正確例外が通知されます。

さらに、どちらかのオペランドが無限大の場合や、結果が出力形式に適合しない場合の量子化などの操作も、無効な操作例外を通知します。[ 38 ]

特別な値

符号付きゼロ

IEEE 754規格では、ゼロは符号付きであり、「正のゼロ」(+0)と「負のゼロ」(-0)の両方が存在することを意味します。ほとんどのランタイム環境0では、正のゼロは通常「 」、負のゼロは「 」と表示されます-0。数値比較ではこれら2つの値は等価ですが、一部の演算では+0と-0に対して異なる結果が返されます。例えば、1/(-0)は負の無限大を返しますが、1/(+0)は正の無限大を返します(したがって、1/(1/±∞) = ±∞という恒等式は維持されます)。x = 0不連続性を持つ他の一般的な関数で、+0と-0を異なる扱いをする可能性のあるものとしては、 Γ( x )や、任意の負の数yに対するy + xi主平方根などがあります。他の近似法と同様に、「負のゼロ」を含む演算は、時折混乱を引き起こす可能性があります。例えば、IEEE 754では、x = yは常に1/ x = 1/ yを意味するわけではなく、0 = −0ですが、1/0 ≠ 1/(−0)です。[ 39 ]さらに、 ±0の逆平方根[ h ]は±∞ですが、実数上の 数学関数は負の値を持ちません。1/×{\displaystyle 1/{\sqrt {x}}}

非正規数

非正規値は、アンダーフローギャップのすぐ外側にある隣接する値と絶対距離が同じ値でアンダーフローギャップを埋めます。これは、アンダーフローギャップにゼロを置き、アンダーフローの結果がゼロに置き換えられていた(ゼロにフラッシュされていた)従来の方法よりも改善されています。 [ 40 ]

最新の浮動小数点ハードウェアは通常、非正規値 (および正規値) を処理するため、非正規値のソフトウェア エミュレーションは必要ありません。

無限

拡張実数直線上の無限大は、1、1.5 などの通常の浮動小数点値と同様に、IEEE 浮動小数点データ型で表現できます。これらはエラー値ではありませんが、多くの場合(丸め方法によって異なりますが)、オーバーフローが発生した場合の代替値として使用されます。ゼロ除算例外が発生した場合、正または負の無限大が正確な結果として返されます。無限大は数値として表現することもできます(C言語の "INFINITY" マクロ、またはプログラミング言語でその構文がサポートされている場合は " ∞ ")。

IEEE 754では、無限大を次のように適切に処理する必要がある。

  • (+∞) + (+7) = (+∞)
  • (+∞) × (−2) = (−∞)
  • (+∞) × 0 = NaN – 何も意味がない

NaNs

IEEE 754では、0/0、∞×0、sqrt(-1)といった特定の「無効な」演算の結果として返される「非数」(NaN)と呼ばれる特別な値が規定されています。一般的に、NaNは伝播されます。つまり、NaNを含むほとんどの演算はNaNになります。ただし、任意の浮動小数点値に対して定義された結果を返す関数は、NaNに対しても同様の結果を返します(例:NaN ^ 0 = 1)。NaNには、デフォルトの静寂NaNと、オプションで生成されるシグナリングNaNの2種類があります。あらゆる算術演算(数値比較を含む)においてシグナリングNaNが発生すると、「無効な演算」例外が通知されます。

標準規格で規定されているNaNの表現には、エラーの種類や発生源をエンコードするために使用できる未指定ビットがいくつかありますが、そのエンコードに関する標準規格は存在しません。理論的には、シグナリングNaNは、ランタイムシステムが初期化されていない変数にフラグを付けたり、通常の値による計算速度を低下させることなく浮動小数点数を他の特殊な値で拡張したりするために使用できますが、このような拡張は一般的ではありません。このアプローチの変種(「NaNボックス化」と呼ばれることもあります)は、一部のJavaScriptランタイム[ 41 ]LuaJIT [ 42 ]で、64ビットポインタ値とIEEE 754倍精度浮動小数点値を同じデータ型に格納するために使用されており、ランタイムは浮動小数点値のための余分なメモリ割り当てや間接参照のオーバーヘッドを排除できます。

設計の根拠

ウィリアム・カーハン。Intel 80x87浮動小数点コプロセッサとIEEE 754浮動小数点規格の主任設計者。

ここで解説するIEEE 754規格のより難解な機能、例えば拡張形式、NaN、無限大、非正規数などは、数値解析の専門家や高度な数値計算アプリケーションにのみ関係する、という誤解がよくあります。実際はその逆です。これらの機能は、数値計算に精通していないプログラマーにも安全で堅牢なデフォルト設定を提供するだけでなく、専門家による高度な数値計算ライブラリのサポートも実現するように設計されています。 IEEE 754の主要な設計者であるウィリアム・カーハンは、「…二進浮動小数点演算に関するIEEE標準754の機能は、数値計算の専門家以外には利用できない機能であるとみなすのは誤りである。事実は全く逆である。1977年、これらの機能は可能な限り幅広い市場に対応するためにIntel 8087に組み込まれた…エラー分析は、IEEE標準754のような、プログラマーの善意による無知を適度に許容する浮動小数点演算を設計する方法を示している」と指摘している。[ 43 ]

  • 無限大やNaNなどの特殊値は、浮動小数点演算が代数的に完全であることを保証する。つまり、すべての浮動小数点演算は明確に定義された結果を生成し、デフォルトではマシン割り込みやトラップをスローしない。さらに、例外的な場合に返される特殊値の選択は、多くの場合正しい答えを返すように設計されている。例えば、IEEE 754演算では、 のような連分数はすべての入力に対して正しい答えを返す。なぜなら、例えばz = 3のR(z) := 7 − 3/[z − 2 − 1/(z − 7 + 10/[z − 2 − 2/(z − 3)])]場合のようなゼロ除算は+無限大を与えることで正しく処理されるため、このような例外は安全に無視できるからである。[ 44 ] Kahanが指摘したように、アリアン5ロケットの喪失を引き起こした、浮動小数点から16ビット整数への変換オーバーフローに続く未処理のトラップは、デフォルトのIEEE 754浮動小数点ポリシーでは発生しなかったであろう。[ 43 ]
  • 非正規数は有限の浮動小数点数xとyに対して、x = yの場合にのみx − y = 0となることを保証するが、これは以前の浮動小数点表現では成り立たなかった。[ 45 ]
  • x87 80ビット形式の設計原理について、カハンは次のように述べている。「この拡張形式は、浮動小数点数と倍精度数をオペランドとする最も単純な演算を除くすべての演算において、速度の低下がほとんどないように設計されています。例えば、多項式評価、スカラー積、部分分数と連分数などの再帰処理を実装するループ内のスクラッチ変数に使用する必要があります。これにより、単純なアルゴリズムを台無しにする可能性のある、オーバーフロー/アンダーフローや深刻なローカルキャンセルを回避できます。」[ 46 ]高精度と拡張指数を用いた拡張形式での中間結果の計算は、科学計算の歴史的実践や科学計算用電卓の設計において前例があります。例えば、ヒューレット・パッカード金融電卓は、演算機能と金融関数を、格納または表示される有効小数点数よりも3桁多い桁数で実行しました。[ 46 ]拡張精度の実装により、通常は1単位(ULP)以内の倍精度結果を高速に提供する標準的な基本関数ライブラリを容易に開発できるようになりました。
  • 値を最も近い表現可能な値に正しく四捨五入することで、計算における体系的な偏りを回避し、誤差の増加を遅らせます。同点を偶数に四捨五入することで、似た数字を足し合わせる際に生じる可能性のある統計的な偏りを排除できます。
  • 有向丸めは、例えば区間演算における誤差の境界チェックを支援するために考案されました。また、一部の関数の実装にも使用されています。
  • 演算の数学的基礎、特に正しい丸めにより、数学的特性を証明し、2Sum、Fast2SumKahan 合計アルゴリズムなどの浮動小数点アルゴリズムを設計することが可能となり、例えば精度を向上させたり、倍精度演算サブルーチンを比較的簡単に実装したりすることが可能になります。

単精度および倍精度形式の特徴として、そのエンコードにより、ビットが符号付き絶対値の整数を表しているかのように、浮動小数点ハードウェアを使用せずに簡単にソートできることが挙げられますが、これが設計上の考慮事項であったかどうかは不明です(初期のIBM 16進浮動小数点表現にも、正規化された数値に対してこの特徴があったことは注目に値します)。一般的な2の補数表現では、ビットを符号付き整数として解釈すると、正の値は正しくソートされますが、負の値は反転されます。これを修正する方法の1つとして、正の値の符号ビットと負の値のすべてのビットを反転するXOR演算を行うことで、すべての値が符号なし整数(-0 < +0)としてソート可能になります。[ 35 ]

推奨事項

代替例外処理

この標準規格では、ユーザー定義のデフォルト値の事前置換、トラップ(何らかの方法で制御フローを変更する例外)、そしてtry/catchなどのフローを中断する他の例外処理モデルなど、様々な形態のオプションの例外処理が推奨されています。トラップやその他の例外メカニズムは、IEEE 754-1985と同様に、オプションのままです。

標準規格の第9項では、言語規格で定義されるべき追加の数学演算[ 47 ]が推奨されている。[ 48 ] 標準規格に準拠するために必須の演算はない。

以下は推奨される算術演算であり、正しく丸められなければならない。[ 49 ]

、関数は必要性が低いと判断されたため、IEEE 754-2008規格には含まれていなかった。[ 51 ]および関数についても言及されていたが、これは誤りとされた。[ 5 ]これら3つはすべて2019年の改訂版で追加された。 asinPi{\displaystyle \operatorname {asinPi} }acosPi{\displaystyle \operatorname {acosPi} }tanPi{\displaystyle \operatorname {tanPi} }asinPi{\displaystyle \operatorname {asinPi} }acosPi{\displaystyle \operatorname {acosPi} }

推奨される操作には、動的モードの丸め方向の設定とアクセスも含まれ、[ 52 ]、実装定義のベクトル縮小操作(合計、スケール積、ドット積など)が含まれますが、その精度は標準では指定されていません。[ 53 ]

2019年現在、バイナリ形式における拡張算術演算[ 54 ]も推奨されています。加算、減算、乗算を対象とするこれらの演算は、形式内で最も近い値に正しく丸められた結果と、形式内で正確に表現可能な誤差項からなる値のペアを生成します。この規格の発行時点では、ハードウェア実装は知られていませんが、よく知られたアルゴリズムを用いて、非常によく似た演算がソフトウェアで既に実装されていました。これらの標準化の歴史と動機については、背景資料で説明されています。[ 55 ] [ 56 ]

2019年現在、IEEE 754-2008で以前必須とされていたminNummaxNumminNumMagmaxNumMagは、非結合性のため推奨となりました。代わりに、2つの新しい最小値および最大値演算のセットが推奨されています。[ 57 ] 最初のセットには 、 minimumminimumNumbermaximummaximumNumberが含まれます。2番目のセットには、 minimumMagnitudeminimumMagnitudeNumbermaximumMagnitudemaximumMagnitudeNumberが含まれます。この変更の経緯と動機については、背景資料で説明されています。[ 58 ]

式の評価

この標準は、言語標準が演算シーケンスのセマンティクスをどのように規定すべきかを推奨し、リテラルの意味や結果の値を変更する最適化の微妙な点を指摘しています。対照的に、1985年版の以前の標準では、言語インターフェースの側面が未規定のままであり、コンパイラ間の動作の不一致や、最適化コンパイラにおける最適化レベルの差異につながっていました。

プログラミング言語は、ユーザーが各基数について式の中間計算の最小精度を指定できるようにする必要があります。これは標準規格ではpreferredWidthと呼ばれ、ブロックごとに設定できる必要があります。式内の中間計算は、オペランドの幅と、設定されている場合は preferredWidth の最大値を使用して計算され、一時データは保存される必要があります。したがって、例えば、x87浮動小数点ハードウェアをターゲットとするコンパイラは、中間計算に拡張倍精度形式を使用する必要があることを指定する手段を持つ必要があります。後続の式を評価する際は、丸めや変数への代入前の先行値ではなく、常に変数に格納された値を使用する必要があります。

再現性

IEEE 754-1985版では、実装において多くのバリエーション(一部の値のエンコードや特定の例外の検出など)が認められていました。IEEE 754-2008ではこれらの許容範囲は縮小されましたが、それでもいくつかのバリエーション(特にバイナリ形式)は依然として残っています。再現性に関する条項では、言語標準において再現可能なプログラム(つまり、言語のあらゆる実装において同じ結果を生成するプログラム)を作成するための手段を提供することが推奨されており、再現可能な結果を​​達成するために何を行う必要があるかが規定されています。

再現性がない可能性のある動作の具体例としては、C言語やC++言語が挙げられます。これらの言語では、浮動小数点演算の結果に高い精度を使用したり、浮動小数点式の縮約(通常の乗算​​と加算をFMA1.0/sqrt(x)逆平方根に1命令で変換するなど)が可能です。[ 59 ] GCCcl.exeなどのC/C++コンパイラは、明示的に許可されない限り、通常、デフォルトで両方を許可します。これらの変更により、精度を明らかに損なうことなく、より高速なコードを生成できるためです。コンパイラは、より明確に非準拠の「高速」最適化も提供しています。[ 60 ] [ 61 ] Cの数学関数は通常、「正しく丸められる」ように実装されておらず、問題をさらに悪化させています。[ 62 ]浮動小数点環境は、サードパーティのコードによって予期せず変更される可能性もあります。

キャラクター表現

標準規格では、基本形式と外部文字シーケンス形式間の変換操作が要求されています。[ 63 ]すべての形式において、10進文字形式との変換が必要です。外部文字シーケンスへの変換は、最も近い偶数への丸め、偶数への結びつきを使用して元の数値に戻すことで実現する必要があります。quiet NaNまたはsignaling NaNのペイロードを保持する必要はなく、外部文字シーケンスからの変換によってsignaling NaNがquiet NaNに変換される可能性があります。

元の2進値は、次のように10進数に変換して戻すことで保存されます。[ 64 ]

  • 2進16進数の場合は5桁の10進数、
  • バイナリ32の場合は9桁の10進数、
  • バイナリ64の場合は17桁の10進数、
  • 2進128の36桁の10進数。

他のバイナリ形式では、必要な小数点以下の桁数は[ i ]です。

1+plog10(2),{\displaystyle 1+\lceil p\log _{10}(2)\rceil ,}

ここで、pはバイナリ形式の有効ビット数です。たとえば、binary256 の場合は 237 ビットです。

10 進浮動小数点形式を使用する場合、10 進表現は次のように保存されます。

  • 10進数32の場合は7桁、
  • 10進64の場合は16桁、
  • decimal128 の場合は 34 桁の小数点。

2進数から10進数、10進数から2進数への正しく丸められた変換アルゴリズムとコードについては、Gay [ 65 ]によって議論されており、テストについてはPaxsonとKahan [ 66 ]によって議論されています。

16進リテラル

この標準規格では、 C99の16進浮動小数点リテラルに基づいて、外部16進仮数文字シーケンスとの間の変換を提供することが推奨されています。このようなリテラルは、オプションの符号(または)、指示子「0x」、ピリオド付きまたはピリオドなしの16進数、指数指示子「p」、およびオプションの符号付き10進指数で構成されます。構文は大文字と小文字を区別しません。[ 67 ] 10進指数は2の累乗でスケーリングされます。例えば、は1/16、は1/256です。[ 68 ]+-0x0.1p00x0.1p-4

参照

注記

  1. ^たとえば、基数が 10、符号が 1 (負を示す)、仮数が 12345、指数が -3 の場合、数値は(-1) 1 × 12345 × 10 -3 = -1 × 12345 × 0.001 = -12.345 になります。
  2. ^概算値。正確な値については、各フォーマットのWikipediaの個別の項目を参照してください。
  3. ^使用される基数の桁数。暗黙の桁を含みますが、符号ビットはカウントされません。
  4. ^対応する小数点以下の桁数については、本文を参照してください。
  5. ^ 10進数とは異なり、96ビット長のバイナリ交換形式は存在しません。ただし、非交換形式としてはまだ許可されています。
  6. ^標準では、シグナリング NaN には 0、静かな NaN には 1 を推奨しているため、このビットのみを 1 に変更することでシグナリング NaN を静かにすることができ、その逆を行うと無限大がエンコードされる可能性があります。
  7. ^アンダーフローの特定のケースではフラグは立てられません。
  8. ^高速逆平方根平方根の計算方法#逆平方根の反復法を参照
  9. ^実装上の制限として、正しい丸めは、サポートされる最大のバイナリ形式の必要な小数点以下の桁数に3を加えた数だけ保証されます。例えば、サポートされる最大のバイナリ形式がbinary32の場合、12桁の小数点以下の外部シーケンスからbinary32に変換すると、正しく丸められることが保証されます。しかし、13桁の小数点以下のシーケンスの変換は正しく丸められません。ただし、標準規格では、実装においてこのような制限を設けないことが推奨されています。

参考文献

  1. ^ IEEE 754 2019
  2. ^ Haasz, Jodi. 「FW: ISO/IEC/IEEE 60559 (IEEE Std 754-2008)」 . IEEE . 2017年10月27日時点のオリジナルよりアーカイブ。 2018年4月4日閲覧
  3. ^ 「ISO/IEEE パートナー標準開発機構(PSDO)協力協定」(PDF) ISO. 2007年12月19日. 2021年12月27日閲覧
  4. ^ ISO/IEC JTC 1/SC 25 2011 .
  5. ^ a b Cowlishaw, Mike (2013-11-13). 「IEEE 754-2008 errata」 . speleotrove.com . 2020年1月24日閲覧。
  6. ^ "ANSI/IEEE Std 754-2019" . ucbtest.org . 2024年1月16日閲覧
  7. ^ ISO/IEC JTC 1/SC 25 2020 .
  8. ^ 「754次版の課題」 IEEE 2024年8月12日閲覧
  9. ^ IEEE 754 2008、§2.1.27。
  10. ^ 「SpiderMonkeyの内部構造」udn.realityripple.com . 2018年3月11日閲覧
  11. ^クレメンス、ベン(2014年9月)。『21世紀のC:ニュースクールからのCのヒント』オライリーメディア社、160ページ。ISBN 9781491904442. 2018年3月11日閲覧
  12. ^ "zuiderkwast/nanbox: C での NaN ボクシング" . GitHub2018年3月11日に取得
  13. ^ IEEE 754 2008、§3.6。
  14. ^ IEEE 754 2008、§3.7。
  15. ^ IEEE 754 2008、§3.7 には、「言語標準では、サポートされる基数ごとに拡張可能な精度をサポートするメカニズムを定義する必要があります。」と記載されています。
  16. ^ IEEE 754 2008、§3.7 には、「言語標準または実装は、その基数でサポートされている最も広い基本形式を拡張する拡張精度形式をサポートする必要があります。」と記載されています。
  17. ^ Motorola MC68000ファミリー(PDF) . プログラマーズリファレンスマニュアル. NXP Semiconductors. 1992年. pp.  1– 16, 1– 18, 1– 23.
  18. ^ IEEE 754 2008、§4.3.1。「以下の2つの丸め方向属性において、少なくとも絶対値を持つ無限精度の結果は、符号を変更せずに丸められるものとするbemax(b12b1p){\displaystyle b^{\text{emax}}(b-{\tfrac {1}{2}}b^{1-p})}{\displaystyle \infty }
  19. ^ IEEE 754 2008、§4.3.3
  20. ^ IEEE 754 2019、§2.1
  21. ^ a b c IEEE 754 2008、§5.3.1
  22. ^ a b IEEE 754 2008、§5.4.1
  23. ^ IEEE 754 2008、§5.4.2
  24. ^ IEEE 754 2008、§5.4.3
  25. ^ IEEE 754 2008、§5.3.2
  26. ^ IEEE 754 2008、§5.3.3
  27. ^ IEEE 754 2008、§5.5.1
  28. ^ IEEE 754 2008、§5.10
  29. ^ IEEE 754 2008、§5.11
  30. ^ IEEE 754 2008、§5.7.2
  31. ^ IEEE 754 2008、§5.7.4
  32. ^ IEEE 754 2019、§5.11
  33. ^ a b c IEEE 754 2019、§5.10
  34. ^ "f32、f64 用の total_cmp を実装 by golddranks · Pull Request #72568 · rust-lang/rust" . GitHub .– IEEE 754-2008および-2019からの関連引用が含まれています。type-punの実装と説明が含まれています。
  35. ^ a b Herf, Michael (2001年12月). 「基数トリック」 .ステレオプシス: グラフィックス.
  36. ^ "9.4. decimal — 10進固定小数点および浮動小数点演算 — Python 3.6.5 ドキュメント" . docs.python.org . 2018年4月4日閲覧
  37. ^ 「10進演算 - 例外条件」speleotrove.com . 2018年4月4日閲覧
  38. ^ IEEE 754 2008、§7.2(h)
  39. ^ゴールドバーグ 1991 .
  40. ^ミュラー、ジャン=ミシェル;ブリセバーレ、ニコラス。デ・ディネシン、フィレンツェ。ジャンヌロ、クロード・ピエール。ルフェーブル、ヴァンサン。メルキオンド、ギョーム。ナタリー・レボル;ステレ、ダミアン。トーレス、セルジュ (2010)。浮動小数点演算ハンドブック(第 1 版)。ビルクホイザー土井: 10.1007/978-0-8176-4705-6ISBN 978-0-8176-4704-9
  41. ^ Wingo, Andy (2011-05-18). 「JavaScript実装における値表現」 . wingolog . 2025年8月21日時点のオリジナルよりアーカイブ。 2025年9月9日閲覧
  42. ^ Pall, Mike (2009-11-02). 「LuaJIT 2.0 知的財産の開示と研究機会」 . gmane.comp.lang.lua.general (Usenet) .オリジナル(メール)から2009-11-07にアーカイブ. 2025-09-09に取得. VMの設計上の側面: [...] NaNタグ: スタックスロットとテーブルスロットには、64ビットのタグ付き値が使用されます。
  43. ^ a b Kahan, William Morton ; Darcy, Joseph (2001) [1998-03-01]. 「Javaの浮動小数点があらゆる場所で誰に害を及ぼすか」(PDF) . 2000年8月16日時点のオリジナルよりアーカイブ(PDF) . 2003年9月5日閲覧.
  44. ^ Kahan, William Morton (1981-02-12). 「なぜ浮動小数点演算標準が必要なのか?」(PDF) . p. 26. 2004年12月4日時点のオリジナルよりアーカイブ(PDF) 。
  45. ^セヴァランス、チャールズ(1998年2月20日). 「浮動小数点の老師とのインタビュー」 .
  46. ^ a b Kahan, William Morton (1996年6月11日). 「コンピュータベンチマークの応用数学、物理学、化学への悪影響」(PDF) . 2013年10月13日時点のオリジナルよりアーカイブ(PDF) 。
  47. ^ IEEE 754 2019、§9.2
  48. ^ IEEE 754 2008、第9条
  49. ^ IEEE 754 2019、§9.2。
  50. ^ 「Too much power - pow vs powr, powd, pown, rootn, compound」 . IEEE . 2024年1月16日閲覧成長率は-1未満にはならないため、そのような成長率は無効な例外を示す。
  51. ^ 「Re: Missing functions tanPi, asinPi and acosPi」 IEEE . 2017年7月6日時点のオリジナルよりアーカイブ2018年4月4日閲覧。
  52. ^ IEEE 754 2008、§9.3。
  53. ^ IEEE 754 2008、§9.4。
  54. ^ IEEE 754 2019、§9.5
  55. ^ Riedy, Jason; Demmel, James. 「IEEE-754 2018に提案された拡張算術演算」(PDF) . 25th IEEE Symbosium on Computer Arithmetic (ARITH 2018). pp.  49– 56. 2019年7月23日時点のオリジナルよりアーカイブ(PDF) . 2019年7月23日閲覧
  56. ^ 「ANSI/IEEE Std 754-2019 – 背景資料」 IEEE 2024年1月16日閲覧
  57. ^ IEEE 754 2019、§9.6。
  58. ^ Chen, David. 「IEEE 754-2018からのMinNumおよびMaxNum演算の削除/降格」(PDF)IEEE . 2024年1月16日閲覧
  59. ^ Beeraka, Gautham (2021年12月14日). 「VS2022における/fp:contractフラグとFPモードの変更点」 . devblogs.microsoft.com . Microsoft . 2025年6月9日閲覧
  60. ^ 「最適化オプション(GNU コンパイラ コレクション(GCC)の使用)」gcc.gnu.org
  61. ^ "/fp (浮動小数点の動作を指定する)" . learn.microsoft.com .
  62. ^ 「浮動小数点を多用するコードは、x86ベースのアーキテクチャではビット正確な結果を生成しますか?」Stack Overflow
  63. ^ IEEE 754 2008、§5.12。
  64. ^ IEEE 754 2008、§5.12.2。
  65. ^ Gay, David M. (1990-11-30), 「2進数から10進数、10進数から2進数の変換を正しく丸める」 , Numerical Analysis Manuscript, Murry Hill, NJ, US: AT&T Laboratories, 90-10
  66. ^ Paxson, Vern; Kahan, William (1991-05-22) 「IEEE 10進数-2進数変換テストプログラム」、原稿、CiteSeerX 10.1.1.144.5889 
  67. ^ IEEE 754 2008、§5.12.3
  68. ^ 「6.9.3. 16進浮動小数点リテラル — Glasgow Haskell コンパイラ 9.3.20220129 ユーザーズガイド」 ghc.gitlab.haskell.org . 2022年1月29日閲覧

標準

二次参考文献

さらに読む