'using namespace std' 导致了奇怪的行为

'using namespace std' is causing a strange behaviour

我 运行 以下 2 个代码片段在同一组输入上,除了第二个 "namespace std" 的用法外,它们是相同的。我无法理解他们的输出不同的原因。有人可以指导我吗?谢谢!

计划 1:

#include<cmath>
#include<cstdio>
//using namespace std;
int main() {
    int i, p, q, r, s;
    while (scanf("%d %d %d %d", &p, &q, &r, &s) == 4) {
        long double ans = 0;
        if (p - q < q)
            q = p - q;
        if (r - s < s)
            s = r - s;
        for (i = 1; i <= q; i++)
            ans += log(p - q + i) - log(i);
        for (i = 1; i <= s; i++)
            ans -= log(r - s + i) - log(i);
        printf("%.5lf\n", exp(ans));
    }
    return 0;
}

输出 1:

0.12587
505606.46055
1.28223
0.48996
2.00000
3.99960

http://ideone.com/x7n5cm

计划 2:

#include<cmath>
#include<cstdio>
using namespace std;
int main() {
    int i, p, q, r, s;
    while (scanf("%d %d %d %d", &p, &q, &r, &s) == 4) {
        long double ans = 0;
        if (p - q < q)
            q = p - q;
        if (r - s < s)
            s = r - s;
        for (i = 1; i <= q; i++)
            ans += log(p - q + i) - log(i);
        for (i = 1; i <= s; i++)
            ans -= log(r - s + i) - log(i);
        printf("%.5lf\n", exp(ans));
    }
    return 0;
}

输出 2:

0.00000
0.00000
0.00000
0.00000
0.00000
0.00000

http://ideone.com/meDkRh

输入:

10 5 14 9
93 45 84 59
145 95 143 92
995 487 996 488
2000 1000 1999 999
9998 4999 9996 4998

编辑: 1) 将#include "bits/stdc++.h" 替换为标准 headers。 2) 用实际代码替换图像。

在摆弄 log() 和怀疑 operator += () 之后,我终于解决了这个难题。

实际错误是由printf("%.5lf\n", ...)造成的。

我稍微修改了示例代码来演示:

#include<cmath>
#include<cstdio>
#include<iomanip>
#include<iostream>
using namespace std;
int main() {
    int i, p, q, r, s;
    while (scanf("%d %d %d %d", &p, &q, &r, &s) == 4) {
        long double ans = 0;
        if (p - q < q)
            q = p - q;
        if (r - s < s)
            s = r - s;
        for (i = 1; i <= q; i++)
            ans += log(p - q + i) - log(i);
        for (i = 1; i <= s; i++)
            ans -= log(r - s + i) - log(i);
        printf("printf: %.5lf", exp(ans));
        cout << "\tcout: " << fixed << setprecision(5) << exp(ans) << endl;
    }
    return 0;
}

现在的输出是:

printf: 0.00000 cout: 0.12587
printf: 0.00000 cout: 505606.46055
printf: 0.00000 cout: 1.28223
printf: 0.00000 cout: 0.48996
printf: 0.00000 cout: 2.00000
printf: 0.00000 cout: 3.99960

我在 ideone 上查看过这个。 我在 Windows 10(64 位)上使用 VS2013 编译和 运行 时得到的相同输出。

我也在 Windows 10(64 位)上用 cygwin 中的 gcc 检查了这个并得到以下输出:

$ g++ -std=c++11 -o test-longdouble test-longdouble.cc ; echo '10 5 14 9
> 93 45 84 59
> 145 95 143 92
> 995 487 996 488
> 2000 1000 1999 999
> 9998 4999 9996 4998
> ' | ./test-longdouble
printf: -0.00000        cout: 0.12587
printf: -4234002535919089587818586571373347278663379000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00000        cout: 505606.46055
printf: -0.00000        cout: 1.28223
printf: -65094314467486612925155033958017324735054040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00000     cout: 0.48996
printf: nan     cout: 2.00000
printf: nan     cout: 3.99960

$ g++ -std=c++14 -o test-longdouble test-longdouble.cc ; echo '10 5 14 9
93 45 84 59
145 95 143 92
995 487 996 488
2000 1000 1999 999
9998 4999 9996 4998
' | ./test-longdouble
printf: -0.00000        cout: 0.12587
printf: -4234002535919089587818586571373347278663379000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00000        cout: 505606.46055
printf: -0.00000        cout: 1.28223
printf: -65094314467486612925155033958017324735054040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.00000     cout: 0.48996
printf: nan     cout: 2.00000
printf: nan     cout: 3.99960

$ g++ --version
g++ (GCC) 5.4.0

第一眼没看出来但是cout输出是正确的,只有printf输出不一样

考虑到 printf 格式化程序选择错误,您不应该对其效果有任何期望

然后我在printf()中修正了错误的格式:

#include<cmath>
#include<cstdio>
#include<iomanip>
#include<iostream>
using namespace std;
int main() {
  int i, p, q, r, s;
  while (scanf("%d %d %d %d", &p, &q, &r, &s) == 4) {
    long double ans = 0;
    if (p - q < q)
      q = p - q;
    if (r - s < s)
      s = r - s;
    for (i = 1; i <= q; i++)
      ans += log(p - q + i) - log(i);
    for (i = 1; i <= s; i++)
      ans -= log(r - s + i) - log(i);
    printf("printf: %.5Lf", exp(ans));
    cout << "\tcout: " << fixed << setprecision(5) << exp(ans) << endl;
  }
  return 0;
}

在 Windows 10(64 位)上用 cygwin 中的 gcc 再次编译和测试:

$ g++ -std=c++14 -o test-longdouble test-longdouble.cc ; echo '10 5 14 9
93 45 84 59
145 95 143 92
995 487 996 488
2000 1000 1999 999
9998 4999 9996 4998
' | ./test-longdouble
printf: 0.12587 cout: 0.12587
printf: 505606.46055    cout: 505606.46055
printf: 1.28223 cout: 1.28223
printf: 0.48996 cout: 0.48996
printf: 2.00000 cout: 2.00000
printf: 3.99960 cout: 3.99960

因此,我只能重复我在评论中已经说过的话:你真的应该使用 C++ 流输出。 printf() 可能由于格式化程序中最轻微的错误而导致奇怪的行为。