1 + 1 * 2 + 1 * 2 * 3 + 1 * 2 * 3 * 4 + ... + 1 * 2 * ... * n
を計算しようとしています。n
はユーザー入力です。 n
の値が12までの場合に機能します。n = 13
、n = 14
、およびn = 15
の合計を計算します。 C89でこれを行うにはどうすればよいですか?私が知っているように、unsigned long long int
はC99またはC11でのみ使用できます。
私のコード:
#include <stdio.h>
#include <stdlib.h>
int main()
{
unsigned long int n;
unsigned long int P = 1;
int i;
unsigned long int sum = 0;
scanf("%lu", &n);
for(i = 1; i <= n; i++)
{
P *= i;
sum += P;
}
printf("%lu", sum);
return 0;
}
実際には、 任意精度の算術演算 (別名bigintまたはbignum)ライブラリ。私の推奨は GMPlib ですが、 その他のもの があります。
独自のbignumライブラリをコーディングしようとしないでください。効率的で賢いアルゴリズムが存在しますが、それらは直感的ではなく、把握するのが困難です(その質問に関する本全体を見つけることができます)。さらに、GMPlibのような既存のライブラリは、標準のCコンパイラが発行しない特定のマシン命令(たとえば [〜#〜] adc [〜#〜] -add with carry)を利用しています。純粋なCコード)。
これが宿題であり、外部コードの使用が許可されていない場合は、たとえば、baseまたは radix 1000000000(10億)で数値を表すことを検討し、非常に単純な方法で操作をコーディングしますあなたが子供として学んだこと。しかし、より効率的なアルゴリズムが存在することに注意してください(そして実際のbignumライブラリがそれらを使用している)。
数値は、それぞれがベース1000000000の「数字」であるunsigned
の配列を持つことにより、ベース1000000000で表すことができます。したがって、配列(おそらくmalloc
を使用して割り当てられるヒープ)それらの長さ。
特にプラットフォームでIEEE754を使用している場合は、double
を使用できます。
このようなdouble
を使用すると、53ビットの精度が得られます。つまり、整数は53の2乗まで正確です。この場合はこれで十分です。
プラットフォームでIEEE754を使用していない場合は、採用されている浮動小数点スキームに関するドキュメントを参照してください。それmight適切である。
MaxIntの制限を超えたときの簡単なアプローチは、適切なnに対して10 ^ nを法とする計算を行い、浮動小数点計算と同じ計算を行いますが、すべてを10 ^ rで除算することです。前者の結果は、最初のn桁を返し、後者の結果は、最初のr桁が削除された答えの最後の桁を返します。この場合、ここの最後の数桁は丸め誤差のために不正確になるため、nより少し小さいrを選択する必要があります。この場合、n = 9およびr = 5を使用するとうまくいきます。