处理小数的简单C程序

处理小数的简单C程序,c,floating-point,decimal,average,C,Floating Point,Decimal,Average,可能重复: 所以程序只读取一组数字,然后除以输入的总数字,求出这些数字的平均值。然而,最终的结果在最后增加了几位小数,我不知道为什么会这样 对于此给定输入: 4831051188200,0 输出应为786.4 但实际上是786.400024。我做错了什么?谢谢各位 int main(int argc, char** argv) { int averageOfNumbers = 0; printf("Enter the sequence of numbers:"); i

可能重复:

所以程序只读取一组数字,然后除以输入的总数字,求出这些数字的平均值。然而,最终的结果在最后增加了几位小数,我不知道为什么会这样

对于此给定输入: 4831051188200,0

输出应为786.4 但实际上是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);

}

使用双精度将解决您的问题。浮子的精度和精度是问题的原因

浮点数提供了一个精确但不精确的实数近似值。(精度取决于它们的大小:您使用的浮点类型中有多少位精度可用。)

IEEE 754浮点(许多计算机上使用的一种非常流行的表示形式)使用二进制。这意味着精确表示二进制分数,如1/2、1/4、1/8及其组合:3/8、5/16等(在可用精度位的限制范围内)。不基于二次幂的分数不能精确表示

数字1/10或0.1没有精确的表示形式。当您将0.1输入机器时,它将转换为一个包含许多接近0.1的二进制数字的值。当你用
printf
或你所拥有的东西把它打印回来时,你又得到了
0.1
,因为
printf
函数将其舍入,所以它看起来像是
0.1
被准确地表示出来:
0.1
进入了机器,天哪,
0.1
出来了。假设需要10位小数精度才能看到
0.1
与实际值之间的差异,但您只打印到8位。当然,它将显示为
0.1
。您的浮点打印例程已切断错误

C printf中的
%f
转换说明符将使用更多的数字表示更大的数字,因为它使用超过小数点的固定位数,默认为六位。例如,0.002将打印为0.002000。但数字123456将打印为123456.000000。数量越大,打印的数字就越重要。当您使用%f打印786.4时,实际上要求的是9位小数精度。786整数部分3个,然后再增加6个

您使用的是
浮点
,它很可能是32位IEEE 754浮点。这只有24位精度。(1位用于符号,7位用于二进制指数,剩下24位。)24位仅相当于大约7位小数精度

因此,您要求机器将786.4(记住,对于786.4,它有一个不精确的表示法!)从只适用于大约7位十进制有效数字的浮点表示法打印到9位有效数字。您需要两个以上的精度数字,但这些数字不存在,因此会得到两个错误数字

因此,您可以使用更宽的字体,如
double
和/或更改打印结果的方式。不要要求这么多重要的数字。例如,尝试
%.3f
(小数点后三位)


顺便说一下,C中的
float
类型应该很少使用。您通常希望使用类型
double
<代码>浮点有它的用途,例如在大型数组中节省空间。

浮点类型不能以完美的精度表示所有数字-许多数字只能用浮点近似表示;这意味着,给定足够的有效数字,您最终将看到那些无法整齐地放入表示中的数字的精度损失

使用float数据类型的问题在于它是浮点类型中精度最低的。(C和C++中的默认浮点类型是<强>双——这是您应该使用的一种类型;除非使用了一些强制的理由否则,否则应避免使用<强>浮点< /St>。在现代32位桌面平台上,浮点对于某些近似数字可能只能精确到约6-7位有效数字,相同平台上的双精度对于相同数字可能精确到约13-14 s.f.(注:这是有效数字,而不是小数点!)


我强烈建议你花点时间阅读浮点数是如何工作的(在谷歌上输入,你会发现大量的解释!);了解它们在内部的表示方式将有助于您成为一名更好的程序员

家庭作业?如果是,请这样标记。您可以截断结果以隐藏不精确性,如
printf(“%.2f”,finalAverage)
ref:printf manual()使用一个double简单地将问题进一步隐藏起来。如果将该值打印到double下更重要的数字中,则会再次发现结果也没有double的精确表示形式。理解浮点将使您成为更好的数值分析师。如果你想成为一名更好的程序员,发誓在你的余生中不再使用浮点。我最近看了Gerald Sussman最近在infoq上的一次演讲,他承认只要代码中有浮点数,他就会感到害怕。哇,我的想法完全正确。:)谈话在这里:。评论大约在0:11:00开始。他说,“……浮点数字是危险的”和“没有什么比浮点数字更能让我感到恐惧”以及“数字分析:我所知道的最大的黑色艺术”。英雄联盟干杯