【问题标题】:In what situation the output could go wrong like this?在什么情况下输出可能会出现这样的错误?
【发布时间】:2022-01-24 05:42:52
【问题描述】:

我正在尝试在 codeforces 上解决问题200B。我测试了我的代码,输出没问题。但是当我将它上传到在线法官系统时,我在第一个测试案例中失败了。它说我的输出是 -0.000000000000,而不是 66.666666666667。
但我已经在 Visual Studio C++ 2010、MacOS clang 13.0.0 和 Linux GCC 6.3.0 上编译并运行,输出都和我的一样,66.666666666667。我很好奇,想知道在什么情况下输出可能是-0.000000000000。
在我的电脑上,
输入:
3
50 50 100
输出:
66.666666666667
在线裁判系统上,
输入:
3
50 50 100
参与者的输出
-0.000000000000
陪审团的回答
66.666666666667
检查员评论
错误答案第一个数字不同 - 预期:'66.66667',发现:'-0.00000',错误 = '1.00000'

#include <stdio.h>

int main(void)
{
    int n;
    double sumOrange = 0;
    double sumDrink = 0;
    scanf ("%d", &n);
    
    while (n-- > 0) {
        int m;
        scanf("%d", &m);

        sumOrange += m / 100.0;
        sumDrink++;
    }

    printf("%.12lf\n", (sumOrange / sumDrink) * 100.0);
    return 0;
}

我只是不明白为什么我的输出可能是 -0.000000000000。请帮忙,谢谢。

更新:在不同版本的 GCC(4.9、5.1、6.3)上测试,没有出现错误输出。猜测原因可能在于printf的具体实现。

【问题讨论】:

  • 顺便用这个格式字符串 %.12f 而不是这个 %.12lf
  • Leon,除此之外:可以删除 / 100.0* 100.0。他们只会在计算中注入微小的错误。
  • @chux-ReinstateMonica,是的,你是对的。我只是对输出感到困惑。于是我想尽办法寻找原因,但都失败了。
  • @VladfromMoscow,感谢您的评论。我刚刚更新了我的代码并通过了测试,但我仍然想知道编译的可执行文件何时、在什么情况下或通过什么编译器会产生这个错误。我刚试过Windows编译器VS 2010,Linux GCC和MacOS XCode(clang),输出都一样,没问题。
  • 对于sumDrink++',请参阅:Is floating point math broken?Why Are Floating Point Numbers Inaccurate?Floating point comparison a != 0.7。例如,float f = 1.1; 实际上是1.100000023842。在f++; 之后,你有2.099999904633 -- 请注意后增量的浮点数学方面。

标签: c


【解决方案1】:

问题是因为 GNU gcc C11 中的printf 函数不支持%.12lf 格式。应该改成%.12f更多信息,可以阅读下面的文章:

Correct format specifier for double in printf

【讨论】:

  • 谢谢。我很高兴知道问题的原因,但我真正想要的是尽可能得到错误的输出。
  • 可能取决于 GCC 版本。 codeforces 中的 GCC 版本是 5.1,而你的 VS C++ 版本是 13.0(clang),所以它只能代表低 GCC 中的错误答案。也许新版本的clang修复了%lf问题,它会自动将%lf转换为%f。因此,您无法在 VS C++ 中表示错误输出。
  • %.12lf works fine in GCC 5.1。它实际上是实现printf 的 GNU C 库,而不是 GCC。但问题出在网上评委的C实现,没有说明版本。
  • @EricPostpischil 我在 Debian jessie 上尝试了 GCC 4.9,输出也还可以。我同意你的看法。原因应该在于printf的具体实现。真的很高兴我学到了一些我不明白的东西。
猜你喜欢
  • 2011-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-25
  • 2020-07-28
  • 1970-01-01
  • 2021-08-06
  • 1970-01-01
相关资源
最近更新 更多