大数阶乘

合集下载

大数阶乘算法

大数阶乘算法

⼤数阶乘算法⼤数阶乘算法前⼏天朋友问我⼀个问题:“10000的阶乘怎么算?”当时我就有点懵,“10000”这个数字太⼤了,⽆论⽤什么数据类型保存结果都会溢出。

这可怎么办呢?⼀时间束⼿⽆策。

然后被⼀顿鄙视。

后来经朋友的提醒,才恍然⼤悟,终于知道怎么实现了,原来是使⽤数组来模拟数字,这样⽆论结果数字有多⼤,只要数组的长度够长就能表⽰出来,⽤这个办法可以进⾏⼤数据的运算。

看起来还是挺有⽤的。

我把它⽤程序实现出来,如果有⽤到的地⽅还可以借鉴⼀下。

(最起码还可以拿来鄙视别⼈^_^)⾸先定义⼀个⾜够长的数组。

拿10000的阶乘为例,最后的结果长度是35660位,所以我们定义⼀个40000个成员的数组就可以了。

int result[40000];其核⼼思想就是把计算结果每⼀位上的数字保存到⼀个数组成员中,例如:把124保存⾄数组中,保存结果应该是result[0] 4result[1] 2result[2] 1这样肯定是没有问题的,⼀个int型数据存放⼀个⼩于10的数是绝对不会溢出。

但是处理起来就稍微有点⿇烦。

把整个数组看成⼀个数字,这个数字和⼀个数相乘的时候,需要每⼀位都和这个乘数进⾏相乘运算还需要把前⼀为的进位加上。

运算⽅法和⼩学数学是⼀样的,乘积的个位是当前位上应该表⽰的数字,10位以上的需要进位。

因为乘数不可能⼤于10000,所以乘数和⼀个⼩于10的书相乘的时候不会⼤于100000,再加上前⼀位的进位⽤⼀个int型数据来保持这个结果就没有问题。

写法如下:int 结果 = result[x] * 乘数 + 进位;每⼀位的计算结果有了,把这个结果的个位数拿出来放到这个数组元素上:result[x] = 结果%10;接下来的⼯作就是计算出进位:进位 = 结果 / 10;这样⼀位⼀位的把整个数组计算⼀遍,最后可能还有进位,⽤同样的⽅法,把进位的数值拆成单个数字,放到相应的数组元素中。

最后输出⼀下结果,从最⾼位吧数字打印⼀遍就OK了。

10000的阶乘的算法(大数的阶乘)

10000的阶乘的算法(大数的阶乘)

10000的阶乘的算法(⼤数的阶乘)很多天没有更新⾃⼰的Blog了,前⼏天拿到⼀个题⽬.就是写⼀段程序计算10000的阶乘.当时我还以为这题⽬⾮常简单,没想到还是需要动点⼤脑的.花了将近半个⼩时才搞定,拿出来分享⼀下.为什么不能⽤普通的⽅法来写呢,⽐如说递归?在我的教科书上可是⽤的是递归呀?不知道你注意没有,如果是100的阶乘的话,其结果肯定是⾮常⼤的,以我们现有语⾔的数据类型肯定是没法使⽤的,就拿C来说,long型能存的下100的阶乘吗?未必.所以我就使⽤数组来存储结果的每⼀位,然后输出每⼀位不就是结果吗.那么具体怎样去做?⾸先确定结果的位数?如何确定呢?请看下⾯.2!=1*2<=10*103!=1*2*3<=10*10*10.......所以我们可以得出⼀个结论n!<=10n所以n!的位数可以这样计算:两边取对数,即log10n!<=log1010n两边n>=Log101+Log102+Log10 3+....Log10 n这样n!的位数肯定等于⼩于Log101+Log102+Log10 3+....Log10 n.以上是错误的正确的推断如下:可以将n!表⽰成10的次幂,即n!=10^M(10的M次⽅)则不⼩于M的最⼩整数就是 n!的位数,对该式两边取对数,有 =log10^n!即:M = log10^1+log10^2+log10^3...+log10^n循环求和,就能算得M值,该M是n!的精确位数。

