关于大数乘法的数组类型问题(int 还是char)

发布时间 2023-04-18 23:11:08作者: 凪风sama

可以知道在处理高精度乘法的时候,我们是不考虑当场进位的,在所有位数都模拟完竖式乘法后才进行逐位进位,这就要求存储每个位的数组保证不会爆掉溢出

众所周知char类型最多只能存储到255,非常非常容易溢出成负数,对于char型数组要考虑每一步乘法都要进位。

而int型数组最大21亿就不用考虑这种问题,当然是在内存允许的前提下

P1045 [NOIP2003 普及组] 麦森数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn),举个例子

这道题要求高精度的乘法,我一开始开的就是char型数组,当输入P较小时尚可,当P超过50时就会爆负数,我真的会谢,找了半天没找到问题,最终发觉应该是char型变量爆了,随后改为int就好了

如图

void Big_Multiple(char A[], char B[], int* lena, int lenb)
{
    char C[1000000]={0};
    for (int i = 0; i < *lena; i++)
    {
        for (int j = 0; j < lenb; j++)
        {
            C[i + j] += A[i] * B[j];
        }
    }
    int lenc = *lena + lenb - 1;
    int last = 0;
    for (int i = 0; i < lenc; i++)
    {
        int Temp = C[i] + last;
        C[i] = Temp % 10;
        last = Temp / 10;
    }
    while (last)
    {
        C[lenc++] = last % 10;
        last /= 10;
    }
    for (int i = 0; i < lenc; i++)
        A[i] = C[i];
    *lena = lenc;
}

char型数组,结果如下

(算的是2的P次方,用了快速幂),可以看到当P大于30就开始爆负数了

下面是改为int后的

void Big_Multiple(int A[], int B[], int* lena, int lenb)
{
    int C[1000000]={0};
    for (int i = 0; i < *lena; i++)
    {
        for (int j = 0; j < lenb; j++)
        {
            C[i + j] += A[i] * B[j];
        }
    }
    int lenc = *lena + lenb - 1;
    int last = 0;
    for (int i = 0; i < lenc; i++)
    {
        int Temp = C[i] + last;
        C[i] = Temp % 10;
        last = Temp / 10;
    }
    while (last)
    {
        C[lenc++] = last % 10;
        last /= 10;
    }
    for (int i = 0; i < lenc; i++)
        A[i] = C[i];
    *lena = lenc;
}

可以看到即使P为10000还没爆负数,完美

当然不难发现我们并不需要将所有数组都开成int型,只有一个数组需要为int型那就是高精度乘法时接受加和的那个数组,其他数组为char型即可

void Big_Multiple(char A[], char B[], int* lena, int lenb)
{
    int C[1000000]={0};//就是这个数组需要设为int型,其他数组设为char型即可
    for (int i = 0; i < *lena; i++)
    {
        for (int j = 0; j < lenb; j++)
        {
            C[i + j] += A[i] * B[j];
        }
    }
    int lenc = *lena + lenb - 1;
    int last = 0;
    for (int i = 0; i < lenc; i++)
    {
        int Temp = C[i] + last;
        C[i] = Temp % 10;
        last = Temp / 10;
    }
    while (last)
    {
        C[lenc++] = last % 10;
        last /= 10;
    }
    for (int i = 0; i < lenc; i++)
        A[i] = C[i];
    *lena = lenc;
}