0

我有一个示例 50.33123 可以以 FP32(1.8.23) 格式存储为 0x4249532E 。如果我们将其转换为二进制

0100 0010 0100 1001 0101 0011 0010 1110

第一位是符号位,0表示正数,

接下来的 8 位是指数 -> 1000 0100 2 -> 84 16 -> 132 10。指数 132 -127 =5

尾数1.1001 0010 1010 0110 0101 110(23 位)

左移我的指数 => 110010.010101001100101110 2 => 50.33123 10

如果我们以 FP16(半精度格式)FP16 => 1.5.10 存储相同的内容:

不四舍五入
1.1001 0010 10 2 左移 5 => 110010.01010 2 => 50.3125 10
误差为 50.33123 - 50.3125 => 0.01873。

四舍五入
1.1001 0010 11 2 => 左移 5 => 110010.01011 2 => 50.34375 10
误差为 50.33123 - 50.34375 = -0.01252

我的问题是,这里的错误很重要。
有没有办法通过 FP16 实现进一步减少错误?

4

1 回答 1

0

我们如何使用 FP16 半精度浮点数来最小化精度误差

Fp16 => 1.5.10fp_16以二进制浮点格式显式存储 10 位精度。使用隐含位,它提供的值的最后一个位置的单位是最高有效位的 2 -10。50.33123 作为 afloat的精确值为50.33123016357421875or 0x1.92A65Cp+5。通过舍入以最小化精度误差,最接近的值fp_1650.343750x1.92Cp+5

OP 已完成此舍入以最小化错误。


...这种情况下的错误是 50.33123 - 50.34375 = -0.01252
我的问题是,这里的错误很重要。有什么方法可以通过 FP16 实现进一步减少错误?

这 0.02% 的差异并不出人意料。在不更改1.5.10格式或保存如下附加值的情况下,这种精度损失是不可避免的。

float a = 50.33123f;
a_fp16_upper = (fp_16) a;
a_fp16_lower = (fp_16) (a - a_fp16_upper);
于 2017-06-10T19:31:02.363 回答