为什么在大型浮子上添加一个小浮子只会掉落一个小浮子?

说我有:

float a = 3 // (gdb) p/fa = 3 float b = 299792458 // (gdb) p/fb = 299792448 

然后

 float sum = a + b // (gdb) p/f sum = 299792448 

我认为它与尾数移动有关。 有人能解释到底发生了什么吗? 32位

32位浮点数只有24位精度。 因此,一个浮点数不能精确地保持b – 通过设置一些指数然后尾数尽可能接近它可以做到最好。

然后当你考虑b和a的浮点表示,并尝试添加它们时,加法运算会将小数a的尾数向下移动,因为它试图匹配b的指数,直到值(3)从关闭点开始。结束,你留下0.因此,加法运算符最终将浮点零添加到b。

浮点数的精度有限。 如果你使用float ,那么你只使用32位。 但是,其中一些位保留用于定义指数,因此您实际上只能使用23位。 您提供的数字对于这23位而言太大,因此忽略最后几位数字。

为了使这更直观一些,假设除了2之外的所有位都保留给指数。 然后我们可以毫无问题地表示0,1,2和3,但是我们必须增加指数。 现在我们需要用2位代表4到16。 所以可以表示的数字会有所分散:4和5不会同时存在。 所以,4 + 1 = 4。

你真正需要知道的关于舍入机制的是你获得的结果是最接近正确答案的浮点数(如果正确的答案恰好在两个浮点数之间,则有一些额外的规则决定该怎么做)。 碰巧的是,您添加的较小数字小于该刻度上两个浮点数之间的距离的一半,因此结果与您添加的较大数字无法区分。 这是正确的 ,在浮动精度的限制范围内。 如果您想要更好的答案,请使用更精确的数据类型,例如double