高精度(模板)

来源:互联网 发布:vue.js 提交表单 ajax 编辑:程序博客网 时间:2024/05/21 23:12

今天写了一道需要高精度的模板题
结果高精乘写错一句,调了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;}
原创粉丝点击