メインコンテンツまでスキップ

付録 D. 半精度

半精度浮動小数点数は 2008 年に IEEE 754 に追加されたばかりであるため、今日のプログラミングプラットフォームでは依然として限定的なサポートしかないことがよくあります。そのようなサポートがなくても、少なくともデコードのサポートを含めることは非常に簡単です。図 3 に、C 言語による半精度浮動小数点数の小さなデコーダーの例を示します。図 4 に Python による同様のプログラムを示します。このコードは、2 バイトの値がすでにネットワークバイトオーダーの (unsigned short) 整数としてデコードされていることを前提としています (付録 C の疑似コードが行うように)。

#include <math.h>

double decode_half(unsigned char *halfp) {
int half = (halfp[0] << 8) + halfp[1];
int exp = (half >> 10) & 0x1f;
int mant = half & 0x3ff;
double val;
if (exp == 0) val = ldexp(mant, -24);
else if (exp != 31) val = ldexp(mant + 1024, exp - 25);
else val = mant == 0 ? INFINITY : NAN;
return half & 0x8000 ? -val : val;
}

図 3: 半精度デコーダーの C コード

import struct
from math import ldexp

def decode_single(single):
return struct.unpack("!f", struct.pack("!I", single))[0]

def decode_half(half):
valu = (half & 0x7fff) << 13 | (half & 0x8000) << 16
if ((half & 0x7c00) != 0x7c00):
return ldexp(decode_single(valu), 112)
return decode_single(valu | 0x7f800000)

図 4: 半精度デコーダーの Python コード