早就想写大数问题,一直拖到现在才把大数相乘给写了。我的思路:大数相乘建立在大数相加的基础上,类似二进制乘法,二进制直接移位相加,十进制先加后移位,再求和。
程序写地冗长,有时间再精减吧。
下一个写大数阶乘。
#include <stdio.h>
#include <string.h>
#define N 100
/***********************
* 函 数 名:length()
* 函数功能:计算字符串长度
************************/
int length(char * p)
{
int len = 0;
while( *(p + len) != '\0')
{
len++;
}
return len;
}
/****************************
* 函 数 名:trans()
* 函数功能:给字符串逆序
****************************/
void trans(char p[])
{
int i,n;
char tmp;
n = length(p);
for(i = 0; i < n/2; i++)
{
tmp = p[i];
p[i] = p[n - 1 - i];
p[n - 1 - i] = tmp;
}
}
/****************************
* 函 数 名:Myadd_big()
* 函数功能:大数求和
****************************/
void Myadd_big(char str1[] ,char str2[] ,char str[])
{
int i = 0, flag = 0; // 下标变量 和 进位标志位
int count1 , count2 ; // 两个数的长度
char tmp;
count1 = length(str1);
count2 = length(str2);
while( str1[i] != '\0' && str2[i] != '\0') //一位一位相加 直到其中一个数结束
{
tmp = str1[i] + str2[i] -'0' + flag;
// 如果字符tmp 大于 字符9 即相加产生了进位 则减去10 让它变为数字字符
if( tmp > '9')
{
str[i] = tmp - 10; // 保存
flag = 1; //进位记为1
}
else
{
str[i] = tmp; //没有进位 直接保存
flag = 0; //将进位记为0 (不可省)
}
i++; //改变下标 将取两个数字串的下一位数 相加
}
//上面while循环结束后 至少有一个数字串被加完 下面 判断哪个被加完
if(count1 == count2) //两个数长度相同 判断最高位是否有进位
{
if(flag == 0)
{
str[i] = '\0'; //添加字符串标志
}
else
{
str[i] = flag + '0'; //将进位位变为字符串 并保存为最高位
i = i + 1;
str[i] = '\0';
}
}
else if( count1 > count2 ) //两数一长一短 则将剩下的数与进位位相加
{
while( str1[i] != '\0')
{
tmp = str1[i] + flag;
if( tmp > '9')
{
str[i] = tmp - 10;
flag = 1;
}
else
{
str[i] = tmp;
flag = 0;
}
i++;
}
if(flag == 0)
{
str[i] = '\0';
}
else
{
str[i] = flag + '0';
i = i + 1;
str[i] = '\0';
}
}
else
{
while( str2[i] != '\0')
{
tmp = str2[i] + flag;
if( tmp > '9')
{
str[i] = tmp - 10;
flag = 1;
}
else
{
str[i] = tmp;
flag = 0;
}
i++;
}
if(flag == 0)
{
str[i] = '\0';
}
else
{
str[i] = flag + '0';
i = i + 1;
str[i] = '\0';
}
}
}
void mymul_big(char str1[],char str2[],char res[])
{
char tmp[N][2*N];
char p;
int i,j;
res[0] = '\0';
for(i = 0; i < N; i++)
{
tmp[i][0] = '\0';
}
i = 0;
while(str2[i] != '\0')
{
j = i;
for( p = '0' ; p < str2[i]; p++)
{
Myadd_big(str1,tmp[i],tmp[i]);
}
for(j = 0; j < i; j++)
{
res[j] = '0';
}
res[j] = '\0';
strcat(res,tmp[i]);
strcpy(tmp[i],res);
res[0] = '\0';
i++;
}
for(j = 0 ; j < i; j++)
{
Myadd_big(res,tmp[j],res);
}
trans(res); // 逆序 将高位存在数组前面 待输出
}
int main()
{
char str1[N],str2[N]; //串1、2 存放输入的数字 串str存放结果
char res[2*N];
printf("input a number:");
gets(str1);
printf("input a number:");
gets(str2);
trans(str1); //将输入的数字串逆序 把低位存放在数组前面
trans(str2);
mymul_big(str1,str2,res);
printf("result:");
printf("%s\n",res);
return 0;
}
检验的时候还发现大数求和中一个错误,都是懒惹的祸!
深入了解
https://blog.youkuaiyun.com/kiwi_berrys/article/details/52444024