高精度算法的理论基础

文章介绍了如何使用高精度算法处理大整数运算,通过将数字存储为数组而非二进制,解决了int和longlong类型的限制。在输入阶段,利用字符串存储输入的高精数,然后转换到数组中。运算过程中,采用倒序存储避免溢出,通过循环和进位机制完成加法操作。文章最后提到输出时再次倒序显示结果。
摘要由CSDN通过智能技术生成

引入

高精度算法是一种模拟算法,主要的作用就是当我们的数据足够大的时候(int 和 long long)都存不下来的时候,仍然可以正确的运算并输出结果。

它是一个最入门的算法,数学基础是小学二年级的加减乘除运算以及其竖式运算。

我们这个系列专栏学习的目标程度是将高精度算法成功的封装好。

算法实现过程

假设有两个高精数,A,B,需要我们去实现他的加减乘除运算,最后正确地输出结果。

第一步,我们要使用计算机去运算,首先要先定义(申请空间)A、B两个数。

问题1:按照计算机的存储数字的原理,都是把十进制数转换为了二进制数,再存储到计算机的物理空间之上:

(常规地输入整数a)

#include<iostream>
using namespace std;
int a;
int main()
{
    cin>>a;
    return 0;
}

可是,int(4字节)long long(8字节)都没法存下一个成百上千位的高精数。这个时候,我们就要投机取巧了,我们不把十进制数转为二进制数存储,而把它用数组来存起来。

但是,这个时候问题又来了。在C++标准输入中,我们输入数组的时候都需要将数以空格隔开:

1 2 3 4 5 6 7 8 9 0

而我们的目标输入方式:

1234567890

所以,我们引入了字符串:

我们先定义一个字符串,并将数输入进去,以字符串的形式存储。然后再正序导入到数组当中去。我们用两个int变量来记录A、B两数的长度。

假设a=99991,b=9;
int main()
{
    string a,b;
    int lena,lenb;
    int a1[1001],b1[1001];
    cin>>a>>b;
    lena=a.size(),lenb=b.size();
    for(int i=lena-1;i--;i>=0) a1[lena-i]=a[i];
    for(int i=lenb-1;i--;i>=0) b1[lenb-i]=a[i];
}

跳跳跳跳跳~~~~

<当前状态为已经向上面那样正序存入数组>我们现在开始运算了,99991+9=????

输出:10000

这个数怎么越变越小了???

这说明我们还是没有能够使我们的存储方式能够满足高精度的运算。分析一下刚刚的那个情况,明显是少了一位-个位的‘0’。为什么会少输呢?这是因为我们没有能够预估到结果的位数有多少。

那么我们就来介绍估计位数的算法。(根本就没有)

所以我们就倒序存储这个数吧,这样就使得我的数组不会溢出,不会损失数据。(具体编码实现请看下一篇文章)

问题2:我现在已经输入并存储了A、B两个数了,下面就开始运算了。

我们的运算过程和竖式运算很相似,除法除外,总共会涉及到两个操作:运算和进位。

所以我们在加减乘运算之前都需要定义一个专门进位的

int x=0;

初始化为 0 。

以加法为例:

我们都知道一个数加另一个数的结果的位数至少是两数当中的位数最大的数。

我们定义一个c数组来存储结果
int c[1001];
int lenc=max(lena,lenb);
证明:举极端例子:10000+1=10001,结果的位数永远不会低于两数中位数最大的那个数的位数

sure,负数另当别论。

然后就是通过构建循环来进行计算:

循环lenc次遍历两个数,个位对个位,十位对十位,然后相加。从低位到高位,每次相加一次,x更新一次,同时每次相加都会连带x一起加。

    c[i]=a[i]+b[i]+x;
    x=c[i]/10;
    c[i]%=10;

之前最后我们再来一个特判,如果我们的结果的前lenc位都已经算出了,那么我们还应该考虑一下是否第lenc+1位为 0 。

如果是 0 ,那么我们就不用去管它,不是 0 ,我们就需要吧第lenc+1位给它添上:

if(x!=0) lenc=lenc+1,c[lenc]=x;

(本文为了对新手友好,一些更晦涩简洁的写法被修改为了冗长但更易于理解的写法)

问题3:输出这个结果。

输入说了那么多,输出其实已经没有太多需要解释的地方了。

将c数组又倒序输出:

这一下,结果终于对啦!

输出:100000

新人写作,还请各位神犇多多指导!

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值