在华为的机试的时候,碰到了大数的问题,所有的大数问题,无非就是相加相减相乘相除这四种,里面的区别就是大数的表示方式,一般我们采用字符数组的方式去保存大数,也有采用链表的。这两种方式中,字符数组的方式比较好理解一些,本文通过代码,来说明大数运算的集中情况,力争将这个问题讲清楚。
大数相乘
题目描述:输入两个不超过100位的大整数的乘积。
输入:1234567 123
输出:151851741
方法一
下面说明一下代码的思路,当两数相乘的时候,一般我们都是从被乘数的个位开始的,于是就有了以下代码,首先是按照顺序用被乘数的个位乘以乘数,这个过程中,遇到进位的时候需要保存下来,也就是carry;而得到的结果我们会存放在我们的tempRes中。
for(i = num1Len - 1; i >= 0;i--)
{
res = Int(num1[i])*Int(num2[j]) + carry;
tempRes[tempResLen--] = Char(res % 10);
carry = res / 10;
}
由于上面最后一次循环没有加上进位,所以在后面还是需要加上进位位的,并且需要将tempResLen这个值和carry初始化。
tempRes[tempResLen] = Char(carry);
tempResLen = num1Len;
carry = 0;
然后我们需要将最终结果保存在result中,并且由于每次被乘数没有移位,所以我们在保存结果的时候,每次循环需要移位,所以每次offset都会加上1。其实这个处理方式和上面的一样,只是这个是保存在最终结果中。
for(k = resultLen - offset; k > (resultLen - offset - num1Len); k--)
{
res = Int(result[k]) + Int(tempRes[tempResLen--]) + carry;
result[k] = Char(res % 10);
carry = res / 10;
}
result[k] += Int(tempRes[tempResLen] + carry);
carry = 0;
tempResLen = num1Len;
offset++;
完整代码如下。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define Int(X) (X - '0') //将字符转化为整型
#define Char(X) (X + '0') //将整型转化位字符
char *multiBigInteger(const char *,const char *);
int checkNum(const char *);
int main(void)
{
char num1[100] = {'\0'},num2[100] = {'\0'};
while(scanf("%s %s",num1,num2) != EOF)
{
char *result = "0";
if(strlen(num1) > 100 || strlen(num2) > 100)
{
printf("ERROR!\n");
return 1;
}
if(checkNum(num1) || checkNum(num2))
{
printf("ERROR:input mus