zoukankan      html  css  js  c++  java
  • 大数阶乘?不用大整数函数也可以!!

    大家好,我是Ziyang。欢迎大家来到我的博客,希望能和大家多多交流。地址:https://www.cnblogs.com/ziyang1060/

    大数阶乘

    由于阶乘的结果会呈几何级数增长,即使在如今的64位字长的计算机中,能表示的大小也是有限的,只能保存20的阶乘。
    那我们如何求很大的数的阶乘呢?(例如1000!)
    这里我们不考虑复杂的大整数函数,而尝试用一种简单的求大数阶乘的办法。

    思路:

    将多位数相乘化解为一位数相乘,例如:
    已知 11! = 39916800
    此时,我们想要得出 12!
    在这里插入图片描述
    当我们将 11! 的每一位数都乘以12后,总的结果就变得十分简单明了。我们只需从最低位开始,依次考虑该位的进位问题,假如说这个位上是96,那么就要往上一位进9,以此类推。

    代码如下:

    //求大数阶乘 https://blog.csdn.net/Ziyang1060
    #include<stdlib.h>
    #include<stdio.h>
    #include<math.h>
    
    int find_digit(int num);//返回阶乘结果的位数
    void factorial(int* fact, int digit, int num);
    int find_pos(int* fact, int digit);
    void process_carry(int* fact, int pos);
    void output(int* fact, int digit, int num);
    
    int main(void)
    {
    	int num, digit;
    	int* fact = NULL;
    
    	scanf("%d", &num);//输入求阶乘的数:num!
    	digit = find_digit(num);
    	if (!(fact = (int*)calloc(digit , sizeof(int))))//动态分配并初始化为0
    	{
    		printf("分配数组空间失败!
    ");
    		return -1;
    	}
    	factorial(fact, digit,num);
    	output(fact, digit, num);
    
    	free(fact); fact = NULL;
    	return 0;
    }
    int find_digit(int num)
    {
    	double digit_f = 0;
    	for (int i = 1; i <= num; i++)
    	{
    		digit_f += log10(i);
    	}
    	return (int)digit_f + 1;
    }
    void factorial(int* fact, int digit, int num)
    {
    	int pos;//最高位的位数
    	fact[0] = 1;//设置第一位为1:0! = 1! = 1
    	for (int i = 2; i <= num; i++)
    	{
    		pos = find_pos(fact, digit);
    		for (int j = 0; j <= pos; j++)
    		{
    			fact[j] *= i;
    		}
    		process_carry(fact, pos);
    	}
    
    }
    int find_pos(int* fact, int digit)
    {
    	for (int i = digit - 1; i >= 0; i--)//找到最高位
    	{
    		if (fact[i] != 0)
    		{
    			return i;
    		}
    	}
    }
    void process_carry(int* fact, int pos)
    {
    	int carry = 0;//进位
    	for (int i = 0; i <= pos; i++)
    	{
    		fact[i] += carry;
    		if (fact[i] <= 9)
    		{
    			carry = 0;
    		}
    		if (fact[i] > 9 && i < pos)// 此时不是最高位
    		{
    			carry = fact[i] / 10;
    			fact[i] %= 10;
    		}
    		if (fact[i] > 9 && i == pos)// 此时为最高位
    		{
    			while (fact[i] > 9)
    			{
    				carry = fact[i] / 10;
    				fact[i] %= 10;
    				fact[++i] = carry;
    			}
    		}
    	}
    }
    void output(int* fact, int digit, int num)
    {
    	int n = 0;
    	int m = 0;
    	int pos = find_pos(fact, digit);//最高位的索引
    	printf("
    输出%d的阶乘结果: 
    ", num);
    	for (int i = pos; i >= 0; i--)
    	{
    		printf("%d", fact[i]);
    		if (++m % 3 == 0)//每三个数字凑一组
    		{
    			printf(" ");
    		}
    		if (m == 3 * 13)//每一行输出13组
    		{
    			printf("
    ");
    			m = 0;
    		}
    	}
    	printf("
    
    %d!共有%d位。
    ", num, pos + 1);
    }
    

    输出结果:

    在这里插入图片描述

    在这里插入图片描述

  • 相关阅读:
    Node.js学习笔记(五) --- 使用Node.js搭建Web服务器
    express常用中间件
    MongoDb 学习笔记(一) --- MongoDb 数据库介绍、安装、使用
    如何优化网站加载时间
    Node.js学习笔记(四) --- fs模块的使用
    dns-prefetch使用整理
    puppeteer 中国区的使用
    mysql 定时任务和存储过程
    疯狂使用 leancloud (投稿文章)
    elasticsearch
  • 原文地址:https://www.cnblogs.com/ziyang1060/p/13109900.html
Copyright © 2011-2022 走看看