2017-03-11 71 views
-2

我在同一組輸入上運行了以下2個代碼片段,除了第二個中的「namespace std」的用法相同之外。我無法理解他們產出不同的原因。有人能指導我嗎?謝謝!'using 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 「比特/ STDC++ H」 與標準的報頭。 2)用實際的代碼段替換圖像。

+3

[擺脫''東西](http://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h?noredirect= 1&lq = 1)幷包含適當的頭文件,以便我們有一個可以正確分析的標準C++程序。 – PaulMcKenzie

+0

@PaulMcKenzie按照建議進行編輯,問題仍然存在。 – piyukr

+0

的重載函數['雙對數()'](http://www.cplusplus.com/reference/cmath/log/)用於整型(由ildjarn疑似)投射的參數'double'做對數前。我在[ideone](http://ideone.com/cLSQqK)中檢查了這個(出於好奇)。嗯。從'double'到'long double'(在'operator + =()')中傳播會導致行爲嗎? – Scheff

回答

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進行編譯和運行時,獲得相同的輸出。

我與海灣合作委員會在Cygwin中選中此也可以在Windows 10(64位),並得到了以下的輸出:

$ 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; 
} 

編譯和Cygwin中使用gcc再次測試在Windows 10(64位):

$ 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()可能會導致奇怪的行爲,因爲格式化程序中有絲毫的錯誤。

+0

你的代碼在ideone上運行良好。但是,當我在我的電腦上運行時,輸出不正確。見http://imgur.com/a/Gxw9Q – piyukr

+0

@piyukr好的。在你的代碼中,你沒有使用標準頭文件。這能解釋不同的行爲嗎? – Scheff

+0

對不起,這是一個錯誤。我再次運行程序,這次是用標準頭文件。見http://imgur.com/a/MwFs6 – piyukr

相關問題