受计算机变量大小限制。当乘数过大时,计算机无法进行乘法,必须自己想法予以实现。
本程序可处理带小数的大数乘法运算。
运算结果正确。可以将前几年破解的 RSA-158 密码来试验
// 前几年破解的 RSA-158 密码是这样因数分解的
// result :39505874583265144526419767800614481996020776460304936454139376051579355626529450683609727842468219535093544305870490251995655335710209799226484977949442955603
// part1:3388495837466721394368393204672181522815830368604993048084925840555281177
// part2:11658823406671259903148376558383270818131012258146392600439520994131344334162924536139
运算时,先将乘数都反转。即倒着乘,主要是防止进位时没有空间了。最后将结果也反转输出即可
以15*15为例
第一步,反转后变为 51*51
第二步,相乘(不进位) 25 10 1,
第三步,进位 25向10进2位后变为5,12向1进1位后变为2,最后结果为522
第四步,反转 522->225,即15*15的结果。
如果有小数,记录总的小数位数,将两个数变为正数后进行上面的步骤,最后加上小数位即可。
源代码如下:
//
// bignum.c
// 完成有小数位的俩个大数的乘法
// Created by GPH on 13-7-14.
// Copyright (c) 2013年 GPH. All rights
//
#include<stdio.h>
#define NUM_RESULT 200
#define NUM_PART 100
void convert(char *a,int *b);
void bigNumberMul(char *a,char*b,int count);
int split(char *a,char*b);
//先将字符串反转。
//再字符型数字转为数字,存在整形数组中,为乘法做准备
//若是高位放在数组头部,则进位时可能没有空间
//所以将低位放在数组头部。高位放尾部。
//输出时倒序即可
void convert(char *a,int *b)
{
int l = strlen(a);
char temp;
for (int i = 0; i < l/2; i++)
{
temp = a[i];
a[i] = a[l-i-1];
a[l-i-1] = temp;
}
for (int i = 0; i < l; i++)
{
b[i] = a[i]-'0';
}
}
//逐位相乘,再进位
void bigNumberMul(char *a,char*b,int count)
{
int ih[NUM_RESULT]={};
int ia[NUM_PART];
int ib[NUM_PART];
convert(a,ia);
convert(b,ib);
for (int i = 0; i < strlen(a); i++)
{
for ( int j = 0; j < strlen(b); j++)
{
ih[i+j] += ia[i]*ib[j];
}
}
//逐次进位
for (int i = 0; i < NUM_RESULT-1; i++)
{
ih[i+1] += ih[i]/10;
ih[i] %= 10 ;
}
int i;
for ( i = NUM_RESULT-1;i >= 0 ; i--)
{
if (ih[i])
{
break;
}
}
for ( ;i >= 0 ; i--)
{
if(i == count-1)
{
printf(".");
}
printf("%d",ih[i]);
}
}
//统计小数位共多少。并删除"."号
//用来最终输出时,确定小数位数
int split(char *a,char*b)
{
int sum = 0;
for (int i = 0;i< strlen(a) ; i++)
{
if(a[i] == '.')
{
//前移,删除'.'
for (int j = i; j < strlen(a)-1 ; j++)
{
a[j] = a[j+1];
}
sum += strlen(a)-i-1;
a[strlen(a)-1] = '\0';
break;
}
}
for (int i = 0;i< strlen(b) ; i++)
{
if(b[i] == '.')
{
//前移,删除'.'
for (int j = i; j < strlen(b)-1 ; j++)
{
b[j] = b[j+1];
}
sum += strlen(b)-i-1;
b[strlen(b)-1] = '\0';
break;
}
}
return sum;
}
int main(int argc, const char * argv[])
{
char a[NUM_PART];
char b[NUM_PART];
int count;
printf("input:");
scanf("%s",a);
printf("input:");
scanf("%s",b);
printf("\n");
getchar();
count = split(a,b);//统计小数位
bigNumberMul(a,b,count);
printf("\n");
return 0;
}