跳到主要内容

附录 D. 半精度 (Half-Precision)

由于半精度浮点数直到 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 代码