大数的阶乘(C++实现)

大数的阶乘

原理

大数的阶乘的运算我个人的思路就是用整型数组进行运算,转化为字符串数组进输出,防止零的丢失,多个字符串数组并列输出长长的结果。先以100的阶乘为例

100的阶乘

我们计算100!这里的数比较大,可以用整型数组进行运算,字符串来存储大数,普通方法会数据类型会越界。
首先我们倒过来运算
100 * 99 = 9900
9900 * 98 = 970200
如果这个数字超过了 10000 , 对它取余试试 , 显然余数是0200 ,(注意此结果整型为200,转化为字符型的时候要进行补零);再对这个数作除以10000的操作 , 得到结果进位为 97 .
那么我们把 97 存在数组元素arr[1]里 , 把 0200存在 arr[0]里面会怎样呢 ? 接着往下看 :
0200 * 97 = 19400
这个数字又比10000大了 , 继续取余得到 9400 , 把它存在a[0]里面 , 继续除以10000得到 1 ;
这个 1 显然需要进位对吧 , 我们加到刚刚在 a[1] 里的 97 上 , 得到 98 ,
97 * 97 = 9409
由于刚才进位了一个1 , 所以存入 a[1] 中数字应该是 9409 + 1 = 9410
那么显然根据a[1]里存的是高位数字 , a[0]里存的是低位数字
连接起来得到 94109400
计算器验证一下
100 * 99 * 98 * 97 = 94109400[1]
此处要注意我们计算arr[0]时不需要加进位的,在计算arr[j] (j>1)时需要加上前一步的进位。

进制选择

为什么100阶乘选10000呢?
100!< 100100 < 10100*(2*2)
说明用容量为100的数组以万进制存储数组是够用的

换个公式说明:
n!<nn<nn*floor(log10n)2(当n>10),可以用n=100,n=1000,检验。
可得以大数数量级的平方次幂为数组元素的进制级别,在规定的数组元素标准类型内不会发生越界。
因此我们可以得以下代码:

代码(vs2017实现)

#include <iostream>//大数的阶乘
#include<string>
//#include<cmath>
using namespace std;
//类型转换
void transform(string& str, int& num)
{
 if (num >= 0 && num < 9)
 {
  str = "000" + to_string(num);
 }
 else if (num >= 10 && num <= 99)
 {
  str = "00" + to_string(num);
 }
 else if (num >= 100 && num <= 999)
 {
  str = "0" + to_string(num);
 }
 else
 {
  str = to_string(num);
 }
}
//阶乘计算
void func(int num)
{
 int *arr = new int[num];//100以内不会越界,但是很大的话还是会越界的
 string* str= new string[num];
 int length = 1;//100的阶乘一开始最大的两个数相乘不会超过一万,所有我们以一万为单位,初始运算所占数组长度为1
 int temp = 0;
 int c_num = 0;//进位
 arr[0] = 1;// 初始化 a[0] 让其第一次运算结果等于 该数本身
 int j = 0;
 for (int i = num; i > 1; i--)
 {
  for (j = 0; j < length; j++)
  {
   if (j == 0)//在首个数组元素中运算不需要加进位
   {
    temp = arr[j] * i;
    arr[j] = temp % 10000;
    transform(str[j], arr[j]);
    c_num = temp / 10000;
   }
   if(j != 0)
   {
    temp = arr[j] * i + c_num;
    arr[j] = temp % 10000;
    transform(str[j], arr[j]);
    c_num = temp / 10000;
   }
  }
  arr[j] = c_num;
  transform(str[j], arr[j]);//整型转字符型
  if (c_num > 0)
  {
   length++;
  }
 }
 for (int i = length - 1; i >= 0; i--)
 {
  cout << str[i];
 }
 cout << endl;
 delete[] arr;//释放
 delete[] str;
}
int main()
{
 int n = 0;
 cout << "输入一个非符整数:";
 cin >> n;
 func(n);
 system("pause");
 return 0;
}

100! 上网查了下结果为在这里插入图片描述

此程序运算结果为:
在这里插入图片描述
我们甚至可以求500的阶乘1000的阶乘,只要在规定的数组元素标准类型内就不会发生越界,我们定义的计算数组是int型,如果是long long的话,则能计算的更大,但是要注意太大可能会堆溢出。
在这里插入图片描述
在这里插入图片描述
参考文献:[1]风吹八万里. https://blog.csdn.net/weixin_43188732/article/details/90724888

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值