高精度(模板)

今天写了一道需要高精度的模板题
结果高精乘写错一句,调了1个小时。。。STO
所以写了一遍常用的高精度,在这里再简单说一下高精度的思路:

高精加

模拟竖式计算
注意每次累加的时候都要加上余数d

高精减

有一个额外操作:判断两数大小,确定答案符号
第一标准:长度
第二标准每一位数的大小
注意:因为在存贮的时候是倒叙存储,所以在对比的时候也要从高位到低位倒叙对比
模拟竖式计算
借位的时候容易出错
因为每一位最多不超过9,需要时只用从紧邻的高位借1即可,不用麻烦的考虑其他情况

由于我在代码中用的重载的方法,
传入的参数是只读的,所以只有在处理减法的时候,需要复制一下被减数

高精乘(高乘高)

超容易写错
二重循环
循环的次数是max(len)
在每一次加法的时候都要加上余数

for (int i=1;i<=len;i++)
{
    int x=0;
    for (int j=1;j<=len;j++)
    {
        c.s[i+j-1]+=a.s[i]*b.s[j]+x;
        x=c.s[i+j-1]/10;
        c.s[i+j-1]%=10;
    }
    c.s[i+len]=x;
}

高精除(高除低)

比较蒟,所以只会高除低
(其实高除高何以看作是高精减)
只要是除法,就可以看作是减法
但是高除低还有一种简单的方法:
分组相除
把大数分成和低精度数字同级的数字(一般是3到4位一组)
每一组和低精度的数字直接做低精度除法

例如:
123512314/24
分组:(123)(512)(314)
存储到数组里
first.
123/24=5……3
second.
下一位需要加上上一位的余数
3512/24=146……8
third.
8314/24=346……10
答案
123512314/24=5146346……10

tip

所有的答案都要去除前导0

#include<cstdio>
#include<iostream>
#include<cstring>

using namespace std;

const int N=100010;
char s[N<<1],opt;
struct node{
    int len,s[N];
    void clear()
    {
        memset(s,0,sizeof(s));
        len=0;
    }
};
node a,b,c;

node operator +(const node &a,const node &b)
{
    node c;
    c.clear();
    int len=max(a.len,b.len);
    int n=len;
    int d=0;
    for (int i=1;i<=len;i++)
    {
        c.s[i]=a.s[i]+b.s[i]+d;
        d=c.s[i]/10;
        c.s[i]%=10;
    }
    if (d) c.s[++n]=d;
    while (c.s[n]==0) n--;
    c.len=n;
    return c;
}

node operator -(const node &aa,const node &b)
{
    node c;
    node a=aa;
    c.clear();
    int len=max(a.len,b.len);
    int n=len;
    for (int i=1;i<=len;i++)
    {
        if (a.s[i]<b.s[i])
        {
            a.s[i+1]--;
            a.s[i]+=10;
        }
        c.s[i]=a.s[i]-b.s[i];
    }
    while (c.s[n]==0) n--;
    c.len=n;
    return c;
}

node operator *(const node &a,const node &b)
{
    node c;
    int len=max(a.len,b.len);
    int n=a.len+b.len;
    for (int i=1;i<=len;i++)
    {
        int x=0;
        for (int j=1;j<=len;j++)
        {
            c.s[i+j-1]+=a.s[i]*b.s[j]+x;
            x=c.s[i+j-1]/10;
            c.s[i+j-1]%=10;
        }
        c.s[i+len]=x;
    }
    while (c.s[n]==0) n--;
    c.len=n;
    return c;
}

int pd()
{
    if (a.len<b.len) return 1;
    else if (a.len>b.len) return 0;
    else
    {
        int i=a.len;
        while (a.s[i]==b.s[i]&&i>1) i--;
        if (a.s[i]<b.s[i]) return 1;
    }
    return 0;
}

void cl()
{
    bool ff=0;
    a.clear(); b.clear();
    int l=strlen(s);
    for (int i=l-1;i>=0;i--)
    {
        if (s[i]>='0'&&s[i]<='9'&&ff==0)
           b.s[++b.len]=s[i]-'0';
        else if (!(s[i]>='0'&&s[i]<='9')) opt=s[i],ff=1;
        else if (s[i]>='0'&&s[i]<='9'&&ff)
           a.s[++a.len]=s[i]-'0';
    }
}

int main()
{
    scanf("%s",&s);
    cl();
    bool p=0;
    if (opt=='+')
        c=a+b;
    else if (opt=='-')
    {
        p=pd();
        if (p)
            for (int i=1;i<=max(a.len,b.len);i++) 
               swap(a.s[i],b.s[i]);
        c=a-b;
    }
    else c=a*b;
    if (p) printf("-");
    for (int i=c.len;i>=1;i--)
        printf("%d",c.s[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/wutongtong3117/p/7673094.html