【问题标题】:Floating point numbers do not work as expected浮点数不能按预期工作
【发布时间】:2011-09-08 15:26:43
【问题描述】:

在下面的代码中,当我将输入作为 1 10 2 1 2 2 时,sum 打印为 52,sum3 打印为 31.200001,而它应该是 31.200000

int main(){

    int t,n,i,a[2000],m,j,f;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        scanf("%d",&f);
        for(i=0;i<f;i++){
            scanf("%d",&a[i]);
        }
        scanf("%d",&m);
        if(n!=0){
            int sum=n*(n+1)/2;
            int sum2=0;
            for(j=0;j<i;j++){
                sum2+=a[j];
            }
            sum-=sum2;
            printf("%d\n",sum);
            float sum3;
            if(n%2==0) sum3=(1.0-2.0*m/n)*sum;
            else sum3=(1.0-2.0*m/(n+1))*sum;
            printf("%f\n",sum3);
        }
        else printf("0.0000\n");
    }
    return 0;
}

【问题讨论】:

  • 不要在没有充分理由的情况下将float 用于浮点数:改用double。 “老师告诉我们使用float”是NOT在试图说服她之前使用float 的好理由;如果她坚持……哦,好吧……

标签: c floating-point


【解决方案1】:

来自the Floating-Point Guide:

为什么我的数字,比如 0.1 + 0.2 加起来不是很好的 0.3,而且 相反,我得到了一个奇怪的结果,比如 0.30000000000000004?

因为在内部,计算机使用一种格式(二进制浮点) 根本无法准确表示像 0.1、0.2 或 0.3 这样的数字。

当代码被编译或解释时,你的“0.1”已经 以该格式四舍五入到最接近的数字,这会导致小 甚至在计算发生之前就有舍入误差。

【讨论】:

    【解决方案2】:

    十进制数 31.2 不能表示为二进制分数。更具体地说,float 类型的最接近的值是 31.200000762939453125,正好是 8178893 * 2-18。

    如果您需要一个更接近十进制 31.2 的数字,请考虑使用类型 double,您的结果将是 31.199999999999999289457264239899814128875732421875 或 8782019273372467 * 2-48

    【讨论】:

      【解决方案3】:

      这是floats 的本质。不能保证它们完全准确。

      请参阅here,了解有关如何/为什么会出现这种情况的更多详细信息。

      【讨论】:

        【解决方案4】:

        31.2 不是二进制浮点数的可表示数字。无论使用什么计算来产生它,你永远不会得到一个正好等于 31.2 的浮点数。您得到的答案与您合理预期的一样好。

        【讨论】:

          【解决方案5】:

          .. 但是您可以尝试减少这种可能性。除其他事项外,您需要考虑加/减指数。

          【讨论】:

            【解决方案6】:

            你可以使用 printf("%g\n",sum3); 代替 printf("%f\n",sum3); 在您的代码中获得正确的输出..

            我希望它会起作用。

            【讨论】:

              猜你喜欢
              • 2018-09-27
              • 1970-01-01
              • 2015-06-26
              • 2013-05-28
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多