'使用命名空间std'导致一种奇怪的行为

时间:2017-03-11 06:34:46

标签: c++ c++11 namespaces c++14 format-specifiers

我在同一组输入上运行了以下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&#34; bits / stdc ++。h&#34;标准标题。 2)用实际代码替换图像。

1 个答案:

答案 0 :(得分: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()会导致奇怪的行为。