用汇编语言计算N阶乘(0到FFFFH)
汇编计算数的阶乘,可计算1000万内的数的阶乘
本程序作者cabbage功能:计算1亿以内数的阶乘E-mail:1225673051@;**********************求阶乘程序,十进制输入一个数,十进制输出其结果*********************STROUT MACRO ;宏,DOS功能调用,设置字符串输出入口参数MOV AH,09HINT 21HENDMCHAR_IN MACRO ;宏,DOS功能调用,设置字符输入入口参数MOV AH,01HINT 21HENDMDATAS SEGMENT PUBLICDATA1 DB 10H DUP(0)LEN1 DW ?LEN2 DW ?CONST1 DW 30CONST2 DW 40INDEX DB 10H DUP(0)STR0 DB '********************FACTORIAL**********************$'STR1 DB 0AH,0DH,'Please input the num:$'STR2 DB 0AH,0DH,'Error!$'STR3 DB 0AH,0DH,'The result is:$'STR4 DB 0AH,0DH,'****************************************************$'STR5 DB 0AH,0DH,'Thank you for using!$'DATA3 DB 0FF24H DUP(0)DATAS ENDSDATAS1 SEGMENT PUBLICDB 0FFFFH DUP(0)DATAS1 ENDSDATAS2 SEGMENT PUBLICDATA2 DB 0FFFFH DUP(0)DATAS2 ENDSDATAS3 SEGMENT PUBLICDB 0FFFFH DUP(0)DATAS3 ENDSSTACKS SEGMENT STACKDW 2000H DUP(?)TOP LABEL WORDSTACKS ENDSCODES1 SEGMENTASSUME CS:CODES1,DS:DATAS,SS:STACKS,ES:DATAS2START:MOV AX,DATASMOV DS,AXMOV AX,STACKSMOV SS,AXMOV AX,DATAS2MOV ES,AXMOV SP,OFFSET TOPMOV LEN1,OFFSET DATA2MOV LEN2,OFFSET DATA3MOV DX,OFFSET STR0STROUTs1:CALL ZERO ;清零DATA1,DATA2,DATA3,INDEX,为保证运行结果不受前次影响XOR AX,AXXOR BX,BXXOR CX,CXXOR DX,DX ;清零AX,BX,CX,DX等寄存器,为保证运行结果不受前次影响MOV DX,OFFSET STR1STROUTXOR SI,SIdo1:CHAR_INCMP AL,0DHJZ d1CMP AL,'0'JB errorCMP AL,'9'JA errorSUB AL,'0'MOV DS:BYTE PTR [SI],AL ;输入原始数据,按位输入,高位先输INC SIJMP do1d1:CMP SI,0JZ exitMOV CX,SIXOR DI,DIdo2:MOV AL,DS:BYTE PTR [SI-1]MOV ES:BYTE PTR DATA2[DI],AL ;先给DATA2中赋值,使其等于输入的数据INC DIDEC SILOOP do2MOV CX,DIXOR SI,SIXOR DI,DIdo3:MOV AL,ES:BYTE PTR DATA2[DI]MOV DS:BYTE PTR [SI],ALINC DI ;再将DATA1中的数据实现,高位存放在地址较大的存储单元INC SILOOP do3s2:XOR AX,AXCALL FAR PTR FAC ;调用阶乘计算函数CMP SI,1 ;当还没有计算到1时,再次进入阶乘函数JNZ s2MOV AL,DS:BYTE PTR [SI-1]CMP AL,1JZ s3JMP s2s3:CALL FAR PTR RESULT ;输出结果JMP s1error:MOV DX,OFFSET STR2STROUTJMP s1exit:MOV DX,OFFSET STR5STROUTMOV AH,4CHINT 21HCODES1 ENDS;*********************************************************CODES2 SEGMENTASSUME CS:CODES2,DS:DATAS,SS:STACKS,ES:DATAS2;递归子过程,计算阶乘,没当递归次数大于等于5000时,返回再次进入,降低栈对递归的限制FAC PROC FARINC AXPUSH AXdo6:MOV AL,ES:BYTE PTR DATA2[DI-1]DEC DICMP AL,0JZ do6INC DICMP DI,CONST2JB s4CALL FAR PTR DZEROs4:CMP SI,1JNZ s5MOV AL,DS:BYTE PTR [SI-1]CMP AL,1JZ s9JMP s6s5:MOV CX,SIDEC CXXOR BP,BPMOV AL,DS:BYTE PTR [BP]SUB AL,1PUSHFAASMOV DS:BYTE PTR [BP],ALdo4:INC BPMOV AL,DS:BYTE PTR [BP]POPFSBB AL,0PUSHFAASMOV DS:BYTE PTR [BP],ALLOOP do4POPFMOV AL,DS:BYTE PTR [SI-1]CMP AL,0JNZ s7DEC SIJMP s7s6:MOV AL,DS:BYTE PTR [SI-1]SUB AL,1MOV DS:BYTE PTR [SI-1],ALs7:CALL FAR PTR MULTPOP AXCMP AX,1388HJZ s8CALL FAR PTR FACs8:RETs9:POP AXRETFAC ENDPCODES2 ENDS;*********************************************************;乘法运算函数,用于多位非压缩码BCD数(DATA1)与多位非压缩码BCD数(DATA2)的乘法运算;,并将结果存放在DATA2中。
C语言大数阶乘的求法
C语⾔⼤数阶乘的求法 ⼀个朋友问我⼀个问题100!利⽤C语⾔怎么实现。
我很当然的写了以下的代码:#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>#include <string.h>int main(){int i;int N=0;int factorial = 1;printf("请输⼊你要的求的阶乘数N\n");scanf("%d", &N);for (i = 1; i <= N; i++){factorial = factorial*i;}printf("%d!=%d",N,factorial);system("pause");return0;}我输⼊⼩数时,结果是没有问题的,但是当我计算100!的时候,发现100!居然是0.这个时候我意识到是不是100!超过我设置的数据类型的范围。
但是我发现在C语⾔中并没有⼀个数据类型可以容纳100!上⽹查询,我发现可以使⽤数组来存储⼤数,原理通俗说就是当⼀个盒⼦(内存)⽆法容纳⼀个⼤数,把⼤数分开放在多个盒⼦⾥(数组),把盒⼦按照顺序输出。
下⾯是⽹上找的⼀个代码,注释很清楚#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>#include <string.h>void factorial(int n, char *pout){if (pout == NULL){return;}int arr[256];int idx = 1;arr[0] = 1;//此处要注意 i从1开始for (int i = 1; i <= n; i++){//cry⽤来记录进位int cry = 0;// idx记录现在有多少位 挨个相乘for (int j = 0; j < idx; j++){arr[j] = arr[j] * i + cry;//此处⽤倒序存储cry = arr[j] / 10;arr[j] %= 10;}//如果进位⼤于10 要降级while (cry > 10){arr[idx++] = cry % 10;cry /= 10;}//进位到这⾥如果还⼤于 0 证明位数要加1if (cry > 0)arr[idx++] = cry;}//将数组倒序赋值给字符串for (int i = idx - 1; i >= 0; i--){*pout++ = arr[i] + '0'; }*pout = '\0';return;}int main(){char buff[255] = {0}; int n = 0;printf("input n:");scanf("%d", &n);factorial(n, buff);puts(buff);return0;}。
n的阶乘c语言程序递归
n的阶乘c语言程序递归递归是一种在函数中调用自身的方式,可以用来解决一些需要重复求解的问题。
阶乘是一个典型的递归问题,可以用递归方式来求解。
阶乘的定义是:n的阶乘(记作n!)是从1乘到n的连续自然数相乘的积。
例如,5的阶乘为5! = 5 × 4 × 3 × 2 × 1 = 120。
下面我们来编写一个能够计算n的阶乘的递归函数。
```c#include <stdio.h>//递归函数,计算n的阶乘int factorial(int n) {//基线条件,当n为1时,直接返回1if (n == 1) {return 1;}//递归调用,将问题规模减小,继续求解return n * factorial(n - 1);}//主函数int main() {int n;printf("请输入一个整数n:");scanf("%d", &n);if (n < 0) {printf("请输入一个非负整数!\n"); return 0;}int result = factorial(n);printf("%d的阶乘是:%d\n", n, result);return 0;}```在上面的代码中,我们定义了一个名为factorial的递归函数,用来计算n的阶乘。
这个函数的基线条件是当n为1时,直接返回1。
否则,将问题规模减小,并继续递归求解。
递归调用的参数是n-1,这样问题的规模就减小了,直到遇到基线条件终止递归。
在主函数中,我们从用户输入获取一个整数n,然后调用factorial函数求解n的阶乘,并将结果输出。
递归调用过程中,每次调用都会将问题规模减小,直到达到基线条件。
因此,递归函数的效率与问题规模有关。
对于阶乘问题,递归的时间复杂度是O(n)。
需要注意的是,递归过程中可能会出现栈溢出的问题。
微机课设报告(计算N的阶乘)
目录一、实验要求.......................... . (3)二、实验内容 (3)三、实验思路 (3)四、实验过程 (5)五、实验总结 (12)一、实验要求实验目的(1)、堆栈传递参数的子程序调用方法。
(2)、序递归调用方法。
(3)、伪指令:PROC,ENDP,NEAR和FAR。
(4)、指令:CALL,RET,RET n。
(5)、T指令推出EXE文件的方法。
(6)、了解怎样在汇编语言一级上实现高级语言中的数学函数。
二、实验内容1、实验内容计算N!:编写计算N阶乘的程序,数值N由键盘输入,N的值要在0到65536之间(用一个16位的字表示),结果在显示器上显示。
2、实验步骤(1)、打开开始菜单,单击运行,在对话框中输入“cmd”,进入dos窗口。
(2)、输入cd\masm5 回车,在输入edit 回车,进入汇编窗口。
(3)、输入代码。
(4)、保存代码,后缀名为.asm。
(5)、回到dos窗口,输入masm文件名保存位置,文件名回车。
(6)、调试程序,根据提示回到汇编窗口,对代码进行修改,直至出现no error及no warrings。
三、实验思路、1、算法阶乘的定义为N!=N*(N-1)*(N-2)*……2*1,从走往右翼此计算,解雇保留在缓冲区BUF中。
缓冲区BUF按由低到高依次排列。
程序首先将BP初始为N,N 不等于0获1则将N送入BUF缓冲区最低自单元中。
然后使BP一次减1,直至变化到1为止。
每次让BP与BUF的字单元按照由低到高的次序香橙。
低位结果AX仍保存在相应的BUF自单元中,高位结果DX泽送到进位子单元CY 中,作为高字香橙时从低字来的进位,初始化CY为0。
计算结果的长度随着成绩运算而不断增长,由字单元LEN指示,LEN单元初始化为1。
当最高字单元与BP香橙时,若DX不为0,则结果长度要扩展。
2、流程图四、实验过程1、源程序CRLF MACRO ;回车,换行MOV AH,02HMOV DL,0DHINT 21HMOV AH,02HMOV DL,0AHINT 21HENDMDATA SEGMENTMESS1 DB 'INPUT THE NUMBER ACCORDING TO HEXNUM!',0DH,0AH,'$' MESS2 DB 'THE RESULT IS:$'ERROR DB 'INPUT ERROR!INPUT ONCE MORE!',0DH,0AH,'$'LEN DW 1CY DW ?BUF DW 256 DUP(0)DATA ENDSSTACK SEGMENT STACK 'STACK'DW 32 DUP(?)STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACKSTART: MOV AX,DATAMOV DS,AXMOV ES,AXMOV AH,09HMOV DX,OFFSET MESS1INT 21H ;显示输入提示信息CALL GETNUM ;读取键入的N值MOV BP,DX ;N值送BPCMP BP,0JZ EEECMP BP,1JZ EEE ;N=0或N=1则转EEEMOV SI,OFFSET BUF ;缓冲区首址MOV [SI],DXXXX: DEC BP ;N值减1CMP BP,0001HJZ LLL ;若为1则转LLLXOR BX,BX ;偏移指针清0MOV WORD PTR CY,0 ;进位单元清0MOV CX,LEN ;当前结果长度送CXTTT: MOV AX,[SI+BX]MUL BP ;相乘ADD AX,CY ;加低位进位JNC JJJ ;结果无进位转JJJINC DX ;有进位将高位单元加1 JJJ: MOV [SI+BX],AX ;结果送缓冲区中MOV CY,DX ;高位单元送进位单元INC BXINC BX ;一个字长度LOOP TTT ;循环CMP DX,0000HJZ BBB ;最后一次的进位为0则转BBB INC WORD PTR LEN ;长度加1MOV [SI+BX],DX ;进位送缓冲区中BBB: JMP XXXEEE: MOV SI,OFFSET BUFMOV WORD PTR b[SI],1 ;结果为1LLL: MOV AH,09HMOV DX,OFFSET MESS2INT 21H ;显示表头MOV CX,LENMOV BX,CX ;长度DEC BXSHL BX,1 ;一个字为两个字节CCC: MOV AX,[SI+BX]CALL DISPDEC BXDEC BX ;显示结果LOOP CCCMOV AX,4C00H ;结束INT 21HDISP1 PROC NEAR ;显示字符(AL)MOV BL,ALMOV DL,BLMOV CL,04ROL DL,CLAND DL,0FHCALL DISPL ;显示高位MOV DL,BLAND DL,0FHCALL DISPL ;显示低位RETDISP1 ENDPDISPL PROC NEAR ;显示一位(DL=0XH)CMP DL,3AHJB DDDADD DL,27HDDD: MOV AH,02HINT 21HRETDISPL ENDPDISP PROC NEAR ;显示4位数(HEC) PUSH BXPUSH CXPUSH DXPUSH AXMOV AL,AHCALL DISP1POP AXCALL DISP1POP DXPOP CXPOP BXRETDISP ENDPGETNUM PROC NEAR ;字符匹配程序PUSH CXREGET:XOR DX,DXGGG: MOV AH,01HINT 21HCMP AL,0DHJZ PPPCMP AL,20HJZ PPPSUB AL,30HJB KKKCMP AL,0AHJB GETSCMP AL,11HJB KKKSUB AL,07HCMP AL,0FHJBE GETSCMP AL,2AHJB KKKCMP AL,2FHJA KKKGETS: MOV CL,04HSHL DX,CLXOR AH,AHADD DX,AXJMP GGGKKK: CRLFMOV AH,09HMOV DX,0FFSET ERROR INT 21HJMP REGETPPP: PUSH DXCRLFPOP DXPOP CXRETGETNUM ENDPCODE ENDSEND START2、测试结果输入程序把程序都输入进去后,进行调试,直至出现0个错误和0个警告!调试完程序之后,输入LINK,对程序进行编译。
c语言高精度计算n的阶乘
c语言高精度计算n的阶乘高精度计算是指在计算机中进行大数运算时,能够精确表示和计算超过计算机位数范围的整数或小数。
在计算n的阶乘时,如果n很大,传统的计算方法可能会导致溢出或精度丢失,因此需要使用高精度计算的方法。
C语言是一种广泛应用于系统软件和应用软件开发的高级程序设计语言。
它支持对内存的直接访问,并提供了丰富的库函数,可以方便地进行高精度计算。
本文将介绍如何使用C语言实现高精度计算n的阶乘。
我们需要明确阶乘的定义。
阶乘是指从1到n的连续整数的乘积,表示为n!。
例如,5的阶乘为5! = 5 ×4 × 3 × 2 × 1 = 120。
传统的计算n的阶乘的方法是使用循环结构,从1到n依次相乘。
但是,当n很大时,结果可能会超出计算机能够表示的范围。
为了避免这个问题,我们可以使用数组来表示大数,并模拟手工计算的过程。
具体实现时,我们可以使用一个整型数组来存储大数的每一位。
数组的每个元素表示一个位数,例如,数组的第一个元素表示最低位,最后一个元素表示最高位。
为了方便计算,我们可以将大数按照逆序存储,即最低位存储在数组的最后一个元素中。
我们需要定义一个函数来实现大数的乘法。
该函数接受两个大数作为参数,并返回它们的乘积。
具体实现时,我们可以使用两层循环遍历两个大数的每一位,并将结果保存在一个新的大数中。
在计算过程中,需要注意进位的处理。
接下来,我们可以定义一个函数来计算n的阶乘。
该函数接受一个整数n作为参数,并返回n的阶乘。
具体实现时,我们可以使用一个循环从2到n,依次计算每个数的阶乘,并将结果与之前的乘积相乘。
在计算过程中,为了避免溢出,我们可以使用前面提到的大数乘法函数。
我们可以在主函数中调用阶乘函数,并输出结果。
为了方便观察,我们可以将大数按照正常顺序输出,即从最高位到最低位。
具体实现时,可以使用一个循环从最高位到最低位遍历大数数组,并将每一位转换为字符型后输出。
用汇编语言计算N阶乘(0到FFFFH)
用汇编语言计算N阶乘(0到FFFFH)一、设计题目编写计算N!的程序(数值N由键盘输入,结果在屏幕上输出。
N的范围为0-65535,即刚好能被一个16位寄存器容纳)。
二、开发目的由于当N值较大时(N>10),N的阶乘计算很繁琐并且计算容易出错。
所以可以编写计算N!的程序,利用计算机强大的计算能力计算N!。
这不仅能节省繁琐计算的时间,而且得到的N!的积比起手工算的要准确。
三、设计方案N的阶乘为1*2*3……(N-1)*N,N的范围为(0000H—FFFFH),N!以字为单位存在一个或几个定义的数据段中。
若已算到(n-1)!,假如它占4个字的空间,接下来它乘以n的原理,如图1所示。
图1 (n-1)!* n的原理因此计算N!的算法可以这样编写,当前n!的值为被乘数,内容存在str2中,单位为字,n+1的值为乘数,存在str1中,单位也为字。
被乘数从str2首地址中内容开始与乘数相乘,得到32位的积,它的低16位覆盖掉当前被乘数所在存储空间的内容。
接着str2下一个字的内容与乘数相乘,也得到32位的积,前一个积的高16位与现在积的低16位相加,它们的和覆盖掉当前被乘数所在存储空间的内容,若它们的和有进位,把进位加到现在积的高16位。
直到把str2中内容乘完。
然后乘数增1,循环上面的内容。
直到执行完(N-1)!*N输入的N为4位16进制数,输出也为16进制数。
四、程序流程图五、程序清单data1 segmentinput1 db 'please input the number :','$'input2 db 10,?,10 dup(?) ;输入的16进制数error db 'Out of range','$'output1 db 'The answer is 1','$'output2 db 'The answer is :','$'str1 dw 100 dup(?) ;保存1—N(后一个数覆盖前一个数)str2 dw 7000h dup(?) ;N!乘积的值(1)p dw 100 dup(?) ;上一个乘积的高16位data1 endsdata2 segmentstr3 dw 7fffh dup(?) ;N!乘积的值(2)data2 endscode segmentassume cs:code,ds:data1,es:data2org 100h ;程序从偏移地址100h开始执行start: mov ax,data1 ;程序初始化mov ds,axmov ax,data2mov es,ax ;初始化结束mov ah,9lea dx,input1int 21hmov ah,2 ;回车mov dl,0dhint 21hmov ah,2 ;换行mov dl,0ahint 21hmov ah,0ah ;输入所需求的N值(N为16进制数)lea dx,input2int 21hmov ah,2mov dl,0dhint 21hmov ah,2mov dl,0ahint 21hlea bx,input2mov al,[bx+1] ;判断输入的N值是否超过FFFFH cmp al,4ja s1mov cl,4 ;把输入的N值有ASCH码转成16进制数mov ah,[bx+2]mov al,[bx+3]cmp al,39hja abc1def1: shl al,clcmp ah,39hja abc2def2: shr ax,clmov dh,almov ah,[bx+4]mov al,[bx+5]cmp al,39hja abc3mov cl,4def3: shl al,clcmp ah,39hja abc4def4: shr ax,clmov dl,al ;转换结束mov ax,dx ;判断N值是否为0cmp ax,0jz s2jmp s3abc1: sub al,37hjmp def1abc2: sub ah,37hjmp def2abc3: sub al,37hjmp def3abc4: sub ah,37hjmp def4s1: mov ah,9 ;若N值超过FFFFH的输出lea dx,errorint 21hjmp nexts2: mov ah,9 ;N值为1的输出lea dx,output1int 21hjmp nexts3: mov cx,ax ;计算N的阶乘mov ax,1mov [str1],ax ;N从1开始,作为乘数lea si,str2mov [si],ax ;N!的积从1开始,作为被乘数mov ax,0mov [p],ax ;(n-1)!的乘积的低16位与n相乘后积的高16位mov bx,1 ;开始N!的乘积占一个字空间mov WORD ptr[p+10],0 ;(n-1)!的乘积的高16位与n相乘后积的低16位和(n-1)!的乘积的低16位与n相乘后积的高16位的和的进位,初始进位为0 mov ah,9lea dx,output2int 21hmov ah,2mov dl,0dhint 21hmov ah,2mov dl,0ahint 21hlop2: mov [p+2],bxlop3: mov ax,[si] ;(n-1)!的乘积从最低16位的内容与n相乘mov dx,[str1]mul dxclcadd ax,[p+10] ;前一次的进位与当前乘积的低16位内容相加jnc k1 ;判断是否产生进位mov WORD ptr[p+10],1add ax,[p] ;前一个积的高16位与现在积的低16位相加jmp k2k1: add ax,[p]jnc k3 ;判断是否产生进位mov WORD ptr[p+10],1jmp k2k3: mov WORD ptr[p+10],0k2: mov [si],axmov [p],dxadd si,2dec bxcmp bx,0jnz lop3mov bx,[p+2]clcadd dx,[p+10]cmp dx,0jz re ;判断(n-1)!乘积的最高16位内容与n的乘积的高16位是否为0inc bxmov [si],dxre: mov ax,[str1]cmp ax,9000h ;判断是N!乘积的内容高位部分是否要存到es 中jnc re1jmp re2re1: cmp cx,1ja s4re2: inc WORD ptr[str1] ;乘数增1lea si,str2mov WORD ptr[p],0mov WORD ptr[p+10],0loop lop2dec bxmov cx,bxlop4: add si,2loop lop4inc bxadd bx,bxinc sijmp lop5s4: inc WORD ptr[str1] ;若N的值超过8000h,8000h*8001h*8002h*N mov [p+6],bxmov [p+8],bxlea si,str2lea di,str3mov es:[di],dxmov WORD ptr[p],0mov WORD ptr[p+10],0mov bx,1dec cxlop6: mov [p+4],bxlop7: mov ax,[si]mov dx,[str1]mul dxclcadd ax,[p+10]jnc k4mov WORD ptr[p+10],1add ax,[p]jmp k5k4: add ax,[p] ;前一个积的高16位与现在积的低16位相加,产生进位jnc k6mov WORD ptr[p+10],1jmp k5k6: mov WORD ptr[p+10],0k5: mov [si],axadd si,2mov [p],dxdec WORD ptr[p+6]mov ax,[p+6]cmp ax,0jnz lop7mov ax,[p+8]mov [p+6],axlop8: mov ax,es:[di]mov dx,[str1]mul dxclcadd ax,[p+10]jnc k7mov WORD ptr[p+10],1add ax,[p]jmp k8k7: add ax,[p] ;前一个积的高16位与现在积的低16位相加,产生进位jnc k9mov WORD ptr[p+10],1 jmp k8k9: mov WORD ptr[p+10],0 k8: mov es:[di],axadd di,2mov [p],dxdec bxcmp bx,0jnz lop8mov bx,[p+4]clcadd dx,[p+10]cmp dx,0jz re4inc bxmov es:[di],dxre4: inc WORD ptr[str1] lea si,str2lea di,str3mov WORD ptr[p],0mov WORD ptr[p+10],0 dec cxcmp cx,0jnz lop6dec bxmov cx,bxlop9: add di,2loop lop9inc bxinc dilop10: dec bx ;若N>8000h,输出N!乘积的高位内容mov al,BYTE ptr es:[di]mov ch,almov cl,4shr al,clcmp al,09hja op3add al,30hjmp ip3op3: add al,37hip3: mov ah,2mov dl,alint 21hmov al,chand al,0fhcmp al,09hja op4add al,30hjmp ip4op4: add al,37hip4: mov ah,2mov dl,alint 21hdec dicmp bx,0jnz lop10mov bx,[p+6]dec bxmov cx,bxlop11: add si,2loop lop11inc bxadd bx,bxinc silop5: dec bx ;输出N!的乘积mov al,BYTE ptr [si]mov ch,almov cl,4cmp al,09hja op1add al,30hjmp ip1op1: add al,37hip1: mov ah,2mov dl,alint 21hmov al,chand al,0fhcmp al,09hja op2add al,30hjmp ip2op2: add al,37hip2: mov ah,2mov dl,alint 21hdec sicmp bx,0jnz lop5next: mov ah,1int 21hmov ah,4chint 21hcode endsend start六、程序运行结果与分析若输入的16进制数N为000A(10进制为10),程序运行后输出的N!应为375F00(H)。
c语言用递归方法求n的阶乘
C语言用递归方法求n的阶乘介绍在计算机编程中,递归是一种非常常用的技巧和思维方式。
递归是指在函数的定义中使用函数本身。
本篇文章将深入探讨如何使用递归方法求解n的阶乘,其中n是一个非负整数。
什么是阶乘阶乘是一个非常基础的数学运算,表示从1到给定的数字n之间的所有整数的乘积。
例如,5的阶乘表示为5!,计算过程如下:5! = 5 × 4 × 3 × 2 × 1 = 120可以看出,阶乘是一个逐渐减小的过程,直到最后乘到1为止。
递归方法求n的阶乘递归方法是一种将一个问题分解为更小规模的子问题,并通过解决子问题来解决原始问题的方法。
用递归方法求解n的阶乘,可以将问题分解为计算n与(n-1)的阶乘的乘积。
具体的递归求解阶乘的C语言代码如下所示:#include <stdio.h>unsigned long long factorial(unsigned int n) {if (n <= 1) {return 1;} else {return n * factorial(n - 1);}}int main() {unsigned int n = 5;unsigned long long result = factorial(n);printf("The factorial of %d is %llu\n", n, result);return 0;}在上述代码中,我们定义了一个名为factorial的递归函数,用于计算n的阶乘。
如果n小于等于1,那么阶乘的结果就是1;否则,我们通过调用函数本身来计算(n-1)的阶乘,并将其乘以n,从而得到n的阶乘。
在main函数中,我们给定了一个示例值n=5,并输出计算结果。
递归方法的工作原理递归方法的核心思想是将一个大问题分解为一个或多个规模更小的子问题。
在本例中,我们将计算n的阶乘的问题分解为计算(n-1)的阶乘的问题,直到将问题进一步简化为计算1的阶乘的问题。
采用汇编语言实现阶乘运算-推荐下载
microcomputer, the microcomputer host functions and interfaces to achieve should be achieved through the assembly language. Despite the low efficiency of assembly language programming programming, but it’s high operating efficiency, and speed. Therefore, the assembly language is the first step to learn Microcomputer Principle and Interface Design. Written calculation of N! Procedures. Numerical keyboard input, output results on the screen.
汇编语言程序设计报告
课程设计题目:采用汇编语言实现阶乘运算
学 号: 10081437 姓 名: 张子琦 院 系: 测试与光电工程学院 专 业: 测控技术与仪器 指导教师: 陈振华
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术通关,1系电过,力管根保线据护敷生高设产中技工资术艺料0不高试仅中卷可资配以料置解试技决卷术吊要是顶求指层,机配对组置电在不气进规设行范备继高进电中行保资空护料载高试与中卷带资问负料题荷试2下卷2,高总而中体且资配可料置保试时障卷,各调需类控要管试在路验最习;大题对限到设度位备内。进来在行确管调保路整机敷使组设其高过在中程正资1常料中工试,况卷要下安加与全强过,看度并22工且22作尽22下可22都能22可地护以缩1关正小于常故管工障路作高高;中中对资资于料料继试试电卷卷保破连护坏接进范管行围口整,处核或理对者高定对中值某资,些料审异试核常卷与高弯校中扁对资度图料固纸试定,卷盒编工位写况置复进.杂行保设自护备动层与处防装理腐置,跨高尤接中其地资要线料避弯试免曲卷错半调误径试高标方中高案资等,料,编试要5写、卷求重电保技要气护术设设装交备备置底4高调、动。中试电作管资高气,线料中课并敷3试资件且、设卷料中拒管技试试调绝路术验卷试动敷中方技作设包案术,技含以来术线及避槽系免、统不管启必架动要等方高多案中项;资方对料式整试,套卷为启突解动然决过停高程机中中。语高因文中此电资,气料电课试力件卷高中电中管气资壁设料薄备试、进卷接行保口调护不试装严工置等作调问并试题且技,进术合行,理过要利关求用运电管行力线高保敷中护设资装技料置术试做。卷到线技准缆术确敷指灵设导活原。。则对对:于于在调差分试动线过保盒程护处中装,高置当中高不资中同料资电试料压卷试回技卷路术调交问试叉题技时,术,作是应为指采调发用试电金人机属员一隔,变板需压进要器行在组隔事在开前发处掌生理握内;图部同纸故一资障线料时槽、,内设需,备要强制进电造行回厂外路家部须出电同具源时高高切中中断资资习料料题试试电卷卷源试切,验除线报从缆告而敷与采设相用完关高毕技中,术资要资料进料试行,卷检并主查且要和了保检解护测现装处场置理设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。
高精度计算n阶乘的c语言源代码和解释
/*begin函数声明**********************/
int Input_uint(); //无符号整形输入函数
/*end函数声明************************/
/*begin自定义类型******************/
/*end自定义类型********************/
{
if (str[count_a]>='0' && str[count_a]<='9')
{
number+=(str[count_a]-'0')*ratio;
ratio*=10;
}
else
break;
}
}
}while(judge<0);
return number;
}
/*end函数定义***********************/
do
{
if (judge==1) ;
else
printf("\n输入错误。请输入一个大于等于零的整数:");
judge=1;
for(count_a=HEAD_N-1,count_c=HEAD_N-1;count_a>=0;count_a--,count_c--)
c语言递归函数求n的阶乘
c语言递归函数求n的阶乘阶乘,又称阶乘函数,指从1到某个正整数n的所有整数的乘积,通常用符号n!表示。
例如,5! = 5 × 4 × 3 × 2 × 1 = 120。
阶乘是一个非常基础的数学概念,在计算机编程中也经常用到。
本文将介绍如何使用C语言递归函数来求n的阶乘。
递归函数是指在函数的定义中使用函数自身的方法。
在C语言中,递归函数可以通过函数调用自身来实现。
为了避免无限递归的问题,递归函数通常会在函数内部添加一个递归结束条件,当满足条件时,函数将不再调用自身,从而结束递归。
下面是一个使用递归函数求n的阶乘的示例代码:```c#include <stdio.h>int factorial(int n){if (n == 0 || n == 1) // 递归结束条件{return 1;}else{return n * factorial(n - 1); // 递归调用}}int main(){int n;printf('请输入一个正整数n:');scanf('%d', &n);printf('%d的阶乘为:%d', n, factorial(n));return 0;}```在上述代码中,我们定义了一个名为factorial的函数,它接受一个整数n作为参数,并返回n的阶乘。
在函数内部,我们首先判断n是否为0或1,如果是,则返回1,这是递归结束的条件。
否则,我们通过调用自身来计算n的阶乘,具体来说,我们将n乘以factorial(n-1),这样就可以一直递归下去,直到n等于0或1时结束递归。
在主函数中,我们先从用户那里读取一个正整数n,然后调用factorial函数来计算n的阶乘,并将结果输出到屏幕上。
在实际编程中,我们需要注意递归深度的问题。
递归深度指的是递归函数调用自身的次数,如果递归深度过大,可能会导致栈溢出等问题。
c语言填空题求n的阶乘程序
c语言填空题求n的阶乘程序阶乘是指将一个正整数 n 与 n-1、n-2、n-3...1 相乘,即 n! = n * (n-1) * (n-2) * ... * 1。
编写一个 C 语言程序,通过填空的方式求给定正整数 n 的阶乘。
下面是完整的代码:```c#include <stdio.h>long long factorial(int n) {long long result = 1;for(int i = 1; i <= n; i++) {result *= i;}return result;}int main() {int n;printf("请输入一个正整数:");scanf("%d", &n);long long result = factorial(n);printf("%d的阶乘是:%lld\n", n, result);return 0;}```在这个程序中,我们使用了一个名为 factorial 的函数来计算阶乘。
该函数接受一个整数参数 n,并返回一个 long long 类型的结果。
在主函数 main 中,我们首先定义了一个整数变量 n,用于存储用户输入的正整数。
然后通过 scanf 函数向用户请求输入一个正整数,并将其保存到变量 n 中。
接下来,我们调用 factorial 函数,传入变量 n 作为参数,并将返回的结果保存到变量 result 中。
最后,使用 printf 函数打印出计算得到的阶乘结果。
这个程序的运行流程如下:1. 用户输入一个正整数。
2. 程序调用 factorial 函数,传入用户输入的正整数,并计算阶乘结果。
3. 阶乘结果被保存在 result 变量中。
4. 程序打印出计算得到的阶乘结果。
注意,本程序使用了 long long 类型来存储阶乘结果,以保证在计算大数阶乘时不会溢出。
简单阶乘计算c语言
简单阶乘计算c语言阶乘是数学中的一个重要概念,也是计算机科学中常见的计算题目。
在C语言中,计算阶乘是一项简单的任务。
本文将介绍如何使用C语言计算阶乘,包括输入、循环和输出等基本操作。
首先,我们需要了解阶乘的概念。
阶乘指的是一个自然数 n 的阶乘,表示 n × (n-1) × (n-2) ×…× 2 × 1,通常用符号 n! 表示。
例如,4! = 4 × 3 × 2 × 1 = 24。
接着,我们需要使用C语言的输入函数 scanf() 获取用户输入的数值,并将其存储到一个变量中。
例如,我们可以使用以下代码获取用户输入的数值:int n;printf('请输入一个自然数n:');scanf('%d', &n);其中,%d 表示输入一个整数,&n 表示将输入的值存储到变量 n 中。
接下来,我们使用一个循环来计算 n 的阶乘。
通常,我们使用for 循环来实现阶乘的计算。
例如,以下代码可以计算 n 的阶乘: int i, result = 1;for (i = 1; i <= n; i++) {result *= i;}在上面的代码中,我们定义了一个变量 i 和一个变量 result,变量 i 用于循环计数,变量 result 初始值为 1。
在每次循环中,我们将 result 乘以 i,最终得到 n 的阶乘。
最后,我们使用输出函数 printf() 来显示计算结果。
以下代码可以将计算结果输出到屏幕上:printf('%d的阶乘为%d', n, result);在上面的代码中,%d 表示输出一个整数,表示换行符。
通过这个输出语句,我们可以将计算出来的阶乘结果显示在屏幕上。
综合以上几个步骤,我们可以得到完整的阶乘计算程序:#include <stdio.h>int main() {int n, i, result = 1;printf('请输入一个自然数n:');scanf('%d', &n);for (i = 1; i <= n; i++) {result *= i;}printf('%d的阶乘为%d', n, result);return 0;}以上代码可以读取用户输入的自然数 n,并计算其阶乘,最后将结果输出到屏幕上。
汇编语言功能用循环累加实现乘法
汇编语⾔功能⽤循环累加实现乘法⽬录问题1:编程计算2的2次⽅,结果存在ax中分析:⽤2+2实现问题2:编程实现2的12次⽅分析:⽤loop实现问题3:编程实现123*236,结果存在ax中分析:⽤236相加123次的计算次数⽐较少,节约计算资源问题4:计算ffff:0006单元中的数乘以3,结果存储在dx中1、判断数据是否能够存储2、判断数据相加是否能够位数相同问题5:计算ffff:0~ffff:b单元中的数据的和,结果存储在dx中1、运算的结果是否超出寄存器的范围2、能否直接相加dx中的数据问题6:计算data段中第⼀组数据的3次⽅,结果保存在后⾯⼀组的dword单元中1、需要利⽤⼀个⼦程序包装出计算的功能问题1:编程计算2的2次⽅,结果存在ax中分析:⽤2+2实现assume cs:codecode segmentmov ax,2add ax,ax;实现程序的返回mov ax,4c00hint 21hcode endsend问题2:编程实现2的12次⽅分析:⽤loop实现assume cs:codecode segmentmov ax,2mov cx,11 ;设置循环次数,只需相加11次s:add ax,axloop smov ax,4c00hint 21hcode endsend问题3:编程实现123*236,结果存在ax中分析:⽤236相加123次的计算次数⽐较少,节约计算资源assume cs:codecode segmentmov ax,236mov cx,122s:add ax,axloop smov ax,4c00hint 21hcode endsend问题4:计算ffff:0006单元中的数乘以3,结果存储在dx中分析:1、判断数据是否能够存储因为内存单元中存储的是字节型数据,范围在0~255之间,乘上8之后不会⼤于16位dx寄存器的存储范围0~655352、判断数据相加是否能够位数相同内存单元是字节单元,如果⽤寄存器直接相加,数据的长度不⼀样,所以需要将寄存器变成8位,则只需要将⾼8位设置为0,⽤低8位相加即可assume cs:codecode segment;设置地址指向为ffff:0006mov ax,0ffffh ;字母开头的常量前⾯需要加0mov ds,axmov bx,6 ;ds:bx则为数据的指向mov al,ds:[bx]mov ah,0mov dx,0 ;初始化寄存器中的内容mov cx,3 ;因为不是⾃⾝相加,所以需要3次s:add dx,axloop smov ax,4c00hint 21h ;程序返回code endsend问题5:计算ffff:0~ffff:b单元中的数据的和,结果存储在dx中分析:1、运算的结果是否超出寄存器的范围12个字节型数据的相加,结果不会超过655352、能否直接相加dx中的数据8位的数据不能直接相加到16位的寄存器中,如果⽤低8位进⾏相加,结果可能会超出8位存储的范围,所以只能先将数据存放到16位的寄存器中,在与dx相加assume cs:codecode segmentmov ax,0ffffhmov ds,axmov bx,0 ;ds:bx指向ffff:0mov dx,0mov cx,12 ;12次到ffff:bs: mov al,ds:[bx]mov ah,0add dx,ax ;利⽤ax进⾏相同位数的相加inc bx ;向后移动⼀个单元loop smov ax,4c00hint 21hcode endsend问题6:计算data段中第⼀组数据的3次⽅,结果保存在后⾯⼀组的dword单元中分析:1、需要利⽤⼀个⼦程序包装出计算的功能2、同时需要两个寄存器分别保存和修改其中的内容assume cs:code,ds:datadata segmentdw 1,2,3,4,5,6,7,8dw 8 dup(0)data endscode segmentstart: mov ax datamov ds,axmov si,0 ;ds:si指向第⼀组word单元mov di,16 ;ds:di指向第⼆组dword单元mov cx,8s: mov bx,ds:[si]call cubemov ds:[di],ax ;计算的结果低16位保存在ax中mov ds:[di+2],dx ;计算的结果⾼16位保存在dx中add si,2 ;ds:si指向下⼀个word单元add di,4 ;ds:di指向下⼀个dword单元loop smov ax,4c00hint 21hcude: mov ax,bxmul bxmul bxretcode endsend start以上就是汇编语⾔功能⽤循环累加实现乘法的详细内容,更多关于汇编语⾔循环累加实现乘法的资料请关注其它相关⽂章!。
汇编--n阶乘
一、实验目的1. 掌握子程序的设计方法;2. 掌握递归子程序的设计思想;3. 体会堆栈操作在子程序嵌套中的重要作用。
二、实验原理及基本技术路线图(方框原理图)一个子程序作为调用程序去调用另一子程序,这种关系称为子程序嵌套。
由于子程序嵌套对堆栈的使用很频繁,因此还要确保堆栈有足够空间,并要注意堆栈的正确状态,这包括CALL、RET、RET N、PUSH、POP、INT、IRET等与堆栈操作有关指令的正确使用。
在子程序嵌套的情况下,如果一个子程序调用的子程序就是它自身,这样的子程序称为递归子程序。
显然递归调用是子程序嵌套的一种特殊情况。
使用递归算法往往能设计出效率较高的程序。
设计递归子程序时,必须保证每一次后继调用都不能破坏它上一次调用时所生成的参数和中间结果,并且该过程不会修改它本身。
这就意味着当使用汇编语言设计递归子程序时,必须考虑每一次调用都应该把它的参数、寄存器和所有的中间结果保存到不同的存储区域。
最好的办法是利用堆栈来存储这些信息,一次调用所保存的信息称为一帧。
递归调用要使用大量的堆栈空间,一定要保证堆栈足够大,而且也要保证堆栈的正确使用,避免死机等不可预料的情况发生。
求N!算法流程图:三、所用仪器、材料(设备名称、型号、规格等) 1. 操作系统平台:Windows Server 2003 2. 汇编环境:Microsoft MASM 5.0 3. 文本编辑器:记事本 四、实验方法、步骤1. 将MASM5.0的文件置于C:\assembly\目录下;2. 将masm.exe和link.exe所在目录(C:\assembly\MASM5)添加到Path环境变量中;3.在C:\assembly\下新建一个JC.asm文件,打开JC.asm,输入汇编程序代码;4. 运行一个命令行窗口,将当前目录切换到C:\assembly\,然后输入命令:masm JC.asm [Enter],来汇编程序,根据汇编结果查看程序代码是否有语法错误,如有,则更正保存后重新汇编,直至没有错误为止,此时会生成JC.obj文件;5. 输入命令:link JC.obj [Enter],观察输出结果,如果没有错误,则生成JC.exe;6. 输入命令:debug JC.exe [Enter],调试程序,并记录运行过程;7. 完成实验报告。
c语言中求阶乘 -回复
c语言中求阶乘-回复C语言是一种广泛使用的计算机编程语言,它提供了丰富的功能和灵活的语法。
在C语言中,我们可以使用递归或循环等方法来求阶乘。
阶乘是指从1开始连乘到给定的数,例如5的阶乘表示为5!,计算公式为5! = 5 * 4 * 3 * 2 * 1 = 120。
在本文中,我们将一步一步地回答关于如何使用C 语言来求阶乘的问题。
首先,我们需要明确问题的要求。
要求是输入一个正整数n,然后计算并输出n的阶乘。
在C语言中,我们可以使用long long类型来存储较大的阶乘结果。
接下来,我们可以使用循环或递归的方式来求解阶乘。
首先,我们将使用循环方法来求解阶乘。
使用循环方式求解阶乘是一种简单直接的方法。
我们可以从1开始循环乘以每个数字,直到达到给定的数字n。
下面是使用循环求阶乘的C代码示例:c#include <stdio.h>long long factorial(int n) {long long fact = 1;for(int i = 1; i <= n; i++) {fact *= i;}return fact;}int main() {int n;printf("请输入一个正整数: ");scanf("d", &n);printf("d的阶乘为lld\n", n, factorial(n));return 0;}在上面的代码中,我们定义了一个名为factorial的函数,它接受一个整数参数n并返回一个long long类型的阶乘结果。
在循环中,我们从1开始循环,将每个数字乘以变量fact,并将结果赋给fact。
最后,我们在主函数中获取用户输入的正整数n,并调用factorial函数来计算阶乘并输出结果。
现在让我们来理解上面的代码。
当用户输入一个正整数n时,主函数将该值传递给factorial函数。
在factorial函数中,我们使用循环从1开始遍历到n,每次乘以当前的数字并将结果乘以之前的结果(fact *= i)。
求n阶乘的算法
求n阶乘的算法阶乘,也叫阶乘运算,是数学中的一种常见运算,它表示从1到n 的连续自然数相乘的结果。
在数学中,阶乘通常用符号"!"表示,如n!表示n的阶乘。
在计算机科学中,求阶乘是一个常见的算法问题,本文将介绍求n阶乘的算法。
一、迭代法求解阶乘迭代法是一种常用的求解阶乘的方法。
其基本思想是利用循环结构,从1开始逐个乘以连续的自然数,直到乘到n为止。
具体算法如下:1. 初始化一个变量result为1,用于保存阶乘的结果。
2. 从1开始循环,每次循环将result乘以循环变量i的值。
3. 循环结束后,result即为n的阶乘的结果。
以下是用迭代法求解n阶乘的Python代码示例:```def factorial(n):result = 1for i in range(1, n+1):result *= ireturn result```二、递归法求解阶乘递归法是另一种常用的求解阶乘的方法。
其基本思想是将问题拆分为更小的子问题,并通过递归调用来解决。
具体算法如下:1. 如果n等于0或1,直接返回1,因为0的阶乘和1的阶乘都等于1。
2. 如果n大于1,递归调用函数本身来求解n-1的阶乘,并将结果乘以n。
以下是用递归法求解n阶乘的Python代码示例:```def factorial(n):if n == 0 or n == 1:return 1else:return n * factorial(n-1)```三、动态规划法求解阶乘动态规划法是一种通过将问题分解为子问题并存储子问题的解来解决复杂问题的方法。
对于求解阶乘,可以使用动态规划法来减少重复计算。
具体算法如下:1. 创建一个数组dp,用于存储阶乘的中间结果。
2. 初始化dp[0]为1,表示0的阶乘的结果为1。
3. 从1开始循环,每次循环将dp[i]的值设置为dp[i-1]乘以i。
4. 循环结束后,dp[n]即为n的阶乘的结果。
以下是用动态规划法求解n阶乘的Python代码示例:```def factorial(n):dp = [1] * (n+1)for i in range(1, n+1):dp[i] = dp[i-1] * ireturn dp[n]```四、时间复杂度分析对于迭代法和递归法,其时间复杂度均为O(n),因为需要循环n次来计算阶乘。
采用汇编语言实现阶乘运算
汇编语言程序设计报告课程设计题目:采用汇编语言实现阶乘运算学号:********姓名:张子琦院系:测试与光电工程学院专业:测控技术与仪器指导教师:***采用汇编语言实现阶乘运算学生姓名:张子琦班级:10081437指导老师:陈振华摘要:汇编语言是微型计算机原理及应用的基础,微机主机和接口所要实现的功能都要通过汇编语言来实现。
尽管汇编语言程序设计编程效率低,但其运行效率高、速度快。
因此掌握汇编语言是学好微机原理和接口设计的第一步。
编写计算N!的程序。
数值由键盘输入,结果在屏幕上输出。
[1]关键字:汇编语言 N!键盘输入屏幕输出指导老师签名:Factorial implemented in assembly language Student name :Ziqi Zhang Class:10081437Supervisor:Zhenhua ChenAbstract:Assembly language is the basis of the principles and applications of the microcomputer, the microcomputer host functions and interfaces to achieve should be achieved through the assembly language. Despite the low efficiency of assembly language programming programming, but it’s high operating effi ciency, and speed. Therefore, the assembly language is the first step to learn Microcomputer Principle and Interface Design. Written calculation of N! Procedures. Numerical keyboard input, output results on the screen.Key words:Assembly language N! Keyboard input Screen outputSignature of Supervisor:目录1 背景[2] (1)1.1汇编语言 (1)1.2设计概述 (2)2 功能描述 (2)3 详细设计 (2)3.1原理及设计思路 (2)3.2流程图 (3)3.3源程序代码[1][2] (4)4 运行过程 (8)4.1编译源程序 (8)4.2汇编 (8)4.3连接并生成可执行文件 (9)4.4运行程序 (9)5 心得体会 (10)6 参考文献 (10)7 致谢 (11)1 背景[2]1.1汇编语言汇编语言是直接面向处理器(Processor)的程序设计语言。
用递归实现整数阶乘算法步骤
用递归实现整数阶乘算法步骤整数阶乘算法是计算一个正整数的阶乘的算法,阶乘是指从1到该正整数之间所有整数的乘积。
例如,5的阶乘为5×4×3×2×1=120。
本文将介绍如何使用递归实现整数阶乘算法。
递归是一种算法,它通过将问题分解为更小的子问题来解决问题。
在递归算法中,函数会调用自身来解决问题。
在整数阶乘算法中,我们可以使用递归来计算一个正整数的阶乘。
步骤1:定义函数我们需要定义一个函数来计算阶乘。
我们可以将函数命名为factorial,并将一个整数作为参数传递给它。
函数的返回值应该是该整数的阶乘。
步骤2:判断边界条件在递归算法中,我们需要定义一个边界条件来停止递归。
在整数阶乘算法中,边界条件是当传递给函数的整数为1时,返回1。
因为1的阶乘为1。
步骤3:递归调用在函数中,我们需要递归调用自身来计算传递给函数的整数的阶乘。
我们可以将传递给函数的整数减1,并将其作为参数传递给递归调用的函数。
然后将递归调用的结果乘以传递给函数的整数,最后返回结果。
步骤4:完整代码下面是使用递归实现整数阶乘算法的完整代码:```def factorial(n):if n == 1:return 1else:return n * factorial(n-1)```步骤5:测试代码为了测试代码,我们可以调用函数并传递一个整数作为参数。
例如,我们可以计算5的阶乘:```print(factorial(5))```输出结果应该为120。
总结使用递归实现整数阶乘算法可以使代码更简洁和易于理解。
但是,递归算法可能会导致栈溢出,因此在实现递归算法时需要小心。
在本文中,我们介绍了使用递归实现整数阶乘算法的步骤,并提供了完整的代码和测试代码。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、设计题目编写计算N!的程序(数值N由键盘输入,结果在屏幕上输出。
N的范围为0-65535,即刚好能被一个16位寄存器容纳)。
二、开发目的由于当N值较大时(N>10),N的阶乘计算很繁琐并且计算容易出错。
所以可以编写计算N!的程序,利用计算机强大的计算能力计算N!。
这不仅能节省繁琐计算的时间,而且得到的N!的积比起手工算的要准确。
三、设计方案N的阶乘为1*2*3……(N-1)*N,N的范围为(0000H—FFFFH),N!以字为单位存在一个或几个定义的数据段中。
若已算到(n-1)!,假如它占4个字的空间,接下来它乘以n的原理,如图1所示。
图1 (n-1)!* n的原理因此计算N!的算法可以这样编写,当前n!的值为被乘数,内容存在str2中,单位为字,n+1的值为乘数,存在str1中,单位也为字。
被乘数从str2首地址中内容开始与乘数相乘,得到32位的积,它的低16位覆盖掉当前被乘数所在存储空间的内容。
接着str2下一个字的内容与乘数相乘,也得到32位的积,前一个积的高16位与现在积的低16位相加,它们的和覆盖掉当前被乘数所在存储空间的内容,若它们的和有进位,把进位加到现在积的高16位。
直到把str2中内容乘完。
然后乘数增1,循环上面的内容。
直到执行完(N-1)!*N输入的N为4位16进制数,输出也为16进制数。
四、程序流程图开始输入N值五、程序清单data1 segmentinput1 db 'please input the number :','$'input2 db 10,?,10 dup(?) ;输入的16进制数error db 'Out of range','$'output1 db 'The answer is 1','$'output2 db 'The answer is :','$'str1 dw 100 dup(?) ;保存1—N(后一个数覆盖前一个数)str2 dw 7000h dup(?) ;N!乘积的值(1)p dw 100 dup(?) ;上一个乘积的高16位data1 endsdata2 segmentstr3 dw 7fffh dup(?) ;N!乘积的值(2)data2 endscode segmentassume cs:code,ds:data1,es:data2org 100h ;程序从偏移地址100h开始执行start: mov ax,data1 ;程序初始化mov ds,axmov ax,data2mov es,ax ;初始化结束mov ah,9lea dx,input1int 21hmov ah,2 ;回车mov dl,0dhint 21hmov ah,2 ;换行mov dl,0ahint 21hmov ah,0ah ;输入所需求的N值(N为16进制数)lea dx,input2int 21hmov ah,2mov dl,0dhint 21hmov ah,2mov dl,0ahint 21hlea bx,input2mov al,[bx+1] ;判断输入的N值是否超过FFFFHcmp al,4ja s1mov cl,4 ;把输入的N值有ASCH码转成16进制数mov ah,[bx+2]mov al,[bx+3]cmp al,39hja abc1def1: shl al,clcmp ah,39hja abc2def2: shr ax,clmov dh,almov ah,[bx+4]mov al,[bx+5]cmp al,39hja abc3mov cl,4def3: shl al,clcmp ah,39hja abc4def4: shr ax,clmov dl,al ;转换结束mov ax,dx ;判断N值是否为0cmp ax,0jz s2jmp s3abc1: sub al,37hjmp def1abc2: sub ah,37hjmp def2abc3: sub al,37hjmp def3abc4: sub ah,37hjmp def4s1: mov ah,9 ;若N值超过FFFFH的输出lea dx,errorint 21hjmp nexts2: mov ah,9 ;N值为1的输出lea dx,output1int 21hjmp nexts3: mov cx,ax ;计算N的阶乘mov ax,1mov [str1],ax ;N从1开始,作为乘数lea si,str2mov [si],ax ;N!的积从1开始,作为被乘数mov ax,0mov [p],ax ;(n-1)!的乘积的低16位与n相乘后积的高16位mov bx,1 ;开始N!的乘积占一个字空间mov WORD ptr[p+10],0 ;(n-1)!的乘积的高16位与n相乘后积的低16位和(n-1)!的乘积的低16位与n相乘后积的高16位的和的进位,初始进位为0 mov ah,9lea dx,output2int 21hmov ah,2mov dl,0dhint 21hmov ah,2mov dl,0ahint 21hlop2: mov [p+2],bxlop3: mov ax,[si] ;(n-1)!的乘积从最低16位的内容与n相乘mov dx,[str1]mul dxclcadd ax,[p+10] ;前一次的进位与当前乘积的低16位内容相加jnc k1 ;判断是否产生进位mov WORD ptr[p+10],1add ax,[p] ;前一个积的高16位与现在积的低16位相加jmp k2k1: add ax,[p]jnc k3 ;判断是否产生进位mov WORD ptr[p+10],1jmp k2k3: mov WORD ptr[p+10],0k2: mov [si],axmov [p],dxadd si,2dec bxcmp bx,0jnz lop3mov bx,[p+2]clcadd dx,[p+10]cmp dx,0jz re ;判断(n-1)!乘积的最高16位内容与n的乘积的高16位是否为0inc bxmov [si],dxre: mov ax,[str1]cmp ax,9000h ;判断是N!乘积的内容高位部分是否要存到es中jnc re1jmp re2re1: cmp cx,1ja s4re2: inc WORD ptr[str1] ;乘数增1lea si,str2mov WORD ptr[p],0mov WORD ptr[p+10],0loop lop2dec bxmov cx,bxlop4: add si,2loop lop4inc bxadd bx,bxinc sijmp lop5s4: inc WORD ptr[str1] ;若N的值超过8000h,8000h*8001h*8002h*N mov [p+6],bxmov [p+8],bxlea si,str2lea di,str3mov es:[di],dxmov WORD ptr[p],0mov WORD ptr[p+10],0mov bx,1dec cxlop6: mov [p+4],bxlop7: mov ax,[si]mov dx,[str1]mul dxclcadd ax,[p+10]jnc k4mov WORD ptr[p+10],1add ax,[p]jmp k5k4: add ax,[p] ;前一个积的高16位与现在积的低16位相加,产生进位jnc k6mov WORD ptr[p+10],1jmp k5k6: mov WORD ptr[p+10],0k5: mov [si],axadd si,2mov [p],dxdec WORD ptr[p+6]mov ax,[p+6]cmp ax,0jnz lop7mov ax,[p+8]mov [p+6],axlop8: mov ax,es:[di]mov dx,[str1]mul dxclcadd ax,[p+10]jnc k7mov WORD ptr[p+10],1add ax,[p]jmp k8k7: add ax,[p] ;前一个积的高16位与现在积的低16位相加,产生进位jnc k9mov WORD ptr[p+10],1jmp k8k9: mov WORD ptr[p+10],0k8: mov es:[di],axadd di,2mov [p],dxdec bxcmp bx,0jnz lop8mov bx,[p+4]clcadd dx,[p+10]cmp dx,0jz re4inc bxmov es:[di],dxre4: inc WORD ptr[str1]lea si,str2lea di,str3mov WORD ptr[p],0mov WORD ptr[p+10],0dec cxcmp cx,0jnz lop6dec bxmov cx,bxlop9: add di,2loop lop9inc bxadd bx,bxinc dilop10: dec bx ;若N>8000h,输出N!乘积的高位内容mov al,BYTE ptr es:[di]mov ch,almov cl,4shr al,clcmp al,09hja op3add al,30hjmp ip3op3: add al,37hip3: mov ah,2mov dl,alint 21hmov al,chand al,0fhcmp al,09hja op4add al,30hjmp ip4op4: add al,37hip4: mov ah,2mov dl,alint 21hdec dicmp bx,0jnz lop10mov bx,[p+6]dec bxmov cx,bxlop11: add si,2loop lop11inc bxadd bx,bxinc silop5: dec bx ;输出N!的乘积mov al,BYTE ptr [si]mov ch,almov cl,4shr al,clcmp al,09hja op1add al,30hjmp ip1op1: add al,37hip1: mov ah,2mov dl,alint 21hmov al,chand al,0fhcmp al,09hja op2add al,30hjmp ip2op2: add al,37hip2: mov ah,2mov dl,alint 21hdec sicmp bx,0jnz lop5next: mov ah,1int 21hmov ah,4chint 21hcode endsend start六、程序运行结果与分析若输入的16进制数N为000A(10进制为10),程序运行后输出的N!应为375F00(H)。