浮点加法的问题。忽略一些小值

时间:2015-05-27 02:39:36

标签: math cuda floating-point

我正在查阅一本关于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相比太小?这有明显的标准吗?

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。