65.9K
CodeProject 正在变化。 阅读更多。
Home

1000 的阶乘

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.54/5 (28投票s)

2009年7月26日

CPOL

4分钟阅读

viewsIcon

146292

downloadIcon

2926

计算大数阶乘的最佳算法

Sample Image - maximum width is 600 pixels

引言

阶乘或正整数的乘积是最常用的数学函数(或过程)之一。许多数学计算需要大数的阶乘的精确结果,例如 1000!,以高精度找到最终结果。但问题是,没有任何编程语言具有存储如此大的数字的变量或机制。所有的编程语言和计算器都估计结果,然后将其存储为科学计数法。例如,Windows XP 的计算器显示 1000! 如下:

4.02387260077093773543702433923 e+2567 

所以我决定发明一种算法来解决这个问题。

算法

您知道要计算一个数的阶乘,您应该将从 1 到它本身的所有数字相乘,例如:

1000! = 1*2*3*……*998*999*1000 

没有任何编程语言中的变量可以精确地存储这个乘法的结果;除非以科学计数法存储。由于顺序乘法的巨大结果,寻找一种新的策略或机制是必要的。

在我推荐的算法中,数字不被视为一个数字,而是被视为顺序数字,其中每个数字都有自己的数值。 实际上,可以使用数字数组。 每次,第二个数字乘以第一个数字的每个数字(数组的索引),然后加上从上一次乘法运算中得到的进位数。
例如,这个过程显示了 12!

12! = 11! * 12     11! = 39916800     12! = 479001600 

Sample Image - maximum width is 600 pixels

  • 如果结果小于 10,则结果将放置在数组的单元格中。
  • 如果它等于或大于 10,它将被 10 除,然后余数将被放置在数组的单元格中,商被放置在变量中,该变量将与下一次乘法运算的响应相加。
    注意:请注意,所有数字都从数组的末尾存储,这与普通计算(实际计算)相同。

编程代码

声明

int numArr[3000];			
int total,rem=0,count;	
register int i;

在第一行中,定义了一个数组,其大小取决于阶乘的大小。 "rem" 被定义为存储除法的余数。

最后,定义了一个名为 "i" 的整数变量,它充当循环计数器和数组的索引,并且由于访问频繁,它被定义为寄存器。

寄存器类型修饰符告诉编译器将声明的变量存储在 CPU 寄存器中(如果可能),以优化访问。

注意:现代编译器具有良好的优化器,可以确定哪些变量应该存储在寄存器中。 当全局寄存器分配优化开启时,它们会做出自己的寄存器选择。

代码的主要部分

i=2999;				//start from end of array.
numArr[2999]=1;
	
for(count=2;count<=1000;count++)
{
  while(i>0)
   {
      total=numArr[i]*count+rem;
      rem=0;
		if(total>9)
		 {
		  numArr[i]=total%10;
		  rem=total/10;
		 }
		else
		 numArr[i]=total;
      i--;
   }
rem=0;
total=0;
i=2999;
}

根据之前解释的算法,存在一个从 2 到 1000 的循环计数,每次 'count' 的值都乘以数组的单元格并加上 'rem',它包含来自先前乘法的进位。

最后,结果存储在 'total' 中,然后放置在数组的单元格中。

另一种算法

起初,我为这个问题找到了另一种算法。 它基于通过连续加法来模拟乘法。 例如 20= 4*5 也是 20= (5+5+5+5)。
所以将数字放入数组中,然后将其自身加上 'X' 次。
1000! 的 X 为

X= ∑ n
n=1,2,3, … ,999,1000

注意:这种算法不如我解释的第一个算法那么优化。 而且它太枯燥了,需要几个大数组。 第二个 ZIP 文件属于此算法。

关注点

我想指出的是,该算法具有很高的计算速度,因此它使程序达到相当最佳的状态。

此算法最重要的特征之一是仅使用一个数组,而其他算法需要更多的内存(使用多个数组来模拟通过顺序和进行的乘法)。

此外,更少的编码有助于轻松理解程序,并且您可以用任何编程语言重写它。

高执行速度的原因之一是使用寄存器变量作为循环的计数器。 循环的计数器是一个对其访问最多的变量。

用法

正如我在引言中提到的,阶乘运算被用于许多数学计算中,特别是那些与需要精确阶乘结果的统计数据相关的计算。

因此,该程序可以成为任何需要阶乘方法的程序的一部分,例如统计软件。

感谢

我要感谢 Mr.Fermisk Naserzade 向我介绍这个问题,并感谢 Mr. Iraj Safa 帮助我编辑本文。

© . All rights reserved.