中止陷阱:6(计算长数因子)

时间:2016-04-12 16:31:18

标签: c factorial

我正在按照以下函数来计算大数link的阶乘,我想了解更多为什么会发生一些事情......

#include<stdio.h>
#define MAX 10000
void factorialof(int);
void multiply(int);
int length = 0;
int fact[MAX];

int main(){
    int num;
    int i;

    printf("Enter any integer number : ");
    scanf("%d",&num);

    fact[0]=1;

    factorialof(num);

    printf("Factorial is : ");
    for(i=length;i>=0;i--){
         printf("%d",fact[i]);
    }
    return 0;
}

void factorialof(int num){
    int i;
    for(i=2;i<=num;i++){
         multiply(i);
    }
}
void multiply(int num){
    long i,r=0;
    int arr[MAX];
    for(i=0;i<=length;i++){
                arr[i]=fact[i];
        }

    for(i=0;i<=length;i++){
         fact[i] = (arr[i]*num + r)%10;
         r = (arr[i]*num + r)/10;
         //printf("%d ",r);
    }
    if(r!=0){
         while(r!=0){
             fact[i]=r%10;
             r= r/10;
             i++;
         }
    }
    length = i-1;   
}

我的问题是:

  1. MAX常数的真正含义是什么?如果它更大或更小意味着什么?
  2. 我发现如果我有一个MAX = 10000(如例子中所示),我最多可以计算出3250!如果我试试3251!我得到一个'Abort trap:6'消息。为什么这个数字?它来自哪里?
  3. 如果我使用标志-m32为32位机器编译此代码会有什么不同?它会像64位一样运行吗?
  4. 谢谢!

2 个答案:

答案 0 :(得分:0)

  1. MAX是factarr中元素的数量;试图访问索引&gt; = MAX的元素会很糟糕。
  2. 错误消息通常特定于您正在使用的环境,您没有提供任何详细信息。
  3. 它们不一样,但差异(例如,指针的大小)不应以任何可辨别的方式影响此代码。

答案 1 :(得分:0)

正如Scott Hunter指出的那样,MAXfactarr数组中元素的最大数量,这意味着它是之前结果中可能出现的最大位数程序空间不足。

请注意,代码仅在其数组声明中使用MAX。它没有使用MAX来确定它是否试图在这些数组的末尾之外读取或写入内存。这是Bad Thing™。您的“中止陷阱:6”错误几乎肯定会发生,因为尝试计算3251!正是这样做:使用arrfact的过大索引。

要查看给定阶乘所需的位数,您可以增加MAX(例如,增加到20,000),并使用以下内容替换printf中现有的main次呼叫:

printf("Factorial requires %d digits.\n", length + 1);

请注意,我使用length + 1因为length本身不是数字位数:而是fact中包含最高位数的数组位置的索引结果。如果我尝试计算3251 !,输出为:

Factorial requires 10008 digits.

这比fact中的可用内容多八位,默认MAX值为10,000。一旦程序逻辑超出了数组中分配的空间,其行为就不确定了。您碰巧看到错误“中止陷阱:6。”

有趣的是,这是我尝试计算3250时的输出!:

Factorial requires 10005 digits.

MAX设置为10,000时,程序仍然可以表现得太可靠,因此程序计算3250的事实!成功可能会令人惊讶,但这是未定义行为的本质:也许你的程序会产生正确的结果,也许它会崩溃,也许它会变得自我意识并发射导弹对抗俄罗斯的目标(because it knows that the Russian counterattack will eliminate its enemies over here) 。像这样的编码不是一个好主意。如果您的程序需要比可用空间更多的空间来完成计算,它应该停止并显示相应的错误消息,而不是尝试继续它正在做的事情。