以下代码似乎总是会产生错误的结果。我在gcc和windows visual studio上测试过它。是因为浮动溢出还是其他什么?在此先感谢:)
#include <stdio.h>
#define N 51200000
int main()
{
float f = 0.0f;
for(int i = 0; i < N; i++)
f += 1.0f;
fprintf(stdout, "%f\n", f);
return 0;
}
答案 0 :(得分:13)
float
只有23位精度。 512000000需要26.简单地说,你没有正确答案所需的精度。
答案 1 :(得分:2)
有关C中数据类型精度的更多信息,请参阅this。
当您超出定义的精度时,您的代码会出现异常行为。
答案 2 :(得分:2)
与浮点运算有关的不可靠的事情包括当它们在幅度上非常不同时将两个数字相加,并且当它们在幅度上相似时减去它们。首先是你在这里做的事情; 1&lt;&lt; 51200000.CPU将其中一个数字标准化,使它们具有相同的指数;当另一个操作数很大时,它会将实际值(1)从可用精度的末尾移开,所以当你在计算的一部分时,一个已经(大约)等于零。
答案 3 :(得分:2)
您的问题是unit of least precision。短:大浮点值不能用小值递增,因为它们将四舍五入到下一个有效浮点数。虽然1.0足以增加小值,但16777216的最小增量似乎是2.0(检查java Math.ulp,但也适用于c ++)。
Boost为this提供了一些功能。
答案 4 :(得分:0)
float
的精度仅为7位数。将数字1
添加到大于2^24
的浮点数会产生错误的结果。使用double
类型代替float
,您将获得正确的结果。
答案 5 :(得分:0)
在编辑问题中的代码时,我遇到了一个未阻止的for loop
:
#include <stdio.h>
#define N 51200000
int main() {
float f = 0.0f;
for(int i = 0; i < N; i++) {
f += 1.0f;
fprintf(stdout, "%f\n", f);
}
return 0;
}