当前位置:首页算法 > 正文

高精度乘法

作者:野牛程序员:2023-05-09 20:02:20算法阅读 2646

高精度乘法指的是在计算机上对非常大的整数进行乘法运算时所采用的一种算法。这种算法的基本思想是将整数按照位数拆分成多个小段,然后对每个小段进行相乘,并且将乘积按照位数对应相加,最后得到整个数的乘积。

以下是一种简单的高精度乘法算法:

  1. 将两个数分别拆分为两个长度相等的小段,如果长度不相等,则在较短的数的前面加上若干个0,使得长度相等。

  2. 对每个小段进行相乘,得到一个小段的乘积。

  3. 将所有的小段乘积按照位数对应相加,得到最终的乘积。

  4. 对于最终的乘积,需要去掉前导的0,并且判断乘积的符号。

需要注意的是,如果要进行高精度乘法,需要使用字符串或数组来表示大整数,因为普通的整数类型在计算机中的位数是有限制的。同时,高精度乘法算法的效率并不高,因为它需要对每个小段进行单独的相乘,所以对于非常大的整数,需要使用更加高效的算法来进行乘法运算。


伪代码如下:

function highPrecisionMultiplication(num1, num2):
    // 将数字转换成字符串,并且倒序排列,方便后面处理
    str1 = reverse(str(num1))
    str2 = reverse(str(num2))

    // 初始化乘积数组,初始值全部为0
    product = [0] * (len(str1) + len(str2))

    // 循环遍历第一个数的每一位
    for i from 0 to len(str1)-1:
        // 循环遍历第二个数的每一位
        for j from 0 to len(str2)-1:
            // 计算当前位数的乘积
            digitProduct = int(str1[i]) * int(str2[j])

            // 将乘积加入到对应位数上
            product[i+j] += digitProduct

    // 处理进位
    carry = 0
    for i from 0 to len(product)-1:
        // 加上进位
        product[i] += carry

        // 如果当前位数大于等于10,则需要向下一位进位
        carry = product[i] // 10
        product[i] = product[i] % 10

    // 去除前导0
    while len(product) > 1 and product[-1] == 0:
        product.pop()

    // 反转数组,并将结果转换成数字
    product = reverse(product)
    result = int("".join(str(digit) for digit in product))

    // 返回计算结果
    return result

C++源代码如下:

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

const int MAX_SIZE = 1005;

// 填充数组,初始值全部为0
void fillArray(int* arr, int arrSize) {
    for (int i = 0; i < arrSize; i++) {
        arr[i] = 0;
    }
}

// 高精度乘法函数,返回结果为字符串类型
string highPrecisionMultiplication(string num1, string num2) {
    // 将输入的数字转换成数组形式
    int len1 = num1.size(), len2 = num2.size();
    int arr1[MAX_SIZE], arr2[MAX_SIZE];
    fillArray(arr1, MAX_SIZE);
    fillArray(arr2, MAX_SIZE);

    for (int i = len1 - 1, j = 0; i >= 0; i--, j++) {
        arr1[j] = num1[i] - '0';
    }

    for (int i = len2 - 1, j = 0; i >= 0; i--, j++) {
        arr2[j] = num2[i] - '0';
    }

    // 计算结果数组大小
    int productSize = len1 + len2;

    // 初始化乘积数组,初始值全部为0
    int product[MAX_SIZE];
    fillArray(product, MAX_SIZE);

    // 循环遍历第一个数的每一位
    for (int i = 0; i < len1; i++) {
        // 循环遍历第二个数的每一位
        for (int j = 0; j < len2; j++) {
            // 计算当前位数的乘积
            int digitProduct = arr1[i] * arr2[j];

            // 将乘积加入到对应位数上
            product[i+j] += digitProduct;
        }
    }

    // 处理进位
    int carry = 0;
    for (int i = 0; i < productSize; i++) {
        // 加上进位
        product[i] += carry;

        // 如果当前位数大于等于10,则需要向下一位进位
        carry = product[i] / 10;
        product[i] %= 10;
    }

    // 去除前导0
    int resultSize = productSize;
    while (resultSize > 1 && product[resultSize-1] == 0) {
        resultSize--;
    }

    // 反转数组,并将结果转换成字符串
    string result(resultSize, '0');
    for (int i = resultSize - 1, j = 0; i >= 0; i--, j++) {
        result[j] = product[i] + '0';
    }

    // 如果结果为0,则直接返回"0"
    if (resultSize == 1 && result[0] == '0') {
        return "0";
    }

    return result;
}

// 测试函数
int main() {
    string num1, num2;
    cout << "请输入第一个数:" << endl;
    cin >> num1;
    cout << "请输入第二个数:" << endl;
    cin >> num2;

    string result = highPrecisionMultiplication(num1, num2);
    cout << "乘积为:" << result << endl;

    return 0;
}

product[i+j] += digitProduct;  其中的i+j 是怎么得到的呢

product[i+j]表示的是两数相乘后得到的乘积的第i+j位。这个乘积是由第一个数的第i位和第二个数的第j位相乘得到的。

比如,假设我们要计算的两个数分别为12345。在第一次循环中,我们会遍历第一个数的第一位,也就是3,并将它与第二个数的每一位相乘,得到的结果分别是:

3 * 5 = 15
3 * 4 = 12
3 * 0 = 0

可以看到,第一次循环中,乘积的第0位是由第一个数的第0位和第二个数的第0位相乘得到的,也就是product[0+0];乘积的第1位是由第一个数的第0位和第二个数的第1位相乘得到的,也就是product[0+1];乘积的第2位是由第一个数的第0位和第二个数的第2位相乘得到的,但是这一位是0,因此不需要处理。

野牛程序员教少儿编程与信息学奥赛-微信|电话:15892516892
野牛程序员教少儿编程与信息学竞赛-微信|电话:15892516892
相关推荐

最新推荐

热门点击