大数乘法C实现

<pre name="code" class="plain">
#include<stdio.h>
#include<string.h>
#include<malloc.h>
const int maxNumber=1004;
//实现2个大数相乘
//by WeiBiao 2014/9/27 12::40
void mul(char* s1, char* s2);//遍历s2去乘每个s1整体,然后移位累加
void subMul(int posVal, int index1, char* s1, int* temp);//取出第二个数的个位、十位、百位etc依次乘第一个数个位,结果存入temp数组中。。。
void updateS1(int index1, int index2, int* t1, int* t2);//更新累加结果,一共需要更新strlen(s2)次
void outPut(int* s);//输出某个数组代表的数(大数)

int main(){
	char s1[maxNumber], s2[maxNumber];
	while(~scanf("%s%s", s1, s2)){
		mul(s1, s2);
	}
	return 0;
}

void outPut(int* s){
	int i;
	for( i = maxNumber-1; i>=0; i--) if(s[i]) break;
	for( int j = i; j >=0; j--)
		printf("%d", s[j]);
	puts("");
}

void updateS1(int index1, int index2,//index1,到index2开始加
				int* t1, int* t2){//与s1对齐,相加
	int incre=0;
	for(int i = index1; i<= index2; i++){
		if((incre+t1[i]+t2[i]) >= 10){ 
			int tp;
			tp=(incre+t1[i]+t2[i])/10;
			t1[i] = (incre+t1[i]+t2[i])%10;
			incre = tp;
		}
		else{
			t1[i] = (t1[i]+t2[i]+incre);
			incre = 0;
		}
	}

	//outPut(t1);
}

void subMul(int posVal, int index1, char* s1, int* temp){//得到temp
	int j, incre;
	for(j = 0, incre=0; j < strlen(s1); ++j){//遍历s1
		if( (incre+ posVal*(s1[j]-'0')) >= 10){
			temp[index1+j] = (incre+ posVal*(s1[j]-'0'))%10;
			incre = (incre+ posVal*(s1[j]-'0'))/10;
		}else{
			temp[index1+j] = posVal*(s1[j]-'0');
			incre = 0;
		}
	}
	temp[index1 + j] = incre;
	//outPut(temp);
}

void mul(char* s1, char* s2){
	s1 = strrev(s1); s2 = strrev(s2);
	int a[maxNumber]={0}, a1 = strlen(s1), a2 = strlen(s2);

	int temp[1010];//申请temp数组存放每一步结果

	for(int i = 0; i < a2; ++i){//执行a2次结束
		memset(temp, NULL, sizeof(temp));
		int posVal = s2[i]-'0'; 

		subMul( posVal, i, s1, temp);//局部乘法,更新temp数组;
		updateS1( i, a1+i+1, a, temp);//更新累加结果
	}
	outPut(a);
}



                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是基于RISC-V指令集的大数乘法计算的汇编语言代码实现: ```assembly # 大数乘法计算 # 输入:x为n位十进制正整数,y为m位十进制正整数 # 输出:z为n+m位十进制正整数,z=x*y # 数据段定义 .data x: .word 0x12345678, 0x9abcdef0, 0x13579bdf # 输入的x y: .word 0x2468ace0, 0xfdb97531 # 输入的y z: .word 0, 0, 0, 0, 0, 0, 0, 0 # 输出的z,初始化为0 # 代码段定义 .text .globl main main: # 初始化寄存器 li t0, 8 # t0为x的字长,即4字节 li t1, 4 # t1为y的字长,即2字节 li t2, 8 # t2为z的字长,即8字节 li t3, 0 # t3为循环计数器,初始化为0 li t4, 0 # t4为进位标志,初始化为0 loop: bge t3, t1, end # 循环结束条件:t3 >= t1 li t5, 0 # t5为当前位的乘积,初始化为0 li t6, 0 # t6为当前位的进位,初始化为0 # 计算当前位的乘积 li t7, 0 # t7为循环计数器,初始化为0 mul_loop: bge t7, t0, add_carry # 乘积计算结束条件:t7 >= t0 lw a0, x(t7) # a0为x的第t7个字 lw a1, y(t3) # a1为y的第t3个字 mulu t8, a0, a1 # t8为a0和a1的乘积 add t9, t5, t8 # t9为当前位的乘积和t8的和 bge t9, t5, no_carry # 进位判断:t9 >= t5 addi t6, t6, 1 # 进位标志加1 no_carry: add t5, t5, t8 # 当前位的乘积加上t8 addi t7, t7, 1 # 循环计数器加1 j mul_loop add_carry: # 计算当前位的进位 li t7, 0 # t7为循环计数器,初始化为0 lw a0, z(t3) # a0为z的第t3个字 add_loop: bge t7, t2, store # 进位计算结束条件:t7 >= t2 lw a1, x(t7) # a1为x的第t7个字 lw a2, y(t3) # a2为y的第t3个字 mulu t8, a1, a2 # t8为a1和a2的乘积 lw a3, z(t7+t3) # a3为z的第t3+t7个字 add t9, t8, a3 # t9为进位和t8的和 bge t9, t8, no_c # 进位判断:t9 >= t8 addi t4, t4, 1 # 进位标志加1 no_c: add t8, t8, a3 # 进位和t8的和 sw t8, z(t7+t3) # 存储当前位的结果 addi t7, t7, 1 # 循环计数器加1 j add_loop store: # 存储当前位的进位 lw a0, z(t3+t1) # a0为z的第t3+t1个字 add t8, t4, a0 # t8为当前位的进位和a0的和 sw t8, z(t3+t1) # 存储当前位的进位 addi t3, t3, 1 # 循环计数器加1 li t4, 0 # 进位标志清零 j loop end: # 输出结果 la a0, z # a0为z的地址 li a1, 8 # a1为输出的字长,即8字节 jal print_hex # 调用输出函数 li a0, 10 ecall # 换行 li a0, 0 ecall # 退出程序 # 输出函数,将a0中的十六进制数按顺序输出 print_hex: li t0, '0' # t0为字符'0'的ASCII码 li t1, 'A'-10 # t1为字符'A'的ASCII码减去10 print_loop: beqz a1, end_print # 输出结束条件:a1 == 0 srl t2, a0, 28 # t2为a0的高4位 andi t2, t2, 0xf # t2为a0的高4位的十六进制数 addi a0, a0, 4 # a0向右移动4位 addi a1, a1, -1 # a1减1 blt t2, 10, print_d # t2 < 10,输出数字字符 add t2, t2, t1 # t2 >= 10,输出大写字母字符 print_d: add t2, t2, t0 # t2为字符的ASCII码 li a0, 1 mv a1, t2 ecall j print_loop end_print: ret ``` 说明: 1. 输入的x和y分别存储在.data段的x和y中,输出的z存储在.data段的z中,初始化为0。 2. 寄存器$t0、$t1、$t2、$t3、$t4分别用于存储x的字长、y的字长、z的字长、循环计数器和进位标志。 3. 外层循环从低位到高位遍历y的每一位,内层循环从低位到高位遍历x的每一位,计算当前位的乘积,并判断是否需要进位。 4. 计算当前位的进位时,需要考虑前面位的进位,因此需要用到进位标志$t4。 5. 内层循环结束后,存储当前位的乘积,同时计算当前位的进位。 6. 循环结束后,输出结果,将z的每一字按十六进制数输出即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值