FP16 最大数量

FP16 max number

看下面的代码时,我没看懂,127、16、23是从哪里来的?我知道127、16的位表示,还有移位操作,但是没办法把它们放在一起。

const FP32 f16max = { (127 + 16) << 23 };

这来自https://eigen.tuxfamily.org/dox/Half_8h_source.html

的第358行

我知道这意味着 1.0:

0011 1111 1000 0000 0000 0000 0000 000

127一定是011 1111 1,左移23就是去掉所有的尾数。这 16 在这里做什么?

该代码构成了一个single-precision浮点数的位表示,值为65536.0。

在single-precision格式中,低23位是尾数的小数部分,接下来的8位是指数加127。所以(127 + 16) << 23表示数1.0 * 216 = 65536.0,比最大可能的half-precision浮点数多了一点。

IEEE 754 single-precision 二进制 floating-point 数字具有以下表示形式:

这里的指数是一个从 0 到 255 的 8 位无符号整数,偏差为 127。或者,你可以说它是一个从 −128 到 127 的有符号整数。然后该数字被解码为:

(−1)b31 (1 + Sum(b23−i 2i; i = 22 … 0 )) × 2e − 127

您提到的行使用 data-type float32_bits 定义为:

union float32_bits {
   unsigned int u;
   float f;
};

所以由于float32_bits是一个联合,整数u和浮点数f占用相同的内存space。这就是为什么当您看到符号为:

const float32_bits f16max = { (127 + 16) << 23 };

你应该理解为将一个bit-pattern赋值给一个浮点数。通过上面的解释,你看到127只不过是上面公式中的偏差补偿,而23是将位移动到浮点数的指数部分的移位。

所以变量f16max表示216为浮点数f16max.f和143·223 作为无符号整数 f16max.u.

有趣的读物:

图片来自维基百科:Single-precision floating-point format