高精度乘除法

72 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第23天,点击查看活动详情

前置知识

如何存储一个大数据 : 把一个大数据放到数据当中去

image-20221029121449464

为什么这样存储

原因是两个数相加或者相乘的时候,会产生进位,此时我们要在高位补上一个数,在数组后面插入一个数比在数组的前面插入一个数容易,如果在前面插入一个数,所有的数都要向后移一位

高精度乘法

这里指的是高精度整数乘低精度整数:

做法: 将较小的数看做一个整体去和大的数的每一位相乘,取模( %10 )做结果 , 取除( /10 )做进位

image-20221029154214097

同样,最后还要去掉前导0


// C = A * b, A >= 0, b > 0
vector<int> mul(vector<int>& A, int b)//高精度整数乘低精度整数
{
    vector<int> C;
    int carry = 0;//进位
    for (int i = 0; i < A.size() || carry; i++)//A数组没有循环完成 || 还有进位
    {
        if (i < A.size()) carry =carry +  A[i] * b;
        C.push_back(carry % 10);//当前这一位的结果
        carry /= 10;//向上一位的进位
    }
    /*
    for(int i = 0 ; i < A.size() ; ++i)
    {   
        carry += A[i] * b;
        res.push_back( carry % 10);
        carry /=  10;
    }
    //最后还有进位
    if(carry != 0) res.push_back(carry);  
    */
    //去掉前导0
    while(C.size() > 1 && C.back() == 0)
         C.pop_back();
    return C;
}

高精度除法

这里主要是指:高精度除以低精度

image-20221029155318588

// A / b = C ... rem, A >= 0, b > 0  余数是rem 商是C
vector<int> div(vector<int>& A, int b, int& rem) //高精度除以低精度
{
    vector<int> C;
    rem = 0;//余数
    for (int i = A.size() - 1; i >= 0; i--) //从高位开始运算
    {
        rem = rem * 10 + A[i];//当前位的除数
        C.push_back(rem / b);//当前位计算结果
        rem %= b;//当前位计算之后的余数
    }
​
    //注意:此时C[0]存的是计算结果的最高位
    //为了统一倒叙打印数组C需要反转让C[0]存的是最低位
    reverse(C.begin(), C.end());
​
    //需要去除前导0 实际计算结果:00999  数组中:99900 需要去掉前导0
    while (C.size() > 1 && C.back() == 0) 
        C.pop_back();
    return C;
}