大整数乘法

高精度计算需要注意的几个问题:

1.用字符串的读入方式,再按字符分别转成数字2.不能用数值型的读入方式二、计算过程中考虑进位和借位问题(先不急于处理,在计算结束时处理)1.数组第i元素>=10(或<0)需要考虑2.从上位增或减1,本位减或加10三、输出时注意跳过高位多余的0四、数组需要稍微大一些,避免运算时溢出问题描述
求两个不超过200位的非负整数的积。
输入数据有两行,每行是一个不超过200位的非负整数,没有多余的前导0。
输出要求
一行,即相乘后的结果。结果里不能有多余的前导0,即如果结果是342,那么就不能输出为0342。
输入样例
12345678900
98765432100
输出样例
1219326311126352690000
解题思路
1.用unsigned an1[200]和unsigned an2[200]分别存放两个乘数,用aResult[400]来存放积。计算的中间结果也都存在aResult中。aResult长度取400是因为两个200位的数相乘,积最多会有400位。an1[0], an2[0], aResult[0]都表示个位。
2.一个数的第i位和另一个数的第j位相乘所得的数,一定是要累加到结果的第i+j位上。这里i, j都是从右往左, 从0开始数。
3.计算的过程基本上和小学生列竖式做乘法相同。为编程 方便,并不急于处理进位,而将进位问题留待最后统一处理。

#include <iostream>
#include <cstring>
using namespace std;
#define MAX 200
int Multiply(int *a1, int *a2, int *result, int nLen1, int nLen2)
{
    //大整数乘法
    int i, j;
    int nHighestPos = 0;
    for(j = 0; j <= nLen2 - 1; ++j)
    {
        for(i = 0; i <= nLen1 - 1; ++i)
        {
            result[i + j] += a1[i] * a2[j];//注意是+=才可以把进位相加
        }

    }
    for(int k = 0; k <= nLen1 + nLen2; ++k)
    {
        if(result[k] >= 10)
        {
            result[k + 1] += result[k] / 10;
            result[k] %= 10;
        }
        if(result[k])
        {
            nHighestPos = k;
        }
    }
    return nHighestPos;
}
int main()
{
    while(1)
    {
        char *s1 = new char[MAX + 10]();
        char *s2 = new char[MAX + 10]();
        int *a1 = new int[MAX + 10]();
        int *a2 = new int[MAX + 10]();
        int *result = new int[MAX + MAX + 10]();
        cin >> s1;
        cin >> s2;

        int nLen1 = strlen(s1);
        for(int i = nLen1 - 1, j = 0; 0 <= i; --i)
        {
            a1[j++] = s1[i] - '0';
        }
        int nLen2 = strlen(s2);
        for(int i = nLen2 - 1, j = 0; 0 <= i; --i)
        {
            a2[j++] = s2[i] - '0';
        }
        int Flag = Multiply(a1, a2, result, nLen1, nLen2);
        //进位处理

        bool bStartOutput = false;//此变量用于跳过多余的0
        for(int k = Flag; 0 <= k; --k)
        {
            if(bStartOutput)//遇到多余的0都跳过,否则输出
            {
                cout << result[k];
            }else if(result[k])
            {
                bStartOutput = true;//碰到第一个非零值,则表明多余的0已都跳过
                cout << result[k];
            }
        }
        if(!bStartOutput)
        {
            cout << 0;
        }
        cout << endl;
        delete [] s1;
        delete [] s2;
        delete [] a1;
        delete [] a2;
        delete [] result;
    }
    return 0;
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值