半精度浮点对象的错误

我5月8日的帖子是关于“半精度”和“四分之一精度”的算术。我还为对象添加了代码fp16而且fp8克里夫的实验室.几天前,我从曼彻斯特大学的Pierre Blanchard和我的好朋友Nick Higham那里得知,这些对象的构造函数中存在一个严重的bug。

内容

这个错误

格式E = eps(fp16(1))
E = 9.765625000000000e-04

的价值e

1/1024
Ans = 9.765625000000000e-04

这是半精度浮点数的相对精度,它是半精度数在1和2之间的间隔。在二进制中,1之后的下一个数是

disp(二进制(1 + e))
0 01111 0000000001

2之前的最后一个数是

disp(二进制(双电子))
0 01111 11111111

显示的三个字段是1位的符号,5位的指数和10位的分数。

到目前为止,一切顺利。当我试图转换之间的任何数字时,错误就出现了双电子而且2half-precision。在这些极限之间没有任何半精确的数字了。区间的下半部分的值应该四舍五入为双电子上半部分的值应该四舍五入为2.偶数惯例说,中点,双电子/ 2,应该圆到2

但是我没有注意到我是如何舍入的。我用了MATLAB函数,它不遵循整数到偶数的约定。更糟糕的是,我没有检查分数是否四舍五入到指数域。我试图在一个声明中完成所有事情。

dbtypeoldfp1648:49
48 u = bitxor(uint16(round(1024*f)),…49 bitshift (uint16 (e + 15), 10));

对于之间的值双电子/ 2而且2,圆(1024 * f)1024,需要11位。的bitxor然后重击指数场。我不会在这里显示结果。如果您的机器上有May半精度对象,请尝试一下。

这不仅适用于稍微小于2的值,它适用于2的任意次方。

修复

我们需要一个正确的从整数到最接近偶数的函数。

dbtypefp1631
31 rndevn = @(s) round(s-(rem(s,2)==0.5));

那就不要一次做完。

dbtypefp1650:56
50% normal 51 t = uint16(rndevn(1024*f));52 if t==1024 53 t= uint16(0);54 e = e+1;55 end 56 u = bitxor(t, bitshift(uint16(e+15),10));

结果证明,对于无法无天的分支是可行的,一次rndeven.非法线的指数都是零,所以当分数侵占时,它会产生正确的结果。

四分之一精度构造函数也需要类似的修正,fp8

克里夫的实验室

我正在更新代码MATLAB中央文件交换.只有@fp16 / fp16而且@fp8 fp8 /都受到影响。(给我几天时间来完成更新流程。)

谢谢

感谢皮埃尔和尼克。




发布与MATLAB®R2017a

|

评论

如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。