C言語では、一般的なデータ型はshort、intなどのデータ型です。小さい数を格納して表現する場合は問題ありませんが、大きい数を格納して表現する場合はデータが表示されます。オーバーフローの問題については、例としてfactorial。intデータを使用すると、13までのfactorialデータがオーバーフローします。結果は1932053504(Codeblocksを使用)ですが、これは明らかに間違っています。
では、この問題をどのように解決するのでしょうか?ここで使用することを検討している重要なツールの1つは配列です。基本的な考え方は、階乗プロセス中に取得された各桁の数を配列の要素に割り当てることです。配列内の要素が階乗よりも大きいように見える場合プロセス10に等しい数値の場合、その桁上げを取得して前の桁に配置します(逆順の出力、つまり配列要素の最後の出力のため)、ローカル要素は1桁の桁上げに更新されます。このプロセスでは、解決する必要のある最上位の問題、つまり出力の開始点があります。最上位はデフォルトで0です(配列添え字は0から始まります。最上位の配列要素も10以上の数値を取得する場合、最上位ビット+1の操作も必要です。
実際、基本的な考え方を読んだ後は、多くの友達がこのプログラムを大まかに理解していると思いますが、実際にコードを使って書く方法にはまだ問題があるかもしれません。
#include<stdio.h>
int main(){
int arr[50]={
1}; //数组的大小可以根据需要设置,这里我按照50来编写的,数组第一位(arr[0])设置为1,其余为0//
int high=0; //设置最高位//
int i; //历遍数组的下标//
int j=1; //阶乘起点//
int n; //阶乘终点//
int temp[50]; //进位的数组//
int flag;
scanf("%d",&n);
while(j<=n){
for(i=0;i<=high;i++){
arr[i]=arr[i]*j; //数组每一位元素与n之前的数相乘//
temp[i]=arr[i]/10; //求每一个数组元素的进位置于temp数组中//
if(i==0) arr[i]=arr[i]%10; //数组元素求本位,本位为本位元素的个位与前一位元素的进位之和//
else arr[i]=arr[i]%10+temp[i-1];
if(i==high&&temp[i]>0){
//当数组最高位的元素有进位时最高位改变//
high=high+1;
arr[high]=temp[i]; //最高位元素的更新//
break;
}
else ;
}
j++;
}
//下面的循环将进位后得到的数组元素中所有能继续进位的元素继续进位,进位不彻底是一个很容易犯的错误!!//
do{
flag=0; //每次循环执行时先设置flag变量为0//
for(i=0;i<50;i++){
//先将temp数组中元素全部置为0,防止进位后的temp数组不能覆盖掉原来temp数组非0的元素,从而进入死循环//
temp[i]=0;
}
for(i=0;i<=high;i++){
//与上同//
temp[i]=arr[i]/10;
arr[i]=arr[i]%10+temp[i-1];
if(i==high&&temp[i]>0){
high=high+1;
arr[high]=temp[i];
break;
}
}
for(i=0;i<50;i++){
//如果进位后的temp数组中还有非0的元素说明进位不彻底,flag赋值为1,继续进位//
if(temp[i]) flag=1;
}
}while(flag);
printf("%d的阶乘:",n);
for(i=high;i>=0;i--){
//从最高位开始逆序输出//
printf("%d ",arr[i]);
}
printf("\n");
}
コードをデバッグしましたが、問題はないはずです。テストしたデータはプログラムのバグを回避できる可能性があるため、再度デバッグするときは、さらにいくつかのデータセットをテストすることをお勧めします。
この記事がすべての人に役立つことを願っています。コードに問題や単純化がある場合は、批判して修正することを歓迎します。
最後に、皆さんを励まし、プログラミングを学ぶ道を一緒に前進したいと思います!