大数的阶乘(n!)
信息科学与工程学院
编程设计实验文档
题目:较大数的阶乘
一、设计目的:
1.解决一般大数的阶乘问题,可以避免一般算法实行时的数据溢
出的弊端
2.培养自己对算法的理解,提高自身的水平
3.熟练对c语言的操作,加强对c语言的理解
二、设计分析:
实现一般较小的数的阶乘,可以直接利用普通的乘法进行循环
运算即可,即利用s=n*(n-1)的核心算法。但是,当n比较
大的时候,会造成运算的结果,即s会变得特别大,便会造成
数据溢出。此时,就需要另一种算法,是结果可以保存,不溢
出。那么,这个算法就是要解决这个问题,所以,我想到另一
方式用来解决这个问题,即利用数组。
如下:
首先,定义两个整型的数组:
int a[200];//暂且先设定是200位,我称之为“结果数组” int add[200];//我称之为“进位数组”
现在具体说明两个数组的作用:
1.a[200]
比如说,一个数5的阶乘是120,那么我就用这个数组存储它: a[0]=0
a[1]=2
a[2]=1
因此,用这样的数组我们可以放阶乘后是200位的数
2.在介绍add[200]之前,我介绍一下算法的思想,就以6!为
例:
从上面我们知道了5!是怎样存储的。
就在5!的基础上来计算6!,演示如下:
fac[0]=fac[0]*6=0
fac[1]=fac[1]*6=12
fac[2]=fac[2]*6=6
3.现在就用到了我们的:“进位数组”add[1000].
先得说明一下:add[i]就是在第2步中用算出的结果中,第
i位向第i+1位的进位数值。还是接上例:
add[0]=0;
add[1]=1; // 计算过程:就是 (a[1]+add[0]) % 10=1 add[2]=0; // 计算过程:就是 (a[2]+add[1]) % 10=0
.......
.......
.......
add[i+1] =( a[i+1] + add[i] ) % 10
三、算法流程图
四、主要模块功能及程序说明
本程序主要分为三个模块,第一个模块就是判断输出是否错误,当输入的数据是小于1的时候,程序的输出结果是显示“输入
错误;第二个模块当输入正确时模拟一个乘法的运算,先算出
该数的阶乘是多少兵保存在a[200]这个数组中;第三个模块
根据所得结果位数的判断如何按4个数字一组的输出这个数,
当所得结果为4的倍数时,我选择的是单独输出末尾四个数,
剩下的按“1234,”这样的形式输出,当所得结果不是4的倍
数时,我选择优先输出前面的几个数,把后面的数字按四个一
组“,1234”这样的形式输出。
五、实验结果:
1.当输出的数字小于0的时候
2.当输入的数所得的结果是4的倍数时,如输入11时
3.当输入的数所得的结果不是4的倍数时,如15
附录
A变量及函数功能说明
n是输入的数据
S是输出结果的位数除以4所得的余数
t是输出结果的位数除以4所得的商值
a[200]是用来保存最后结果的数组
temp为阶乘的任一元素与临时结果的某位的乘积结果digit表示所得结果的位数
carry表示进位
B.源程序代码
#include
int main()
{
int n,s,t;
int a[200];
int carry;
int digit=1;
int temp,i,j;
scanf("%d",&n);
a[0]=1;
if(n<1)
printf("输入错误/n");
else
{
for(i=1;i<=n;++i)
{
for(j=1,carry=0;j<=digit;++j)
{
temp=a[j-1]*i+carry;
a[j-1]=temp%10;
carry=temp/10;
}
while(carry)
{
a[++digit-1]=carry%10;
carry/=10;
}
}
t=digit/4;
s=digit%4;
if(s==0)
{
for(i=t;i>1;i--)
printf("%d%d%d%d,",a[4*i-1],a[4*i-2],a[4*i-3],a[4*i-4]);
printf("%d%d%d%d",a[3],a[2],a[1],a[0]);
}
else
{
for(i=digit-1;i>=digit-s;i--)
printf("%d",a[i]);
for(i=t;i>0;i--)
printf(",%d%d%d%d",a[4*i-1],a[4*i-2],a[4*i-3],a[4*i-4]); }
}
}
阶乘运算
//阶乘各算法的 C++ 类实现 #include
阶乘的计算和处理程序设计
阶乘的计算及处理程序设计 一、问题描述 要求输入一个自然数n,求n!,同时统计结果中有几个0。 二、课题分析 1)计算n!。 2)统计0的个数。 三、数据结构的设计 x:输入的数n i:n! b:储存数据i上的各位上的数,从而判断b是否为0 j:统计0的个数 四、处理结构的设计 建立两个函数f1和f2,使f1函数起到求阶乘的作用,f2函数起到求0个数的作用。
求阶乘流程图
计算0的个数流程 五、源程序 1)主要结构体: f1函数: long int f1(int x) { long int i; //声明长整型变量i if (x==0||x==1) //采用递归函数f1求阶乘i=1; else i=f1(x-1)*x; return (i); }
f2函数: int f2(int i) {int j=0; int b=0; while(i>=10) //循环结构,判断末位是否为零,再去末位{b=i %10; if(b==0)j++; i=i/10; } return (j); } 2)整体: #include
N阶乘的递归调用展开式
long fact(int n) 1 { 2 long k; 3 if (n<0) 4 { 5 printf( “Data error!\n”); 6 exit(0); 7 } 8 else if (n==0||n==1) k=1; 9 else k=n*fact(n-1); 10 return k; 11 } main() { int n; long f; printf(“Please input an integral number:\n”); scanf(“%d”, &n); f=fact(n); printf(“%d!=%ld\n”, n, f); }
求fact(4)的详解过程, 执行了的语句用红色表示long fact(4) 1 { 2 long k; 3 if (4<0) 4 { 5 printf( “Data error!\n”); 6 exit(0); 7 } 8 else if (4==0||4==1) k=1; 9 else k=4*fact(4-1); /*断点1:调用fact(3)*/ 10 return k; 11 }
long fact(3) 1 { 2 long k; 3 if (3<0) 4 { 5 printf( “Data error!\n”); 6 exit(0); 7 } 8 else if (3==0||3==1) k=1; 9 else k=3*fact(3-1); /*断点2:调用fact(2)*/ 10 return k; 11 }
long fact(2) 1 { 2 long k; 3 if (2<0) 4 { 5 printf( “Data error!\n”); 6 exit(0); 7 } 8 else if (2==0||2==1) k=1; 9 else k=2*fact(2-1); /*断点3:调用fact(1)*/ 10 return k; 11 }
计算N的阶乘
北华航天工业学院 课程设计报告(论文) 设计课题:计算N的阶乘 专业班级: 学生姓名: 指导教师: 设计时间:2010年12月16日
北华航天工业学院电子工程系 微机原理与接口技术课程设计任务书 指导教师:刘金梅教研室主任: 2010年12 月18 日
内容摘要 本次课程设计编写计算N!的程序。数值N由键盘输入,结果在屏幕上输出,通过编制一个阶乘计算程序,了解怎样在汇编语言一级上实现高级语言中的数学函数。其难点在于随着N的增大,其结果远非寄存器所能容纳。这就必须把结果放在一个内存缓冲区中。然而乘法运算只限于两个字相乘,因此要确定好算法,依次从缓冲区中取数,进行两字相乘,并将DX中的高16位积作为产生的进位。 索引关键词:N的阶乘汇编语言内存缓冲区
目录 序言————————————————————5 正文————————————————————5 一、程序算法————————————————-—-5 二、源程序—————————————————-—-6 三、程序运行与调试—————————————-—11 四、N的阶乘程序流动图——————————-—-—11 心得体会——————————————————13 参考文献——————————————————13
序言 本文是关于微型计算机原理写文件课程设计。编写程序,将内存区域中用调试程序(DEBUG)设置好的一连串数据(以Ctrl+z为结束符)做为一个文件存入磁盘,文件名为DATA.ASM。内存区域的段地址和偏移地址在程序中输入。 随着计算机的高速发展,微型计算机已经应用到各个领域,微型计算机原理应用技术已经成为电子信息的核心产业。 微型计算机原理是计算机科学与技术、通讯工程、电气工程、机电工程的核心课程。 通过这次课程设计,是我们更好地理解了课程中所学的理论知识,并把实际问题转化为理论知识,学会如何把学到的知识用于解决实际问题,培养我们的动手能力。 正文 一、程序算法 阶乘的定义为N!=N(N-1)(N-2)……2,从左至右依次计算,结果保存在缓冲区BUF中。缓冲区BUF按结果由高到低依次排列。程序首先将BP初始化为N,N 不等于0或1则将N送入BUF缓冲区最低字节单元中。然后使BP为N-1,以后BP依次减1,直到变化为1为止。每次让BP与BUF中的字节单元按由低到高的次序相乘。低位结果AX仍保存在相应的BUF字节单元中,高位结果DX则送到进位字单元CY中,作为高字相乘时从低字来的进位,初始化CY为0.计算结果的长度随着乘积运算而不断增长。由字单元LEN指示。LEN单元初始化为1。当最高字单元与BP相乘时。若DX不为0,则结果长度要扩展。
大数阶乘与快速排序算法(汇编)
微机原理 课程设计说明书设计题目:大数阶乘与排序 专业 班级 学生 指导教师 2014 年春季学期
目录 目录 (1) 一.课设目的与要求 (2) 1.课设目的 (2) 2.题目要求 (2) 二.基本原理 (2) 1.大数阶乘原理设计 (2) 2.排序原理设计 (2) 三.架构设计 (2) 四.方案实现与测试 (3) 五.分析总结 (9) 六.参考文献 (9)
一.课设目的与要求 1.课设目的:检验和提高学生在汇编语言程序设计,微机原理与接口应用方面分析问 题与解决问题的能力 2.题目要求: 1).要求实现用汇编语言编写设计一个求解大数的阶乘精确值的程序;采用字节型数组 存放阶乘结果的每个数字位,采用逐位相乘,再对每一位规格化来实现;输出结成结果的位数及尾零的个数。 2).用汇编语言编写设计快速排序与希尔排序程序,注意合理使用堆栈,以避免堆栈溢 出,进一步动态显示排序过程。 二.基本原理 1.大数阶乘原理设计:我们在处理一个大于一定范围的数的阶乘时,无论使用什么类型去保存运算结果都必然会发生溢出,这势必会导致运算结果出错。使用数组来模拟数字,这样无论结果数字有多大,只要数组的长度够长就能表示出来,用这个办法可以进行大数据的运算。 2.排序原理设计:快速排序原理:首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。 三.架构设计 核心思想就是把计算结果每一位上的数字保存到一个数组成员中,例如: 把112保存至数组中,保存结果应该是 result[0] 2 result[1] 1 result[2] 1 把整个数组看成一个数字,这个数字和一个数相乘的时候,需要每一位都和这个乘数进行相乘运算还需要把前一为的进位加上。运算方法和小学数学是一样的,乘积的个位是当前位上应该表示的数字,10位以上的需要进位。因为乘数不可能大于10000,所以乘数和一个小于10的书相乘的时候不会大于100000,再加上前一位的进位用一个int型数据来保持这个结果就没有问题。写法如下: int 结果= result[x] * 乘数+ 进位; 每一位的计算结果有了,把这个结果的个位数拿出来放到这个数组元素上: result[x] = 结果%10; 接下来的工作就是计算出进位: 进位= 结果/ 10; 这样一位一位的把整个数组计算一遍,最后可能还有进位,用同样的方法,把进位的数值拆成单个数字,放到相应的数组元素中。
大数的阶乘
大数的阶乘 众所周知,阶乘的定义就是n! = (n-1)!*n,但是有基本的初始条件的,即0! = 1 因此1! = 1*0! = 1 * 1 = 1; 2! = 2*1! = 2 * 1 = 2; 依次类推,但是当n足够大时,整型根本无法装下n的阶乘,如果用C语言来实现的话,根本不可能,那怎么办呢? 其实阶乘也无非是乘法和加法罢了,如4!= 24;我们可以用数组来存各位,结舌数组的起始长度是1哈,每当遇到超过长度时,就自加1,不过这里要稍微处理下的,我们可以倒过来存,以便做乘法的,可以这样来存。 4! 4 2 5! = 5 * 4!,可以用5去乘以4,如果大于10则需向高位进位,下一位的结果就等于下一位乘以5然后加上刚才的进位,当然也要取余数哈,然后继续看有没进位哈,知道遍乘数组每一位哈。 给个能求1000!的例子,用C语言实现的,供大家参考,以便交流学习哈。 #include 教材:《数据结构》严蔚敏吴伟民清华大学出版社 《数据结构算法实现及解析》高一凡西安电子科技大学出版社 第一部分数据结构概述 一、定义(研究是数据结构的存储和数据的操作的) 如何把现实中大量而复杂的问题以特定的数据类型和特定的存储结构保存到主存储器(内存)中,以及在此基础上为实现某个功能(比如查找某个元素,删除某个元素,对所有元素进行排序)而执行的相应操作,这个相应的操作也叫做算法。 数据结构= 个体的存储(从某个角度而言,可忽略)+ 个体与个体之间关系的存储(核心) 算法= 对存储数据的操作 二、算法 解题的方法和步骤 衡量算法的标准 1.时间复杂度 大概程序要执行的次数,而非执行的时间 2.空间复杂度 算法执行过程中大概所占用的最大内存 3.难易程度(即可读性) 4.健壮性 三、数据结构的地位 数据结构是软件中最核心的内容 程序= 数据的存储+ 数据的操作+ 可以被计算机执行的语言 第二部分预备知识 一、指针 指针的重要性:指针是C语言的灵魂 定义 地址:内存单元的编号 从零开始的非负整数 范围:0--FFFFFFFF(即0--4G-1) 指针: 指针就是地址,地址就是指针 指针变量是存放内存单元地址的变量 指针的本质是一个操作受限的非负整数(只能进行减运算)分类: 1.基本类型的指针 2.指针和一维数组的关系 二、结构体 为什么会出现结构体 为了表示一些复杂的数据,而普通的基本类型变量无法满足要求什么叫结构体 结构体是用户根据实际需要自己定义的数据类型 如何使用结构体 两种方式: struct Student st = {1000, "zhangsan", 20} struct Student * pst = &st; 1.st.sid 2.pst->sid pst所指向的结构体变量中的sid这个成员 数的阶乘 很多教材中的阶乘程序只是简单地用了阶乘的定义,算法比较简单,考虑也不够全面,其相应的程序如下: /* 数的阶乘(经典版)*/ #include"stdio.h" main() { extern jiecheng(int n); int n; printf("请输入一个数:"); scanf("%d",&n); jiecheng(n); } extern jiecheng(int n) { long result=1; int i; for(i=1;i<=n;i++) result*=i; printf("该数的阶乘为:%ld\n",result); } 该函数在参数n比较小的时候运行完全正常,但是随着n变大(如,超过12)就出现 了问题,结果会溢出而变成意料之外的数据,究其原因,是因为任何基本类型的变量都有一定的表示范围。要计算更大参数的阶乘,可以使用数组存放阶乘结果,于是有了下面的程序: /* 数的阶乘(改进版)*/ #include"stdio.h" main() { int n; printf("请输入一个数:"); scanf("%d",&n); jiecheng(n); } int jiecheng(int n) { int m,i,j,c,t,a[1000]; a[0]=1; m=1; for(i=2;i<=n;i++) { for(c=0,j=0;j } while(c) { a[m++]=c%10; c/=10; } } printf("该数的阶乘为:"); for(j=m-1;j>=0;j--) printf("%d",a[j]); printf("\n"); } 这样一来,就可以计算大数的阶乘了。如有疑问,多谢赐教! 实验五 一、实验内容 1、掌握3种循环结构:while,do-while,for的区别与联系,以及他们之间相互转换的方法,并能正确使用他们. 2,掌握与循环语句相关的break语句和continue语句的使用方法. 二、实验目的 1、掌握3种循环结构:while,do-while,for的区别与联系,以及他们之间相互转换的方法,并能正确使用他们. 2,掌握与循环语句相关的break语句和continue语句的使用方法. 三、实验步骤 实践教程例题1 1.输入正整数n,计算n的阶乘. 2.实践教程例2 输入若干字符,统计其中数字字符.白字符和其它字符的个数,输入EOF结束. 3、实践教程例3 N个人围坐成一圈,从1开始顺序编号;游戏开始,从第一个人开始由1到m循环报数,报到m的人退出圈外,问最后留下的那个人原来的序号。 4`书2.3 设计程序将输入的百分制成绩转换为五分制输出,90分以上为5分,80~89为4分,70~79为3分,60~69为两分,60分以下为1分。 书2.5 编译打印如下图形 * * * * * * * * * * * * * * * * * * * * * * * * *数据结构概述
关于阶乘的程序编写
输入正整数n,计算n的阶乘c++实验报告