半精度浮点对象中的错误
我在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
format长E = 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.
コメント
コメントを残すは,ここをクリックして MathWorks アカウントにサインインするか新しい MathWorks アカウントを作成します。