关于计算高精度的阶乘之和的问题

在这里插入图片描述关于计算阶乘之和,你肯定会觉得这是一个非常简单的问题,那只不是用一个循环而已了,很简单了。但是要计算高精度呢,高精度,我的第一想法,把我们平常用的int换成long或者long long呗,实在这些还是不行,那我用unsigned long long这总行了吧。于是我为了保险,我直接用unsigned long long来的,毕竟阶乘也无负数,以下就是我的代码。

#include <iostream>

int main()
{
    unsigned long long n, sum = 0, k = 1;
    std::cin >> n;
    for (unsigned long long i = 1;i <= n;i++) {
         k *= i;
         sum += k;
     }   
    std::cout << sum;
    return 0;
 }

但是,测试过后,只有50分,我测试了一下错误案例,我发现了当n打到22的时候代码就不能保持高精度了,即便是我用了unsigned long long,我低估了阶乘之和的威力。然后我们知道,phython语言是有高精度的,在这里我们不予以讨论,我们就只在C++这个范围内解决这道题。看来这道题不能这么来实现了,那怎么办呢,我想了许久,我萌生了一个想法,那就是用数组!我们可以假设最大的这个数的长度有1000位,那么我就可以用一个a[1000+1]一个这样的数组来表示这样一个数,其中没一个a[i](i>0&&i<1001)都表示一个位数,这样看来,一个具有一千位的数就可以被我们表示出来,那么我们要实现的高精度当然也就实现了。深思熟虑后,终于想出了代码。

#include <iostream>

int a[1001];//这个数组的意思是a[i](i>0&&i<1001)这个数的阶乘
int c[1001];//这个数组的意思是a[i](i>0&&i<1001)这个数及之前数的阶乘之和

void sum(int *a,int *c)//这个sum函数就是算此时a[i](i>0&&i<1001)这个数及之前数的阶乘之和
{
    int jw = 0;//这个jw是用来看有无进位的
    for(int i = 1;i <= 1000;i ++)
    {
        c[i] += a[i] + jw;//这一步表示a[i]之前的阶乘之和与a[i]的阶乘每一位都相加
        jw = c[i] / 10;
        c[i] %= 10;//这两条语句表示进位
    }
}

void jiecheng(int *a,int c)//这个jiecheng函数就是算a[i](i>0&&i<1001)这个数的阶乘
{
    int jw = 0;//这个jw是用来看有无进位的
    for(int i = 1;i <= 1000;i ++)
    {
        a[i] = a[i]*c + jw;//把每一位都乘以c,且加上上一个数的进位之后的数
        jw = a[i]/10;
        a[i] %= 10;//这两条语句表示进位
    }
}

int main()
{
    int n, w = 0;
    std::cin >> n;
    a[1] = 1;
    for(int i = 1;i <= n;i ++)
    {
        jiecheng(a,i);//先调用jiecheng函数算出a[i]的阶乘
        sum(a,c);//然后调用sum函数算出当前a[i]的阶乘于a[i]之前的阶乘之和

    }
    for(int i = 1000;i >= 1;i --)
    {
        if(c[i]!=0) w = 1;//先把所有为0的排除掉,当c[i]不等于0时,直接令w = 1,然后就可以全部输出来了
        if(w) std::cout << c[i];//输出每一位
    }
    return 0;
}

这一段代码提交之后,果然通过了,这说明当连unsigned long long都无法表示一个数时,我们就可以用数组来代替这一个数,这样就能达到高精度了。
笔者写到这里就基本结束了,如果对你有帮助就点一个赞哦,谢谢!

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值