高精度加减乘除的笔记+代码

来源:互联网 发布:php中级工程师面试题 编辑:程序博客网 时间:2024/06/14 13:49

关于高精度:

其实在学习高精度以前,我已经会用pascal打高精度的代码了,所以我今天基本就把加减乘的代码复习并且重新打了一遍,然后又学会了高精度除以低精度的取余做法,加下来就让为大家一一演示一下吧!


高精度加法:

最主要的就是要学会如何倒着输入(因为竖式是从各位开始加的,所以要反着做)如何用竖式模拟,如何进位,输出即可

代码如下:

#include<bits/stdc++.h>
using namespace std;
int main()
{
string sa,sb;
int la,lb,lmax,a[10000]={},b[10000]={};
cin>>sa>>sb;
la=sa.length();
lb=sb.length();
lmax=max(la,lb);
for (int i=1;i<=la;i++)
a[i]=sa[la-i]-48;
for (int i=1;i<=lb;i++)
b[i]=sb[lb-i]-48;//到这存储到数组里面
for (int i=1;i<=lmax;i++)
{
a[i+1]=a[i+1]+(a[i]+b[i])/10;
a[i]=(a[i]+b[i])%10;//以上为加和进位
}
if (a[lmax+1]!=0) lmax++;//判断最高位是否为0
for (int i=1;i<=lmax;i++)
cout<<a[lmax-i+1];//反向输出结果
return 0;
}

高精度减法

对于高精度的减法,要注意:是大数减小数还是小数减大数并判断正负,如何减和退位,如何最后输出多余的零等。

代码如下:

#include<bits/stdc++.h>
using namespace std;
int main()
{
string sa,sb;
int la,lb,lmax,a[10000]={},b[10000]={};
cin>>sa>>sb;
la=sa.length();
lb=sb.length();
lmax=max(la,lb);
if (lb>la||(lb==la&&sb>sa)) 
{
cout<<'-';
string t=sa;
sa=sb;
sb=t;
int k=la;
la=lb;
lb=k;
}//判断s1大还是s2大,并判断和输出负号

for (int i=1;i<=la;i++)
a[i]=sa[la-i]-48;
for (int i=1;i<=lb;i++)
b[i]=sb[lb-i]-48;//反向读入
for (int i=1;i<=lmax;i++)
{
if (a[i]>=b[i]) a[i]-=b[i];//判断a[i]比b[i]大的情况,这个好办,直接减
else //否则(a[i]比b[i]小的情况)
{
a[i]=a[i]-b[i]+10;//像高位借10
a[i+1]--;//高位减一
}
}
while (a[lmax]==0) lmax--;//去掉多余的零
for (int i=1;i<=lmax;i++)
cout<<a[lmax-i+1];//反向输出
return 0;
}

高精度减法之高精度乘单精度:

同样,模拟竖式。用高精度的每一位乘单精度,然后进位什么的搞一下就ok啦

代码如下:

#include<bits/stdc++.h>
using namespace std;
int main()
{
string sa;
int la,lb,lmax,a[10000]={},b[10000]={},intb;
cin>>sa>>intb;
la=sa.length();
if (sa=="0"||intb==0)
{
cout<<0;
return 0;
}//判断有0的情况
for (int i=1;i<=la;i++)
a[i]=sa[la-i]-48;
        lmax=la+20;//lmax表示最后结果的最高位,因为单精度最多不会超过20位,所以就很暴力的+20
for (int i=1;i<=la;i++)a[i]*=intb;//用高精度的每一位分别处以单精度的数
for (int i=1;i<=lmax;i++)
{
a[i+1]=a[i+1]+a[i]/10;
a[i]=a[i]%10;
}//进行进位处理
while (a[lmax]==0) lmax--;//去除多余的零
for (int i=1;i<=lmax;i++)
cout<<a[lmax-i+1];
return 0;
}

高精度乘法之高精度乘高精度

原来的做法都是用a和b数组,这个高精度乘高精度就要史无前例的用上c数组了

通过列一个乘法竖式,可以发现:a[i]*b[j]的个位在c[i+j-1]的位置,如果有十位,存储在c[i+j]的位置。因此,可以通过枚举数字模拟乘法。

代码如下:

#include<bits/stdc++.h>
using namespace std;
int main()
{
string sa,sb;
int la,lb,lmax;
long long a[10000]={},b[10000]={},c[21000]={};//因为是乘法,数字会比较大,所以要用long long
cin>>sa>>sb;
la=sa.length();
lb=sb.length();
if (sa=="0"||sb=="0")
{
cout<<0;
return 0;
}
for (int i=1;i<=la;i++)
a[i]=sa[la-i]-48;
for (int i=1;i<=lb;i++)
b[i]=sb[lb-i]-48;
lmax=la+lb;
for (int i=1;i<=la;i++)
  for (int j=1;j<=lb;j++)
                      c[i+j-1]+=a[i]*b[j];//根据上述进行存储结果
for (int i=1;i<=lmax;i++)
{
c[i+1]=c[i]/10+c[i+1];
c[i]=c[i]%10;
}//做进位
while (c[lmax]==0) lmax--;
for (int i=1;i<=lmax;i++)
cout<<c[lmax-i+1];
return 0;
}

高精度除法:

同样,模拟竖式:

                                   15(a[i])

                         7(b)/109

                                   7(x)

                                    39

                                   35(x)

                                      4

模拟算式,首先要有一个数组a存储被除数,

用一个b存储除数,

还有用一个x存储剩下来的数.

代码如下:

#include<bits/stdc++.h>
using namespace std;
int main()
{
string sa;
int b,a[10000]={},x=0,i;
cin>>sa>>b;
for (i=1;i<=sa.size();i++)
a[i]=sa[i-1]-48;//因为除法是从高位开始处理的,所以应该正的存入数组,当然这样更容易希望
for (i=1;i<=sa.size();i++)
{
x=x*10+a[i];//求当前的余数x
a[i]=x/b;//求第i位做出发所得到的结果
x=x%b;//得到最后减完的余数
}
for (i=1;a[i]==0;i++);//以上为去掉前面的0
for (int k=i;k<=sa.size();k++) cout<<a[k];//输出商
cout<<endl<<x;输出余数
return 0;
}


ok辣,高精度就写到这里啦大笑