当我在C ++ Primier Plus中阅读关于浮点的章节时。
它给出了一个例子,如下所示:
#include <iostream>
int main(){
using namespace std;
float a = 2.34E+22f;
float b = a + 1.0f;
cout << "a =" << a <<endl;
cout << "b -a =" << b - a<< endl;
return 0;
}
结果是:
a = 2.34e+22
b -a = 0
本书的解释是,我引用:
&#34;问题是2.34E + 22表示左边23位的数字 小数。通过添加1,您尝试将1添加到该数字的第23位数字。的 但是 类型float只能表示数字中的前6位或7位数,因此尝试更改 第23位数字对该值没有影响。 &#34;
但我不明白。有人可以帮助我理解为什么b -a以可理解的方式为0吗?
答案 0 :(得分:2)
C / C ++中的float
类型以标准“单精度”格式存储。数字的格式为
±m*2^e
其中m
是2 23 和2 24 之间的整数,e
是整数。 (我遗漏了很多与此无关的细节。)
那么这是如何解释你所看到的?
首先,代码中的数字总是“舍入”到最近的浮点数。因此值2.34e+22
实际上舍入为10391687 * 2 51 ,即23399998850475413733376.这是a
的值。
其次,浮点运算的结果总是四舍五入到最接近的浮点数。因此,如果向a
添加1,结果为23399998850475413733377,它再次四舍五入到最近的浮点数,当然仍为23399998850475413733376.因此b
得到的值与a
。由于两个数字相等,a - b == 0
。
您可以向a
添加远大于1的数字,但仍会得到相同的结果。原因是结果是四舍五入的,当你添加至少2 50 或大约1e + 15的数字时,最接近的浮点数仍然是a
答案 1 :(得分:1)
b - a
为0
,因为b
和a
相等。
当你为一个大数字添加一个太小的数字时,就像你根本没有添加任何东西一样。
在这种情况下,“太小”将小于约2.34e + 15,即小7位数。
答案 2 :(得分:0)
单精度浮点类型float
是这样的(假设IEEE-754)
分数部分仅有23位,大约小于10 7 。当您向2.34E+22f
添加相当小的数字时,float
的精确度会限制结果的表示,因此b
最终会保留a
的未更改值。
答案 3 :(得分:0)
现有答案都是正确的(来自Mark Ransom和Yu Hao)。
非常简短的解释是浮点值不是很精确。在6或7位十进制数后,这些值将四舍五入。对于非常大的数字,这种不精确意味着价值的微小变化将变为零。即使+ 1
或+ 100
完成1000000000
,也可能是“非常小的变化”。