擺弄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()
可能會導致奇怪的行爲,因爲格式化程序中有絲毫的錯誤。
[擺脫''東西](http://stackoverflow.com/questions/31816095/why-should-i-not-include-bits-stdc-h?noredirect= 1&lq = 1)幷包含適當的頭文件,以便我們有一個可以正確分析的標準C++程序。 –
PaulMcKenzie
@PaulMcKenzie按照建議進行編輯,問題仍然存在。 – piyukr
的重載函數['雙對數()'](http://www.cplusplus.com/reference/cmath/log/)用於整型(由ildjarn疑似)投射的參數'double'做對數前。我在[ideone](http://ideone.com/cLSQqK)中檢查了這個(出於好奇)。嗯。從'double'到'long double'(在'operator + =()')中傳播會導致行爲嗎? – Scheff