大数相乘,就是指数字比较大,相乘的结果超出了基本类型的表示范围,通常将其保存在一个字符串中来计算。
所以这样的数不能够直接做乘法运算。
在学习密码学的过程中,当从用户界面接受的数据字符串CString无法使用atoi或atol转化为对应的数字时,就需要使用大数乘法。
原理:
1,两个字符数组存储str1和str2的值。
2,由于两数相乘后结果位数最多为len1+len2.则可以设置一个数组result[len1+len2]来保存结果;
3,result[0]预留出来。相乘之后,暂时保存结果result的每一位的数字,不做进位处理。result每一位上的数字result[i+j+1] = str1[i]*str[j].
4,从后往前遍历,判断是否需要进位。
代码实现
#include <stdio.h>
#include <assert.h>
#include <string.h>
char* BigNumMul(const char* str_1, const char* str_2, char* result)
{
int len_1 = 0;
int len_2 = 0;
int len = 0;
int i = 0;
//断言传入的a,b,c不为空
assert(str_1);
assert(str_2);
assert(result);
len_1 = strlen(str_1);
len_2 = strlen(str_2);
len = len_1 + len_2;
for (i = 0; i < len_1; ++i)
{
int j = 0;
for (; j < len_2; ++j)
result[i+j+1] += (str_1[i]-'0')*(str_2[j]-'0'); //使用+=,整合c[i+j+1]上所有运算结果。
//将c[0]留出来,防止c[1]进位时没有地方存储
}
//从最后一位往前判断是否进位。
for (i = len-1; i >= 0; --i)
{
if (result[i] > 9)
{
result[i-1] += result[i]/10;//进位
result[i] %= 10;//保留本来该有的值
}
result[i] += '0';
}
if ('0' == result[0])//如果第一个字符为0,将所有字符往前移一位
memmove(result, result+1, len);
return result;
}
void test()
{
char str_1[1024] = {0};//存储number1
char str_2[1024] = {0};//存储number2
char result[1025] = {0};//存储result
printf("输入number1:");
scanf("%s", str_1);
printf("输入number2:");
scanf("%s", str_2);
//大数乘法
BigNumMul(str_1, str_2, result);
//输出结果
printf("result = %s\n", result);
}
int main()
{
do{
test();
getchar();
printf("输入ctrl+z结束输入,输入Enter键继续。。。\n");
}while (getchar() != EOF);
return 0;
}
附上其他大数运算:
大数减法:http://blog.csdn.net/qq_35524916/article/details/67745337
大数加法:http://blog.csdn.net/qq_35524916/article/details/67651027