位数的确定解决之后,就看看如何计算了.看看如下代码:1int index=0;2long carrier=0;3double bitCount = 1;4int begin = 0;56for(index=2; index<=n; ++index)7 {8long multiValue = 0;9 bitCount += log10((long double)index);10if(arrValue[begin] == 0)11 begin++;1213for(int j=begin; j<int(bitCount); ++j)14 {15 multiValue += (index*arrValue[j]);16 arrValue[j] = char(multiValue % 10);17 multiValue /= 10;18 }19 }这⾥就是计算的关键了.注意⼀下进位问题即可.所有代码如下:12//////////////////////////////////////////////////////////////////////////3// Date created: 2005/07/124// Author: Confach Zhang5// Purpose: 计算n!的值6//////////////////////////////////////////////////////////////////////////789using namespace std;10#include "StdAfx.h"11#include <iostream.h>12#include <conio.h>13#include <stdlib.h>14#include <math.h>15#include <stdio.h>16#include <iomanip.h>1718int GetNumber(); //输⼊ n19int GetBitLength(int n); //求n!的位数20char* Initialize(int); //初始化存储结果的值21void PrintValue(char *a,int size); //打印值到屏幕22void PrintValue(char *a,int size,char* fileName); //打印值到⽂件 23char* GetValue(int val); //计算24char* SubGetValue(char* ,int);252627int main()28{29int value=GetNumber();30char fileName[16];31int size=GetBitLength(value);32char *pa = Initialize(size);3334//pa=GetValue();35 pa=GetValue(value);3637 PrintValue(pa,size);3839//sprintf(fileName,"%s","10000!.txt");40 sprintf(fileName,"%d!.txt",value);4142 PrintValue(pa,size,fileName);43 delete []pa; //note:44return 1;45}46//函数GetValue47// 求得计算结果48//返回结果49//History:50//1)char* GetValue()51//2)GetValue(int val)52// 参数:val 计算阶乘的值53char* GetValue(int val)54{55//定义⼀个数组存储阶乘的值56 //⾸先得到10000!阶乘的位数57int VALUE=val;58int length=GetBitLength(VALUE);59char *arrValue = new char[length];60if(!arrValue) {61 cout <<"申请内存失败!" << endl;62 exit(1);63 }64 arrValue[0] = 1;65for(int i=1; i<length; i++)66 arrValue[i] = 0;67 arrValue=SubGetValue(arrValue,VALUE);68return arrValue;69}7071char* SubGetValue(char* arrValue,int n)72{73int index=0;74long carrier=0;75double bitCount = 1;76int begin = 0;7778for(index=2; index<=n; ++index)79 {80long multiValue = 0;81 bitCount += log10((long double)index);82if(arrValue[begin] == 0)83 begin++;8485for(int j=begin; j<int(bitCount); ++j)86 {87 multiValue += (index*arrValue[j]);88 arrValue[j] = char(multiValue % 10);89 multiValue /= 10;90 }91 }92return arrValue;93}9495//得到计算阶乘的值,此函数为新增96int GetNumber()97{98int n;99 cout << "请输⼊要计算阶乘的n值: ";100 cin >> n;101while(n < 0) {102 cout << "输⼊错误,请重新输⼊: ";103 cin >> n;104 }105if(n == 0)106 exit(1);107return n;108}109110//函数GetBitLength111// 求得计算结果的位数,本函数为新增加112//参数113// n 需要计算的阶乘的数114//返回结果的位数115int GetBitLength(int n)116{117double sum = 1.0;118for(int i=1; i<=n; i++)119 sum += log10((long double)i);120return int(sum);121}122//-----------123//函数:Initialize124// 初始化存储结果的数组125//参数:126// size 数组的长度127//返回值128// 初始化后的数组129//-------------130char * Initialize(int size)131{132char *arrValue = new char[size];133if(!arrValue) {134 cout << size<<"太⼤,申请内存失败!" << endl; 135 exit(1);136 }137 arrValue[0] = 1;138for(int i=1; i<size; i++)139 arrValue[i] = 0;140return arrValue;141}142143//-----------144//函数:PrintValue145// 将结果输⼊到屏幕上146//参数:147// buff 存储结果的数组148// buffLen 数组的长度149// fileName ⽂件名150//-------------151void PrintValue(char *buff, int buffLen)152{153int bit = 0;154int nCol=0;155for(int i=buffLen-1; i>=0; i--) {156if(bit % 10 == 0)157 {158 cout << " " ;159 nCol++;160if(nCol==10)cout<<endl;161 }162 cout << int (buff[i]);163 bit++;164 }165 cout << endl;166167}168//-----------169//函数:PrintValue170// 将结果输⼊到⼀个⽂件中171//参数:172// buff 存储结果的数组173// buffLen 数组的长度174// fileName ⽂件名175//-------------176177void PrintValue(char *buff,int buffLen,char *fileName) 178{179int bit = 0;180int nCol=0;181182 FILE *fp=NULL;183//-----------------------------184185if (fileName==NULL) return ;186 fp=fopen(fileName,"wt");187if (fp==NULL)188 {189 printf("不能创建⽂件%s",fileName);190return ;191 }192193for(int i=buffLen-1; i>=0; i--)194 {195 fprintf(fp,"%d",int(buff[i]));196197if(bit % 9 == 0)198 {199 fprintf(fp,"%s"," ");200 nCol++;201if(nCol==8)202 {203 fprintf(fp,"%s","\n");204 nCol=0;205 }206 }207 bit++;208209 }210 fprintf(fp,"\n");211 fclose(fp);212}213好了,不说了.Last Updated: 2005年7⽉14⽇12:43:07 感谢的建议Last Updated: 2005年7⽉15⽇ 8:48:20 感谢的精彩建议posted on 2005-07-14 12:17 阅读(1260) 所属分类:re: 10000的阶乘 2005-07-14 12:34@Milestone能写多点⽂字吗?⽐如说说,⽤普通的递归会出现什么问题和不⾜你的这种新⽅法的原理是什么,关键的技术点⼜在哪?这样⼀堆代码,我真的看不懂,可能我技术太菜了;)*¥—#**re: 10000的阶乘 2005-07-14 12:36@kwklover谢谢你的提议,有空我写上.re: 10000的阶乘 2005-07-14 13:13普通的递归不⾏猜想原因是C的标准数据类型有可能不能保存结果那么⼤的数值。

