数论 —— 高精度乘法

高精度乘法

高精度乘法其实是大整数之间的相乘,大整数之间的相乘如果超过 int 或 long long 类型是无法用变量来表示的。有的大整数甚至超过500位。那如何 精确的 表示大整数与大整数之间的相乘呢?

答案是使用整型数组来表示 个位 百位 千位…

举例说明:
图片未加载请刷新

  1. 165 * 13 ,我们可以发现我们先把各个位置的数据先算起来 3 * 165 时为 3 18 15
    1 * 165时为 1 6 5 注意要错位, 再将相应位置的数据加起来为 1 9 23 15,最后进行进位操作变为 2 1 4 5,即正确结果为2145
  2. 令指向165数字的游标为 i ,指向13数字的游标为j,i , j 都 0 开始 遍历, 我们也可以发现一个规律,比如A0位置数和即为 i + j位置的数和. 再比如A1位置的数值总和(未进位前的 和为 23) 等于i + j ( 即等于( 1 + 0 )以及 (0 + 1 )) (23 = 6 * 3 + 1 * 5))
  3. 还有一种情况需要说明, 两个大整数相乘的结果的位数一定不会超过该两大整数的位数之和,即 a * b = c, len(c) <= len(a) + len(b)
    比如 12 * 3 = 36 12 * 9 = 108 未超过 (2 + 1 = 3)位
    比如 165 * 13 = 2145 165 * 99 = 16335 未超过 (3 + 2 = 5) 位
    比如 999 * 999 = 998001 未超过 (3 + 3 = 6) 位

因此无论哪两个大整数之间相乘,其结果的位数不会超过两个大整数的位数之和。当然可能小于两个整数位数之和,此时需要去掉 前导0

比如 163 * 13 = 02145 ,需要去掉 首位的 0

具体实现我们来看代码吧!

#include <iostream>
#include <cstdio>
#include <cstring>
//高精度
using namespace std;
int a[10000], b[10000], c[10000];//定义3个整型数组
int main()
{
    string x, y;
    cin >> x >> y;//输入两个字符串 165   和  13 
    int lenx = x.length();
    int leny = y.length();
    int i, j;
    for (i = lenx - 1, j = 0; i >= 0; i--, j++)
        a[j] = x[i] - '0';//将字符串逆向存入到a数组中,lenx = 3
        
//  2    1   0
//  1    6   5   
    for (i = leny - 1, j = 0; i >= 0; i--, j++)
        b[j] = y[i] - '0';//将字符串逆向存入到b数组中,leny = 2
// 1   0
// 1   3  

    for (i = 0; i < lenx; i++)
    {
        for (j = 0; j < leny; j++)
        {
            c[i + j] += a[i] * b[j];//两个循环进行遍历,来存储A【i】位置的各个总数
        }
    }
    int lenc = lenx + leny;//两个大整数相乘结果的最大位数
    for (i = 0; i < lenc - 1; i++)
    {//开始进行进位处理
        c[i + 1] += c[i] / 10;
        c[i] = c[i] % 10;
    }
    while (c[lenc - 1] == 0 && lenc > 1) lenc--;//去掉前导0
    for (i = lenc -  1; i >= 0; i-- )
        cout << c[i];
    cout << endl;
    return 0;
}

此代码即是整个高精度数据的计算,主要是用于大整数之间的相乘,理解原理和逻辑思路后建议自己写写来巩固一下呗!

本人新手,可能讲解的不是非常的通俗易懂,也许有很多不足之处!此处推荐两篇博客供大家学习学习参考参考!

大整数 X 大整数高精度
大数之间的运算(高精度)

©️2020 CSDN 皮肤主题: 岁月 设计师:pinMode 返回首页