【算法笔记】高精度加减乘除

关于高精度:

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


高精度加法:

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

代码如下:

#include
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<   return 0;
}

高精度减法

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

代码如下:

#include
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<  return 0;
}

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

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

代码如下:

#include
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<  return 0;
}

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

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

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

代码如下:

#include
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<  return 0;
}

高精度除法:

同样,模拟竖式:

                                   15(a[i])

                         7(b)/109

                                   7(x)

                                    39

                                   35(x)

                                      4

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

用一个b存储除数,

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

代码如下:

#include
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<  cout<  return 0;
}


ok啦,高精度就写到这里啦,祝大家学会高精度








你可能感兴趣的:(【算法笔记】高精度加减乘除)