1乘到100的简便方法公式

1乘到100的简便方法公式

1乘到100的简便方法公式求1到100的乘积的简便方法公式是阶乘(factorial)。

阶乘是指一个正整数与小于它的所有正整数之积。

在数学中表示为n!。

具体地,1到100的乘积可以表示为100!,即100的阶乘。

阶乘的计算可以通过循环的方式进行,从1到n依次相乘,或者通过递归的方式实现。

在计算机程序中,通常使用循环的方法来求解阶乘。

拓展:
阶乘的计算在数学和计算机领域中有广泛的应用。

以下是一些拓展的情况:
1.负整数的阶乘:
负整数的阶乘是没有意义的,因为阶乘要求所有相乘的数都是正整数。

2.非整数的阶乘:
非整数的阶乘也没有明确的定义。

然而,可以通过Gamma函数来
拓展阶乘的定义,其中Gamma函数是阶乘的延伸。

3.大数阶乘的计算:
当n非常大时,直接计算n的阶乘可能会超出计算机的表示范围。

解决办法是使用大数运算的技术,例如使用字符串来表示大数,并通
过手动模拟竖式计算来求解阶乘。

4. Stirling近似公式:
Stirling近似公式是对阶乘的近似计算公式,可以用于计算大数
的阶乘。

该公式可以用于估计n的阶乘的近似值,其中n较大。

