【问题标题】:Getting negative numbers or zero as output of factorial in C在C中获取负数或零作为阶乘的输出
【发布时间】:2020-04-20 07:04:02
【问题描述】:

我写了一个非常简单的程序来计算一个数的阶乘,问题是从大约 30 到 60,它返回一个负数,从 70 它返回 0。 我不知道我做错了什么。这个问题可能取决于我电脑的计算能力吗? 代码如下:

#include <stdio.h>

int main(){

int x, i;
long long int f = 1;

printf("Insert a number:");
scanf("%d", &x);

    if (x == 0){
        printf("0! = 1");
     }
    else { 
        for (i = 1; i <= x; i++){
            f *= i;
        }
        printf("%d! è = %lli", x, f);
    }

return 0;
}

【问题讨论】:

  • 将 f 更改为 long long unsigned int,大量的 msb 为 1,表示负数
  • 这不是你计算机的计算能力,而是一个 long long int 的范围,它甚至不足以表示任何接近 70 的东西!。 long long int 通常是 64Bit,这意味着可表示的最大数将是 2^63
  • @sergeyrar 这“修复”了负数,但结果仍然不正确(只是不太明显)。 64Bit 仍可表示的最高阶乘是 20!顺便说一句,任何比这更高的东西和常规整数类型都不会再削减它了
  • @Schiele 有,但是你不能再使用普通的整数类型和运算符了。本质上,您必须像在纸上那样进行乘法运算,并将数字存储为整数数组。然而,已经有许多库可以做到这一点,只需谷歌“bignum”或“bigint”
  • @Schiele 不,这些库(例如 gmp)提供了一组您必须使用的函数和数据类型。因此,您不必使用f *= i,而是必须使用库提供的某种乘法函数。话虽如此,自己实现一个基本的 bigint 函数(如加法或乘法)并不是那么难,并且您可以在此过程中学到很多东西。您必须问自己是否只想尽快找到解决方案,或者借此机会了解有关 bigints 的更多信息。

标签: c factorial


【解决方案1】:

这是我的代码:

#include<stdio.h>
#include<math.h>
#include<stdlib.h>

void Carry(int bit[],int pos)
{
    int i,carray=0;
    for(i=0;i<=pos;i++)
    {
        bit[i]+=carray;
        if(bit[i]<=9) 
        {
            carray=0;
        }
        else if(bit[i]>9&&i<pos)
        {
            carray=bit[i]/10;
            bit[i]%=10;     
        }
        else if(bit[i]>9&&i>=pos)
        {
            while(bit[i]>9) 
            {
                carray=bit[i]/10;  
                bit[i]%=10;       
                i++;
                bit[i]=carray;   
            }
        }
    }
}
int main()
{
    int num,pos,digit,i,j,m,n;
    double sum=0; 
    int *fact;   
    printf("input want to calculute  factorial num:");
    scanf("%d",&num);       
    for(i=1;i<=num;i++)
    {
        sum+=log10(i);
    }
    digit=(int)sum+1;  
    if(!(fact=(int *)malloc((digit+1)*sizeof(int))))
    {
        printf("malloc failed\n");
        return 0;
    }
    for(i=0;i<=digit;i++)
    {
        fact[i]=0;
    }
    fact[0]=1;
    for(i=2;i<=num;i++)
    {
        for(j=digit;j>=0;j--)
        {
            if(fact[j]!=0)
            {
                pos=j;
                break;
            }
        }
        for(j=0;j<=pos;j++)
        {
            fact[j]*=i; 
        }
        Carry(fact,pos); 
    }
    for(j=digit;j>=0;j--)
    {
        if(fact[j]!=0)
        {
                pos=j; 
                break;
        }
    }
    m=0; 
    n=0;  
    for(i=pos;i>=0;i--)
    {
        printf("%d",fact[i]);
        m++;
        if(m%4==0)  
        {
            printf(" ");
        }
        if(m==40)  
        {
            printf("\n");
            m=0;
            n++;
            if(n==10)
            {
                printf("\n");
                n=0;
            }
        }
    }
    printf("\n\n");
    return 0;
}

【讨论】:

    猜你喜欢
    • 2015-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多