两个大数相乘

计算机一般能处理的数据有限,如int为32位二进制数,double为64位二进制数,当有两个个200位的数字,怎么计算其结果呢,

这个可以用数组来计算,模仿小学时计算数学乘法一样,数组将两个数字的每一位都存为数字,然后逐位相乘,相加来得出结果。

如:

           1 2 3

        x

           1 2 3

————————

              3 6 9

           2 4 6

        1 2 3

————————

        1 5 1 2 9

说明一下:这个乘法每次运算都是把结果存起来,并且有规律的,第0位与第0位乘得第(0+0)位,第1位与第0为乘得第(1+0)位,

依次类推

当然计算机计算也可以这样,但数字的位置应该调换一下,低位在前高位在后,这样算出来的结果在逆序输出即可,原因是:这样

索引的计算比较方便

代码如下:

#include "stdio.h"
#include "iostream"
#include "cstring"
#define N 200
#define N2 2*N
using namespace std;

int main(){
	//存储两个数字字符串
	char strn1[N], strn2[N];
	// 将两个字符串转换为数字存储
	int num1[N],num2[N];
	//存储结果
	int result[N2];

	cin>>strn1>>strn2;

	int i,j =0;
	int len1 = strlen(strn1);
	int len2 = strlen(strn2);
	memset(num1,0,sizeof(num1));
	memset(num2,0,sizeof(num2));

	//将字符串转换为数字,并逆序
	for(i = len1 - 1;i>=0;i--){
		num1[j++] = strn1[i] - '0';
	}

	j = 0;

	for(i = len2 - 1;i>=0;i--){
		num2[j++] = strn2[i] - '0';
	}

	memset(result,0,sizeof(result));
	//用第一个数字的每一位乘以数字2的每一位,乘得的结果存入相应的位置
	//这个位置的由来:
	//两个数字都逆序了,那么最小位都在0坐标,而结果,数字1第0与数字2第0为的乘积
	//存储在结果的第零位,相应的可以数字第1为和数字2的第三为乘积应存储到结果的第
	//1+2位,依次类推
	for(i = 0;i<len1;i++){
		for(j = 0;j < len2;j++){
			result[j + i] += num1[i] * num2[j]; 
		}
	}

	//处理结果,将结果中大于9的进位,并存储为单一数字
	for(i = 0;i<400;i++){
	
		result[i + 1]  += result[i] / 10;//向高位进位result[i] / 10
		result[i] = result[i] % 10;      //进位后,原本位应为余数
	}
	//通过逆序输出,得出结果
	//注意这里从后面输出,可能是为0,所以设置一个标记,当第一次
	//遇见不是0时,其余的所有的数字包括0都是有效的
	int flag = 0;
	for(i = 400 - 1;i>=0;i--){
		if(flag){
			printf("%d", result[i]);

		} else if(result[i]){
			flag = 1;
			printf("%d", result[i]);
		}
	}
	printf("\n");
	return 0;
}

当然,用整数存储可能会因为整数数组不能太大,可以直接用字符串,也同样的操作,这就可以算无数多位之间的乘积了:

实现如下:

/*
	Filename:twoBigMultiByStirng.cpp
	Author: xiaobing
	E-mail: xiaobingzhang29@gmail.com
	Date: 2013-08-23
*/
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
using namespace std;
string trim(string str){
	string buff(str);
	char space = ' ';
	str.assign(buff.begin() + buff.find_first_not_of(space), 
			buff.begin() + buff.find_last_not_of(space) + 1)
	return str;
}
int main(){

	//输入两个随意长的字符串
	string str1,str2;
	cin>>str1>>str2;

	//去掉首位空格
	str1 = trim(str1);
	str2 = trim(str2);
	//获取每个字符串的长度
	int len1 = str1.length();
	int len2 = str2.length();
	int total = len1 + len2;

	//将字符串逆序
	string num1(str1.rbegin(), str1.rend());
	string num2(str2.rbegin(), str2.rend());

	cout<<"Reversed string one: "<<num1<<endl;
	cout<<"Reversed string two: "<<num2<<endl;

	//动态分配结果的空间字符串,一个n位数乘以m位数最多为n+m位数
	char *result;
	result = (char*)malloc(len1 + len2);

	//初始化结果全为'0'
	int i,j;
	for(i = 0;i < len1 + len2;i++){
		result[i] = '0';
	}

	//将第一个数字的每一位乘以第二个数字的每一位
	for(i = 0;i < len1;i++){
	
		for(j = 0;j < len2;j++){
			//结果存储位置
			int pos = i + j;	
			//第一个个数的第i位和第二个数的第j位乘积再加上pos位置的真值
			int tmp = (num1[i] - '0') * (num2[j] - '0') + (result[i + j] - '0'); 
			//结果为真值对10求余数
			result[i + j] = tmp % 10 + '0';
			//产生的进位
			int carry = tmp / 10;

			//当进位大于0,则更新下一位,一直更新,直到进位为0
			while(carry > 0){
				//下一个位置的数真值加上进位得到tmp
				tmp = result[pos + 1] - '0' + carry;
				//下一个位置等于tmp对10求余数
				result[pos + 1] = tmp % 10 + '0';
				//计算进位
				carry = tmp / 10;
				//移动位置
				pos++;
			}		

		}
	}

	cout<<"乘积为:"<<endl;
	//输出结果,由于是逆序存储,所以从后面往前面输出
	//输出时,当遇见大于0的数开始输出,以后的数不管
	//是0或非0都有效
	int flag = 0;
	for(i = len1 + len2 - 1;i >= 0;i--){
		if(flag == 1){
			cout<<result[i];
		} else if (result[i] != '0'){
			flag = 1;
			cout<<result[i];
		}
	}
	cout<<endl;

	free(result);
    return 0;
}

    原文作者:大整数乘法问题
    原文地址: https://blog.csdn.net/xiaobing_blog/article/details/10242239
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