正に減少する浮動小数点のソートされた配列を合計しようとしています。それらを合計する最良の方法は、低いものから高いものへと数値を合計し始めることであることがわかりました。その例を示すためにこのコードを作成しましたが、最大数から始まる合計の方が正確です。どうして?(もちろん、合計1 / k ^ 2はf = 1.644934066848226である必要があります)。
#include <stdio.h>
#include <math.h>
int main() {
double sum = 0;
int n;
int e = 0;
double r = 0;
double f = 1.644934066848226;
double x, y, c, b;
double sum2 = 0;
printf("introduce n\n");
scanf("%d", &n);
double terms[n];
y = 1;
while (e < n) {
x = 1 / ((y) * (y));
terms[e] = x;
sum = sum + x;
y++;
e++;
}
y = y - 1;
e = e - 1;
while (e != -1) {
b = 1 / ((y) * (y));
sum2 = sum2 + b;
e--;
y--;
}
printf("sum from biggest to smallest is %.16f\n", sum);
printf("and its error %.16f\n", f - sum);
printf("sum from smallest to biggest is %.16f\n", sum2);
printf("and its error %.16f\n", f - sum2);
return 0;
}
コードはdouble terms[n];
スタック上に配列を作成します。これにより、プログラムがクラッシュする前に実行できる反復回数に厳しい制限が課せられます。
ただし、この配列からは何もフェッチしないため、そこに配置する理由はまったくありません。私はあなたのコードを削除するために変更しましたterms[]
:
#include <stdio.h>
int main() {
double pi2over6 = 1.644934066848226;
double sum = 0.0, sum2 = 0.0;
double y;
int i, n;
printf("Enter number of iterations:\n");
scanf("%d", &n);
y = 1.0;
for (i = 0; i < n; i++) {
sum += 1.0 / (y * y);
y += 1.0;
}
for (i = 0; i < n; i++) {
y -= 1.0;
sum2 += 1.0 / (y * y);
}
printf("sum from biggest to smallest is %.16f\n", sum);
printf("and its error %.16f\n", pi2over6 - sum);
printf("sum from smallest to biggest is %.16f\n", sum2);
printf("and its error %.16f\n", pi2over6 - sum2);
return 0;
}
これを、たとえば10億回の反復で実行すると、最小優先アプローチの方がはるかに正確になります。
Enter number of iterations:
1000000000
sum from biggest to smallest is 1.6449340578345750
and its error 0.0000000090136509
sum from smallest to biggest is 1.6449340658482263
and its error 0.0000000009999996
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加