大整数的乘法、加法、减法

乘法用经典的算法来解决,还有分治法来解决大整数乘法,但是效率提升不明显而且代码稍烦。所谓的经典算法就是直接按照位相乘,然后换算进位的算法,也很简单。加法和乘法用到的进位算法一样,减法是用借位。注意结果的位数,乘法、加法、减法结果的位是不同的。下面是代码

#include <iostream>
using namespace std;

void multiply(short *a, short *b, short *result, int len_a, int len_b, int len_result);
void my_plus(short *a, short *b, short *result, int len_a, int len_b, int len_result);
int my_sub(short *a, short *b, short *result, int len_a, int len_b, int len_result);
void carry(short *result, int len_result);

int main()
{
        const int len_a = 31;
        const int len_b = 31;
        const int len_result = len_a + len_b; //一个m位整数乘以一个n位的整数,那么这个数不是m+n位就是m+n+1位的
        short a[len_a] = {2, 9, 2, 3, 4, 5, 6, 7, 8, 9, 1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 1, 8, 1, 9, 2};
        short b[len_b] = {2, 0, 1, 9, 1, 8, 1, 7, 1, 6, 1, 5, 1, 4, 1, 3, 1, 2, 1, 1, 1, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1};

        //乘法
        short result[len_result] = {0};
        multiply(a, b, result, len_a, len_b, len_result);
        carry(result, len_result);
        printf("Multiply result is: ");
        if(result[0] != 0)
                printf("%d", result[0]);
        for(int i=1; i<len_result; i++)
                printf("%d", result[i]);
        printf("\n");

        //下面是加法的,plus好像是个关键字,加了个my
        const int len_plus_result = (len_a>len_b)?len_a+1:len_b+1; //一个m位的数和一个n位的数相加,结果最大位为两个位数最大的加一
        short plus_result[len_plus_result] = {0};
        my_plus(a, b, plus_result, len_a, len_b, len_plus_result);
        carry(plus_result, len_plus_result);
        printf("Plus result is: ");
        if(plus_result[0] != 0)
                printf("%d", plus_result[0]);
        for(int i=1; i<len_plus_result; i++)
                printf("%d", plus_result[i]);
        printf("\n");

        //减法的
        const int len_sub_result = (len_a>len_b)?len_a:len_b;
        short sub_result[len_sub_result] = {0};
        int flag = my_sub(a, b, sub_result, len_a, len_b, len_sub_result);
        printf("Sub result is: ");
        if(flag == -1)
                printf("-");
        int zero_flag = 0;
        for(int i=0; i<len_sub_result; i++)
        {
                if(sub_result[i] != 0)
                        zero_flag = 1;
                if(zero_flag != 0)
                        printf("%d", sub_result[i]);
        }
        printf("\n");
        return 0;
}

void my_plus(short *a, short *b, short *result, int len_a, int len_b, int len_result)
{
        //把a和b都对齐到同样位数的数组中
        int len = (len_a>len_b)?len_a:len_b;
        short *temp_a = new short[len]();
        short *temp_b = new short[len]();

        int m=len-1;
        for(int i=len_a-1; i>=0; i--)
                temp_a[m--] = a[i];
        m=len-1;
        for(int i=len_b-1; i>=0; i--)
                temp_b[m--] = b[i];

        //计算加法,同样从result[1]开始
        int k=1;
        for(int i=0; i<len; i++)
        {
                result[k] = temp_a[i] + temp_b[i];
                k++;
        }
        delete temp_a;
        delete temp_b;
}

int my_sub(short *a, short *b, short *result, int len_a, int len_b, int len_result)
{
        //把a和b都对齐到同样位数的数组中
        int len = (len_a>len_b)?len_a:len_b;
        short *temp_a = new short[len]();
        short *temp_b = new short[len]();

        int m=len-1;
        for(int i=len_a-1; i>=0; i--)
                temp_a[m--] = a[i];
        m=len-1;
        for(int i=len_b-1; i>=0; i--)
                temp_b[m--] = b[i];

        int flag = 0;//默认为0,a>b
        for(int i=0; i<len; i++)
                if(temp_a[i] > temp_b[i])
                        break;
                else if(temp_a[i] < temp_b[i])
                {
                        flag = -1;
                        break;
                }
        //计算减法,没有进位从result[0]开始
        int k=0;
        for(int i=0; i<len; i++)
        {
                if(flag == 0)
                        result[k] = temp_a[i] - temp_b[i];
                else
                        result[k] = temp_b[i] - temp_a[i];
                k++;
        }


        //这里的借位与加法和乘法的不同,直接写在函数里面
         for(int i=len_result-1; i>0; i--)
        {
                if(result[i]<0)
                {
                        result[i] += 10;
                        result[i-1]--;
                }
        }
        delete temp_a;
        delete temp_b;
        return flag;
}

void multiply(short *a, short *b, short *result, int len_a, int len_b, int len_result)
{
        int k=1;//从result的result[1]开始存储,result[0]留着可能的进位
        for(int i=0; i<len_a; i++)
        {
                for(int j=0; j<len_b; j++)
                {
                        result[k] += a[i]*b[i];
                        k++;
                }
                k=2;
                k+=i;
        }
}


void carry(short *result, int len_result)
{
        int carry;
        int tens_place;
        for(int i=len_result-1; i>0; i--)
        {
                int temp = result[i];
                if(temp>9)
                {
                        carry = temp/10;
                        tens_place = temp%10;
                        result[i] = tens_place;
                        result[i-1] += carry;
                }
        }
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值