大数阶乘和大指数整数幂的计算

大数阶乘和大指数整数幂的计算

若 直接计 算 , 由于计算 组合 数 C( , ) n 忌 时可能会 出现 计算 溢 出 , 计算 P 或 ( 一 p r 1 ) 时可 能会 出现将 接 近 于零 的小数 视 为零 , 而得不 到 需要 的结果. 从 当然
可 以采用 大数 和小 数 相 乘 的策 略 , 一 定 程度 上 避 能
能 、 优 化 方 法研 究 . mal pu 2 0 @y h o cr.n 最 E i jn 03 a o .o c . l n
可 以通 过定 义高 有 效 位 数值 的类 , 定 义该 数 并 值 的乘 、 除运算 , 而定 义 阶乘 和整数 次幂 运算来 计 进 算上 面这 些 问题[ , 2 算法 通 用性好 , 实现 高精度 计 ] 可
Gn ag
Ab t a t I hi a r we gi e a x mpl o pr s n a i r l m o i t t r sr c : n t s p pe v n e a e t e e ta b sc p ob e f r fnie ne wo ks: wh t e t i s i e o tf r a i t t e h r i spo sbl r no o ny fniene wor fd v c s t ha k o e i e o c nge iss a u r t t t s fom he i iil t n ta s a u t l is de ie e ng i “co e s a e t h i a t t s wih a lis d v c s b i g i t t s wih a l t v c s b i n l s ” t t o t e fn l s a u t l t e ie e n n
免 上述 问题. 即使 相 乘 的 顺 序 用一 些 复 杂 的组 合 方 式 , 于充分 大 的 , 不 同的 k 仍 存在 溢 出或 得到 对 对 ,

20000阶乘 算法 -回复

20000阶乘 算法 -回复

20000阶乘算法-回复如何计算20000的阶乘。

[20000阶乘算法] 是如何工作的?为何要使用该算法?有哪些优点和缺点?如何进行优化?这些问题都将在下文中一一回答。

20000的阶乘表示为20000!,意味着从1到20000的所有整数相乘。

计算大数的阶乘是一个非常庞大的任务,需要一种高效的算法来处理。

常见的算法有迭代法和递归法,我们将主要探讨迭代法。

迭代法是通过多次迭代计算得出结果的一种算法。

对于大数阶乘的计算,可以使用一个循环来依次累乘每个数字,从而得到最终结果。

以下是计算20000的阶乘的算法:1. 声明一个变量result并初始化为1。

2. 循环从1到20000,每次乘以当前数字并更新result。

3. 返回result作为最终结果。

下面是具体实现这个算法的Python代码:def calculate_factorial(n):result = 1for i in range(1, n+1):result *= ireturn resultresult_20000_factorial = calculate_factorial(20000)print(result_20000_factorial)使用迭代法计算大数阶乘的优点是它的时间和空间复杂度相对较低。

该算法只需要存储一个结果变量,不需要递归调用或额外的空间。

此外,迭代法的执行速度较快,适用于大规模计算。

然而,该算法也存在一些缺点。

首先,20000的阶乘是一个非常庞大的数,会消耗大量的计算资源。

其次,该算法在计算过程中容易导致整数溢出。

最后,迭代法的时间复杂度为O(n),所以对于更大的数,计算时间将会大幅增加。

为了优化算法,可以使用更高级的数据结构和算法。

一种优化方法是使用大数运算库,例如Python的gmpy2模块或C++的boost库。

这些库提供了高效的大数运算功能,可以处理更大的数值。

另一种方法是使用分治法。

分治法将一个大问题分解成较小的子问题,然后逐步求解。

1000的阶乘算法

1000的阶乘算法

