可能重复:
strange output in comparision of float with float literal
因此,程序只读取一堆数字,并通过除以输入的总数来找到平均数。但是,最终结果最后会增加几个小数,我不知道为什么会这样做。
对于这个给定的输入: 483,10,3051,188,200,0
输出应为786.4 但是INSTEAD是786.400024。我究竟做错了什么?先谢谢费拉斯。
int main(int argc, char** argv)
{
int averageOfNumbers = 0;
printf("Enter the sequence of numbers:");
int nextNumber;
float numberCounter = 0;
do
{
scanf("%d", &nextNumber);
if(nextNumber > 0)
{
numberCounter++;
averageOfNumbers += nextNumber;
}
}
while(nextNumber > 0);
float finalAverage = (float) (averageOfNumbers/numberCounter);
averageOfNumbers = averageOfNumbers/numberCounter;
printf("Average of the numbers in the sequence is %f\n", finalAverage);
}
答案 0 :(得分:3)
浮点数提供了对实数的精确但不精确的近似。 (精确度取决于它们的大小:您正在使用的浮点类型中有多少精度位。)
IEEE 754浮点(在许多计算机上使用的非常流行的表示)使用二进制。这意味着二进制分数如1/2,1 / 4,1 / 8及其组合:3 / 8,5 / 16等精确表示(在可用的精度位数的限制范围内)。不基于2的幂的分数不能完全表示。
数字1/10或0.1没有确切的表示。当您在机器中输入0.1时,它将转换为具有许多二进制数字的值,该值接近0.1。当您使用printf
或有你的内容打印回来时,再次获得0.1
,因为printf
函数会将其四舍五入,因此看起来0.1
正好代表0.1
:0.1
进入机器,然后由0.1
出来。假设它需要10个十进制数字的精度来查看0.1
和实际值之间的差异,但是您只打印到8位数。好吧,当然它会显示为%f
。您的浮点打印程序已将错误切断!
C printf中的float
转换说明符将对更大的数字使用更多的数字,因为它使用小数点后的固定位数,默认值为6。因此,例如0.002将打印为0.002000。但数字123456将打印为123456.000000。数量越大,打印的数字越多。当您使用%f打印786.4时,您实际上要求9个十进制数字的精度。三个为786整数部分,然后是另外六个。
您正在使用double
,这很可能是32位IEEE 754浮点数。这只有24位精度。 (1位用于符号,7位用于二进制指数,剩下24位。)24位相当于大约7位精度的十进制数字!
所以,你要求机器打印786.4(它有一个不精确的表示,请记住!)到九个有效数字,从浮点表示只有大约7个十进制有效数字。你要求两个以上的精度数字不存在,因此得到两个错误数字。
所以你可以做的是使用像%.3f
这样更广泛的类型和/或改变你打印结果的方式。不要问这么多重要人物。例如,尝试float
(小数点后三位数)。
C中的double
类型应该很少使用。您通常希望使用类型float
。 {{1}}有其用途,例如在大型数组中节省空间。
答案 1 :(得分:0)
使用double可以解决您的问题。浮子的精度和精度是问题的原因。
答案 2 :(得分:0)
浮点类型不能完美地表示所有数字 - 许多数字只能用浮点表示;这意味着给定足够有效的数字,你最终会看到那些不能完全适合表示的数字的精度损失。
使用 float 数据类型的问题在于它是浮点类型中最不准确的。 (C和C ++中的默认浮点类型是 double - 这是您应该使用的;您应该避免使用 float ,除非您有一些令人信服的理由使用它除此以外)。在现代的32位桌面平台上,对于某些近似数字, float 可能只能精确到6-7个有效数字,同一平台上的 double 可能是准确的大约13-14平方英尺的相同数字(注意:这是重要的数字而不是小数位!)。
我强烈建议您花点时间阅读浮点数的工作方式(将其输入谷歌,你会发现大量的解释!);了解它们如何在内部表现将有助于使您成为更好的程序员