16進浮動小数点(HFP)は、IBM System/360 コンピュータで初めて導入され、そのアーキテクチャに基づく後続のマシン [ 1 ] [ 2 ] [ 3 ] および System/360 とのアプリケーション互換性を意図したマシン[ 4 ] [ 5 ] でサポートされている浮動小数点数をエンコードするためのフォーマットです。
IEEE 754浮動小数点と比較すると、HFP形式は仮数部が長く、指数部が短くなっています。すべてのHFP形式は、バイアスが64の7ビットの指数部を持ちます。表現可能な数値の正規化された範囲は、16 −65から16 63(約5.39761 × 10 −79から7.237005 × 10 75)です。
この数値は次の式で表されます: (−1)符号× 0.仮数× 16指数−64。
単精度HFP数値(IBMでは「short」と呼ばれる)は32ビットワードに格納される。
この形式では、最初のビットは抑制されず、基数(16進数)の小数点(IBMのドキュメントや図では「小数」)は仮数(小数)の左側に設定されます。
基数が16であるため、この形式の指数はIEEE 754の同等の指数の約2倍になります。バイナリで同様の指数範囲を実現するには、9ビットの指数が必要になります。
値 −118.625 を HFP 単精度浮動小数点値としてエンコードすることを検討してください。
値が負なので、符号ビットは1です。
118.625 10のバイナリ値は1110110.101 2です。この値は、左端の桁がゼロになるまで、小数点を一度に 4 ビット (1 16 桁) 左に移動することで正規化され、0.01110110101 2となります。残りの右端の桁はゼロで埋められ、24 ビットの小数部 .0111 0110 1010 0000 0000 0000 2となります。
正規化された値は、基数小数点を16進数で2桁左に移動させ、乗数と指数は16 + 2 となります。指数(+2)に+64のバイアスを加えると+66となり、これは100 0010 2です。
符号、指数+バイアス、正規化された分数を組み合わせると、次のエンコーディングが生成されます。
つまり、表される数値は −0.76A000 16 × 16 66 − 64 = −0.4633789… × 16 +2 = −118.625です。
表現されている数値は +0.FFFFFF 16 × 16 127 − 64 = (1 − 16 −6 ) × 16 63 ≈ +7.2370051 × 10 75です
表現されている数値は +0.1 16 × 16 0 − 64 = 16 −1 × 16 −64 ≈ +5.397605 × 10 −79です。
ゼロ (0.0) は正規化形式ではすべてのビットがゼロとして表され、これは算術的には +0.0 16 × 16 0 − 64 = +0 × 16 −64 ≈ +0.000000 × 10 −79 = 0 となります。すべてのビットがゼロである部分がある場合、正または負の符号ビットとゼロ以外のバイアス指数の組み合わせは、算術的にゼロに等しくなります。ただし、CPU ハードウェアによって生成されるゼロの正規化形式は、すべてのビットがゼロです。これは、3 つの浮動小数点精度形式すべてに当てはまります。他の指数値との加算または減算では、結果の精度が失われる可能性があります。
基数が16であるため、バイナリ仮数部には最大3ビットの先頭ゼロが存在する可能性があります。つまり、数値をバイナリに変換すると、精度は21ビット程度しか得られない可能性があります。この「精度の変動」効果により、計算結果が非常に不正確になる場合があります。このことが大きな批判を招いています。[ 6 ]
不正確さの良い例として、10進数値0.1の表現が挙げられます。正確な2進数表現や16進数表現はありません。16進数形式では、0.19999999... 16または0.0001100110011001100110011001... 2と表現されます。つまり、次のようになります。
これは21ビットしか持たないのに対し、バイナリ版は24ビットの精度を持つ。
6桁の16進数の精度は、おおよそ6桁の10進数に相当します(つまり、(6 − 1) log 10 (16) ≈ 6.02)。単精度16進浮動小数点数を10進数文字列に変換するには、同じ16進浮動小数点数に戻すために、少なくとも9桁の有効数字(つまり、6 log 10 (16) + 1 ≈ 8.22)が必要になります。
倍精度HFPフォーマット(IBMでは「ロング」と呼ばれている)は、「ショート」フォーマットとほぼ同じだが、小数部の幅が広く、倍精度の数値がダブルワード(8バイト)に格納される点が異なる。
この形式の指数は、対応するIEEEバイナリ形式の範囲の約4分の1しかカバーしていません。
14桁の16進数精度は、おおよそ17桁の10進数精度に相当します。倍精度16進浮動小数点数を10進数文字列に変換して、同じ16進浮動小数点数に戻すには、少なくとも18桁の有効数字が必要です。
IBMが拡張精度と呼ぶ4倍精度HFPフォーマットは、System/370シリーズに追加され、一部のS/360モデル(S/360-85、-195、および特別な要求またはOSソフトウェアによるシミュレーションによるその他のモデル)で利用可能でした。拡張精度の小数部フィールドはより広く、拡張精度の数値は2つのダブルワード(16バイト)として格納されます。
28桁の16進数精度は、おおよそ32桁の10進数精度に相当します。拡張精度HFPを10進数文字列に変換する場合、同じHFP値に戻すには少なくとも35桁の有効数字が必要です。下位桁に格納される指数は、上位桁より14小さくなります。ただし、上位桁の指数が0未満になる場合はこの限りではありません。
利用可能な算術演算は、正規化および非正規化の両方の加算と減算、および比較です。事前正規化は指数差に基づいて行われます。乗算と除算は、事前正規化された非正規化値に対して行われ、結果は1桁のガード桁の後に切り捨てられます。2で割る処理を簡略化するための半分演算があります。ESA/390以降では、平方根演算が利用できます。すべての演算には、精度損失を避けるために1桁の16進ガード桁があります。ほとんどの算術演算は、単純なポケット電卓のように切り捨てられます。したがって、1 − 16 −8 = 1となります。この場合、結果はゼロから遠ざかるように丸められます。[ 7 ]
1998年のS/390 G5から[ 8 ] 、 IBMメインフレームには、 IEEE 754浮動小数点演算規格に準拠したIEEEバイナリ浮動小数点演算ユニットも搭載されるようになりました。IEEE十進浮動小数点演算は、 2007年にミリコード[ 10 ]を使用してIBM System z9 GA2 [ 9 ]に追加され、2008年にはハードウェアでIBM System z10に追加されました[ 11 ] 。
最新の IBM メインフレームは、3 つの浮動小数点基数と 3 つの 16 進数 (HFP) 形式、3 つの 2 進数 (BFP) 形式、および 3 つの 10 進数 (DFP) 形式をサポートしています。コアごとに 2 つの浮動小数点ユニットがあり、1 つは HFP と BFP をサポートし、もう 1 つは DFP をサポートしています。3 つの形式すべてを保持するレジスタ ファイル FPRs が 1 つあります。2015年のz13以降、プロセッサには、それぞれ 128 ビット幅の 32 個のベクトル レジスタを含むベクトル機能が追加されました。ベクトル レジスタには、2 つの 64 ビット浮動小数点数または 4 つの 32 ビット浮動小数点数を含めることができます。[ 12 ] 従来の 16 個の浮動小数点レジスタは新しいベクトル レジスタに重ねて配置されているため、一部のデータは従来の浮動小数点命令または新しいベクトル命令で操作できます。
IBM HFPフォーマットは以下で使用されています。
IBMはHFP形式を使用するハードウェアの唯一のプロバイダーであり、その形式をサポートするIBMマシンはメインフレームのみであるため、それを必要とするファイル形式はほとんどありません。例外の1つはFDAが要求するSAS 5トランスポートファイル形式です。この形式では、「ファイル内のすべての浮動小数点数はIBMメインフレーム表現を使用して格納されます。[...] ほとんどのプラットフォームは浮動小数点数にIEEE表現を使用します。[...] トランスポートファイルの読み書きを支援するために、IEEE表現(ビッグエンディアンまたはリトルエンディアン)からトランスポート表現に変換し、また元に戻すルーチンを提供しています。」[ 13 ] IBMの形式のコードはLGPLv2.1でも利用可能です。[ 15 ]
「IBM System/360 のアーキテクチャ」という記事では、この選択の理由として「浮動小数点加算におけるシフト前、オーバーフロー、シフト後の精度損失の頻度がこの選択によって大幅に減少する」と説明されています。[ 16 ]これにより、大規模な System/360 モデルではパフォーマンスが向上し、小規模なモデルではコストが削減されました。著者は精度損失の可能性を認識していましたが、64 ビット浮動小数点変数ではこれは重要ではないと想定していました。残念ながら、設計者はベンフォードの法則を認識していなかったようで、これは数値の大部分が精度低下の影響を受けることを意味します。
System/360 のアーキテクト 2 名による書籍「コンピュータ アーキテクチャ」では、1958~65 年の Sweeney の研究が引用されており、2 より大きい基数を使用することで、アライメントと正規化に必要なシフト数、特に必要な異なるシフト数が大幅に削減されることが示されています。実装を高速化するために基数を大きくし、8 ビット バイトを考慮すると基数 16 を選択するのは自然なことでした。32 ビット浮動小数点数は丸め誤差を伝播しない計算にのみ使用され、64 ビット倍精度はすべての科学計算および工学計算に使用される予定でした。倍精度の初期実装には適切な丸めを可能にするガード 桁がありませんでしたが、これは最初の顧客への納品後すぐに変更されました。[ 17 ]