1000的阶乘算法
计算1000的阶乘是一个相当大的数字,它的结果将是一个包含很多位的数。

由于1000的阶乘是一个非常大的数字,所以不可能直接将它写入内存中。

一个有效的方法来计算大数的阶乘是使用迭代方法。

这种方法的基本思想是:
n的阶乘= (n-1的阶乘) * n
这是一个Python代码示例,用于计算1000的阶乘:
python复制代码:
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)
print(factorial(1000))
此代码首先检查n是否为0,因为0的阶乘是1。

然后,它递归地调用自身,每次将n减1,并将结果乘以n。

这个过程一直持续到n为0为止。

然而,需要注意的是,这种方法在计算非常大的阶乘时可能会遇到问题,因为Python的默认数据类型无法存储这
么大的数字。

在这种情况下,你可能需要使用一些特殊的数据结构或库,如大数库,来处理大数的计算。

大数的认识奥数题

大数的认识奥数题

大数的认识奥数题导语在奥数竞赛中,大数问题常常是让学生们感到头疼的一类题目。

这些问题涉及到了对大数的认识和运算技巧。

本文将解析几个经典的大数题目,帮助读者更好地理解和应对这类题目。

一、问题一:最大的n位数问题描述:给定一个正整数n,要求输出由n个9组成的最大的整数。

解析:这道题目很简单,只需要将n个9连接起来即可得到最大的n位数。

解答:假设n=3,最大的3位数就是999;假设n=5,最大的5位数就是99999。

可以用一个循环来实现这个问题。

二、问题二:大整数相加问题描述:给定两个正整数a和b,要求计算它们的和。

解析:这道题目考察了大整数的相加运算,需要注意的是两个整数的位数可能不相等。

解答:可以使用数组来存储大整数,并且从末位开始逐位相加,将结果保存在另一个数组中。

需要注意的是,如果相加的结果超过了9,就需要进位。

具体步骤如下:1. 将两个大整数拆分成数组,并对齐使其位数相等,不足位的用0填充。

2. 从最后一位开始相加,将结果保存在结果数组中,并判断是否需要进位。

3. 将结果数组转化为字符串即为最终答案。

三、问题三:大整数相乘问题描述:给定两个非负整数a和b,求其乘积。

解析:这道题目是大数运算中比较经典的问题,需要注意的是乘法的进位问题。

解答:同样可以使用数组来存储大整数,在计算过程中进行逐位相乘,并将结果保存在结果数组中。

需要注意的是,乘法的进位规律。

具体步骤如下:1. 将两个大整数分解成数组,并定义一个结果数组,数组长度为a的位数+b的位数。

2. 从后向前遍历乘法计算,每次计算两个位上的乘积,并将结果保存在对应的位置上。

3. 遍历结果数组,将每个位置上的数字都进行进位处理。

4. 将结果数组转化为字符串即为最终答案。

四、问题四:大数的阶乘问题描述:给定一个正整数n,求n的阶乘。

解析:阶乘的计算涉及到大数的乘法运算,需要考虑进位问题。

解答:可以通过逐位乘法来计算阶乘。

将每个乘积的结果保存在数组中,并在遍历过程中将进位处理。

大数的认识知识点总结

大数的认识知识点总结

大数的认识知识点总结在数学中,大数是指位数较大的整数或实数。

处理大数涉及到许多特殊的计算方法和技巧。

本文将总结一些与大数相关的知识点,帮助读者更好地理解和处理大数。

一、大数的表示方法1. 十进制表示法:将大数按照普通的十进制数进行表示,例如123456789。

2. 科学计数法:将大数转化为指数形式,使其更加紧凑。

例如,一亿可以表示为1×10^8。

3. 简化表示法:如果大数中存在一段重复的数字,可以使用简化表示法。

例如,222222可以表示为2×10^5。

二、大数的运算1. 大数的加法:按照普通的竖式加法规则进行计算。

需要注意的是,对齐两个加数的各位,并考虑进位的情况。

