我正在查阅一本关于CUDA的书。
在解释CUDA浮点的章节中,我发现了一些奇怪的东西。
书中说(1.00 * 1)+(1.00 * 1)+(1.00 * 0.01)+(1.00 * 0.01)= 10.所有数字都是二进制数。 0.01表示十进制0.25。
因此,在十进制中串行加1 + 1 + 0.25 + 0.25会导致2。
这本书说明了为什么会这样;在做1 + 1之后,它将忽略+0.25,因为它与其他操作数相比太小(1 + 1,2的结果)。
在此之后,他们说做0.25 + 0.25 + 1 + 1将产生2.5,因为0.5被认为足以加1。
这是什么意思?处理器如何判断0.25与2相比太小?这有明显的标准吗?
答案 0 :(得分:1)
所有这些工作(或不工作)的机制是,如果将数字加在一起,则较小的一些精度(绝对值)会丢失。这来自执行操作的有限精度。
您总和的数字之间的差距越小,损失就越小。
在你的情况下,当你做1 + 1时,你得到2.然后0.25 比<2>小<10> 。你的书表明这是一个很大的因素,0.25很小,以至于它就像加0(在2的数量级上近似为0.25)。同样的事情发生在第二个0.25:它什么也没有增加。
当你从0.25 + 0.25开始时,你将添加两个相同大小的数字,所以你得到一个完美的0.5。然后当你添加1时,你要添加两个数字,其比率只有2 :这比前一个案例中的因子10要小得多,而且你的书说它可以完成,所以你总共得到1.5。然后是剩下的第1项:你要加1.5和1;两者之间的因素是只有1.5 ,所以,这可以做到,你得到2.5。
答案 1 :(得分:1)
该示例隐式声明了一个二进制浮点格式,它具有任意精度指数,但在尾数中只有2位。所有数字的格式均为1.xx * 2 ^ n。
当一个人执行浮点加法时,必须对参数进行反规范化或缩放以使其具有相同的指数。
0.25 = 1e-2 = 0.5e-1 = 0.25e0 = 0.125e1
2.00 = 1e1
但是在相同的基数0.125 = 0.001,这不能用小数点后的2位尾数表示。
即使我们添加字长,也没关系:
0.25 = 0.001000000000000000 (e=1)
2.00 = 1.000000000000000000 (e=1)
---------------------------------
2.25 = 1.001000000000000000 (e=1)
^^
结果将是小数点后的那两位,即(1.00e1)= 2。