说我有:
float a = 3 // (gdb) p/f a = 3
float b = 299792458 // (gdb) p/f b = 299792448
然后
float sum = a + b // (gdb) p/f sum = 299792448
我认为它与尾数移位有关。有人能解释到底发生了什么吗? 32位
答案 0 :(得分:5)
32位浮点数只有24位精度。因此,a
float不能完全保持b
- 通过设置一些指数然后尾数尽可能接近它,它可以做到最好。
然后,当您考虑b
和a
的浮点表示并尝试添加它们时,加法运算会在尝试时向下移动小数a
的尾数匹配b
的指数,到值(3)从结尾落下的点,然后你离开0.因此,加法运算符最终将浮点零添加到b
。
答案 1 :(得分:3)
浮点数的精度有限。如果您使用的是float
,那么您只使用32位。但是,其中一些位保留用于定义指数,因此您实际上只能使用23位。你给出的数字对于那些23位来说太大了,所以忽略了最后几位数。
为了使这更加直观,假设除了2之外的所有位都保留给指数。然后我们可以毫无问题地表示0,1,2和3,但是我们必须增加指数。现在我们需要用2位表示4到16。所以可以表示的数字会有所分散:4和5不会同时存在。所以,4 + 1 = 4。
答案 2 :(得分:1)
你真正需要知道的有关舍入机制的一点是,你得到的结果是最接近正确答案的浮点数(如果正确的答案正好两个花车之间)。碰巧的是,您添加的较小数字小于该刻度上两个浮点数之间的距离的一半,因此结果与您添加的较大数字无法区分。这是正确的,在浮点精度的限制范围内。如果您想要更好的答案,请使用更精确的数据类型,例如double
。