跳至正文
View Categories

1 min read

主要内容 #

  1. 高精度乘以单精度例题精讲
  2. 高精度乘以高精度例题精讲

1. 高精度乘以单精度例题精讲 #

1.1 计算过程 #

这种乘法运算与高精度加法类似,所不同的是,对于高精度数字由低位到高位逐位乘以单精度数。设高精度的数位数字为a[i],单精度数为b,则可以把a[i]*b除以进制的余数作为更新a[i]的值,把其商数作为进位。过程如下:
1.接收输入的高精度的字符串a:用string接收正整数的数字串;
2.从低位往高位存放到数组a,单精度整数b用int型存储;
3.重点:将两个数进行相乘,计算相乘的过程中,同时处理进位
注意:刚开始时,进位x=0;同时要注意最高位的进位,不要漏了。

1.2 例题 #

求10000以内n的阶乘。
输入:
只有一行输入,整数n(0<= n <= 10000)。
输出:
一行,即n!的值。
样例输入:
100
样例输出:
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
参考程序

#include < iostream >
#include < string >
using namespace std;

int a[40010], n, x, len = 1;

int main(){
    cin >> n;
    //初始化为1
    a[1] = 1;
    for(int i = 1; i <= n; ++i){
        x = 0;
        //len 表示当前整数的长度
        for(int j = 1; j <= len; ++j){
            a[j] = a[j] * i + x;
            //x 表示处理上一位的进位
            x = a[j] / 10;
            a[j] = a[j] % 10;
            //判断进位后整数的长度是够增加
            if(x > 0 && j >= len) len++;
        }
    } 
    //逆序输出
    for(int i = len; i >= 1; i--) cout << a[i];
    cout << endl;
    return 0;
}

2. 高精度乘以高精度例题精讲 #

2.1 计算过程 #

1.接收输入的两个大整数的数字串:用string接收两个正整数的数字串(C用字符数组或字符指针);
2.从低位往高位存放到数组a和b中;
3.重点:将两个数进行相乘:
计算相乘的过程中,可以先不考虑进位,后面再处理进位
(1)先不考虑进位,先按竖式计算,求出各个位置相乘得到的数存到数组c中;
(2)然后,再处理进位,用求余。

2.2 例题 #

求两个不超过200位的非负整数的积。
输入:
有两行,每一行是不超过200位的非负整数。
输出:
一行,即两行数相乘的结果。
样例输入:
1234567
7654321
样例输出:
9449772114007
参考程序

#include < iostream >
#include < string >
using namespace std;
const int MAX = 100;
int toMul(int a[], int b[], int c[], int la, int lb);
 
int main(int argc, const char * argv[]) {
    // 因为第一个数a的位数为len1,b的位数为:len2,所以c应为len1+len2+1
    // 如:a,b位数最高为2位数,则最大为:99 * 99 < 100 * 100 = 10000
    // 积的位数小于 2 + 2 + 1 = 5;
    int a[MAX], b[MAX], c[2*MAX+1], i, la, lb, lc;
    string str1, str2;
    
    cout << "请输入两个高精度数(空格隔开):\n";
    while(cin >> str1 >> str2) { // 1.输入两个大整数的数字串
        cout << "这两个数之积是:\n";
        memset(a, 0, sizeof(a)); // 清零
        memset(b, 0, sizeof(b));
        memset(c, 0, sizeof(c));
        
        la = (int)str1.size();
        lb = (int)str2.size();
        // 2.将两个大整数从低位往高位存放到数组中
        for(i = 0; i < la; i++)
            a[la-i-1] = str1[i] - '0'; // '0'->48
        for(i = 0; i < lb; i++)
            b[lb-i-1] = str2[i] - 48; // 减去'0'或48都可以
        // 3.c=a*b,求两个大整数的积
        lc = toMul(a, b, c, la, lb);
        // 4.输出结果:从高位往低位输出
        for(i = 0; i < lc; i++)
            cout << c[lc-i-1];
        cout << endl;
        cout << "请输入高精度数和一个整数(空格隔开):\n";
    }
    return 0;
}
 
// c=a*b,求两个大整数的积
int toMul(int a[], int b[], int c[], int la, int lb) {
    int i, j, lc;
    
    // 逐位相乘求出对应位置的数,先不考虑进位
    for(i = 0; i < la; i++)
        for(j = 0; j < lb; j++) {
            c[i+j] = c[i+j] + a[i] * b[j];
        }
    lc = la + lb; // 积的最大长度
    // 处理进位
    for(i = 0; i < lc; i++) {
        c[i+1] = c[i+1] + c[i] / 10; // 求进位,求出第i位向第i+1位的进位
        c[i] = c[i] % 10;
    }
    while(lc > 1 && c[lc-1] == 0)
        lc--;
    return lc;
}