Cleve的角落:数学和计算上的Clyver

科学计算,数学及更多

半精度浮点对象中的错误

我在5月8日的帖子大约是“半精确”和“四分之一精确”算术。我还添加了对象的代码FP16andFP8克利夫的实验室。A few days ago I heard from Pierre Blanchard and my good friend Nick Higham at the University of Manchester about a serious bug in the constructors for those objects.

内容

错误

Let

formatE = EPS(FP16(1))
e= 9.765625000000000e-04

这value ofe

1/1024
ANS = 9.76562500000000000E-04

这是半精度浮点数的相对精度,即在1和2之间的间隔中半精度的间距

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

和2之前的最后一个数字是

disp(binary(2-e))
0 01111 111111111

显示的三个字段是符号,这是一个位,指数有五个位,分数有十位。

到现在为止还挺好。当我尝试转换任何数字之间的任何数字之间显示的错误2-eand2到半精度。这些限制之间不再有半精度的数字。间隔的下半部分的值应舍入到2-e上半部分的值应汇总到2。往返的大会说,中点,2-e/2那should round to2

But I wasn't careful about how I did the rounding. I just used the MATLABroundfunction, which doesn't follow the round-to-even convention. Worse yet, I didn't check to see if the fraction rounded up into the exponent field. I tried to do everything in one statement.

dbtypeOldFP1648:49
48 u = bitxor(uint16(圆形(1024*f)),... 49 bitshift(uint16(e+15),10));

对于之间的值2-e/2and2, 这round(1024*f)1024.,需要11位。这Bitxor然后将指数字段抓住。我不会在这里显示结果。如果您的计算机上有5月的半精度对象,请尝试一下。

这不仅发生在少于2的值的情况下,还会发生接近2的任何功率。

修复

我们需要一个适当的圆形最佳功能。

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

然后,不要一次尝试一次。

dbtypeFP1650:56
5.0.% 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));

It turns out that the branch for denormals is OK, onceround被取代rndeven。Denmals的指数为所有零,因此当分数侵蚀时会产生正确的结果。

季度构造函数需要类似的修复程序,FP8

克利夫的实验室

I am updating the code on theMatlab Central.文件交换。仅有的@fp16/fp16and@fp8/fp8被影响到的。(给我几天以完成更新过程。)

Thanks

Thanks to Pierre and Nick.




与Matlab®R2017A一起出版

|
  • 打印
  • 发送电子邮件

コメント

コメントを残すは,ここをクリックして MathWorks アカウントにサインインするか新しい MathWorks アカウントを作成します。