2. 大数的减法:按照普通的竖式减法规则进行计算。

需要注意的是,被减数与减数的各位对齐,并考虑借位的情况。

3. 大数的乘法:可以使用快速乘法算法,将乘法转化为多次加法的形式。

需要注意的是,按位相乘后的进位问题。

4. 大数的除法:可以使用长除法的方法进行计算,将除法转化为多次减法的形式。

5. 大数的取模运算:通过除法计算得到商和余数,只保留余数。

三、大数的性质1. 位数相加:两个大数的位数相加,等于它们的数字位数之和。

例如,10000位的数与1000位的数相加后,结果仍然是10000位。

2. 位数相乘:两个大数的位数相乘,等于它们的数字位数之和。

例如,1000位的数与1000位的数相乘后,结果是2000位。

3. 大数的阶乘:计算大数的阶乘时,需要考虑到大数的位数增长非常快。

可以利用特殊的算法来优化计算过程,如分治算法或递归算法。

四、大数的应用领域1. 密码学:在密码学中,需要使用大素数进行加密操作。

大数的运算和性质对密码学算法的安全性具有重要影响。

2. 数据分析:在大数据时代,需要处理包含大量数字的数据集。

大数运算的技巧对数据分析和统计具有重要作用。

3. 金融领域:在金融交易和计算中,经常涉及到大量的数字计算,如股票交易、利率计算等。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

谢谢大家
整型函数调用
• int fact(int n) •{ • int i=1,m=1; • for(i=1;i<=n;i++) • m=m*i; return m; }
//i++,加法问题 //乘法问题
详细代码
1000!
1000!,1秒内可以计算出来 一共2570位
20000!
计算用时3-4分钟,一共77338位
r0=k%10
r1=k%10 r2=k%10
pls=k/10
pls=k/10 pls=k/10
(最高位记得加上进位)
字符串型函数调用
• string F_plus(string num1,string num2); • string F_multi(string num1,string num2); • string Fact(string num1,int n) • { • int i; string x1=”1”; string x2=”1”; • for(i=1;i<n;i++) • { • x1=F_plus(x1,”1”); //代替i++,更简单的的方法是直接将 i 转为字符串 • x2=F_multi(x2,x1); • } • return x2; • } //加法 //乘法
探讨一下n!的计算
• 我们在用C语言编程计算阶乘的时候,无论用递归方法,还是调 用函数计算,都会遇到一个问题就是数位溢出
解决办法
• 一般的阶乘计算方法是用整型变量计算,而整型变量的长度是有
限的,所以我这里介绍的办法是用字符串代替整型变量,用函数
调用的方法计算
整型函数调用
• int fact(int n) •{ • int i=1,m=1; • for(i=1;i<=n;i++) • m=m*i; return m; }
//i++,加法问题 //乘法问题
那么用字符串怎么进行算术计算呢?
• 答案是用C语言模拟我们在小学就会的手算。
字符串转为多 个整型变量
用整型 变量 进行数值算
多个整型变量 转为字符串
字符串乘法
把位相乘的结果用 二维数组装起来
每一列的数字 相加就可以得出结果
方法实现
• a1a0 x b1b0 • k=a0xb0+pls • k=a1xb0+pls • k=a0xb1+pls • k=a1xb1+pls a[2][4]= pls=0(pls为进位) r0=k%10 pls=k/10(无需进位判断) r1=k%10 pls=k/10 r2=k%10 pls=k/10 r3=k%10 pls=k/10 每一列进行加法运算,就可以得到结果
0 0 r进位和 数位对齐就ok
方法实现
• a2a1a0 +b2b1b0 • k=a0+b0+pls (pls为进位,pls=0) • (无需进位判断) • k=a1+b1+pls (pls为进位,pls=0) • k=a2+b2+pls (pls为进位,pls=0) • 结果:(pls)r2r1r0
相关文档
最新文档