高精度计算(+-*/)(压位计算)(c++实现)

 进来的时候如果没看见除法,说明我也还不会,会了的话我会补充上去的。如果要看的除法的,得去看别人的了。


目录

初始化:

 加法:

减法:

乘法:

 输出:这个是重点!!!!!!!!!!!

完整代码:


 如果你是从我的“P1601 A+B Problem(高精)”这篇文章来的话,可以看一下压位计算,更加的快捷方便。

高精度计算就是因为超过了数据表达的类型,从用其他的方式来进行计算。

压位就是说将一长串的数字分割开来,来单独进行保存,从而不会发生超过范围。


初始化:

可以看到 k 其实就是控制一个int里面有多少位,你可以自己设定,但如果太大了的话 乘法就有可能越界,如果只是加减法可以适当的调整大小。

读入还是得用string类型,没办法确实太大了

后面的输出里面会说到int类型的一个缺陷。

void Initialization(string str,int num[]){//初始化,用数组的第一位来保存里面有几位
    int n=str.length(),k=1,j=1;
    for(int i=1;i<=n;i++){
        if(k==10000){//表示用的10000进制,也可以自己改进制,但是如果太高的话,乘法和除法不好处理
            j++;
            k=1;
        }
        num[j]+=k*(str[n-i]-'0');
        k=k*10;
    }
    num[0]=j;
    return;
}

 加法:

我是新建了一个数组来存放结果,也可以就利用那两个数组进行运算,但我懒了(其实是不怎么会,怕出错)

关键点1:就是在于进位,要记得每次都要判断是否大于10000,我使用10000进制的,如果你改成了其他的,这个数字跟k相同就行

关键点2:就是会多一位出来,我代码里面也写了是关键,你得判断多出来的一位里面有没有东西,如果有就得加进去。

void addition(int num1[],int num2[]){//加法
    int result[Maxn];
    memset(result,0,sizeof(result));
    result[0]=max(num1[0],num2[0]);
    for(int i=1;i<=result[0];i++){
        result[i]+=num1[i]+num2[i];
        if(result[i]>=10000){//则要进行进位
            result[i]-=10000;
            result[i+1]++;//往前进位
        }
    }
    //下面是关键
    if(result[result[0]+1]>0){//类似于9999+1,则会多一位出来,就要判断是否多了一位。
        result[0]++;
    }
    cout<<result;
}

减法:

同样是新建的数组。

关键点1:跟加法不一样,你得借位,所以是跟0进行比较,并且记得借了一位,要减去

关键点2:这里判断有没有多是用 while 循环,跟加法不一样,他有可能会一直借位,所以得一直判断。

void subtraction(int num1[],int num2[]){//减法
    int result[Maxn];
    memset(result,0,sizeof(result));
    result[0]=max(num1[0],num2[0]);
    for(int i=1;i<=result[0];i++){
        result[i]+=num1[i]-num2[i];
        if(result[i]<0){//要向前借位
            result[i]+=10000;
            result[i+1]--;
        }
    }
    //下面也是关键
    while(result[result[0]]==0&&result[0]>1){//将前面多余的0删除
        result[0]--;
    }
    cout<<result;
}

乘法:

新建。

这个比加法就要难,相当于是多个加法的叠加,而且每次加的时候不是在同一个位置加,会往前跑一个。

进位就不说了。

result[i+j-1]+=num1[i]*num2[j];//减1是为了从第一位开始

这一行代码如果不能理解的话,可以去列一下竖式,我相信肯定都会明白的,就是往前移一个相加。总不能不会列竖式吧,这要是不会我也没办法了 

后面就是判断前置0的 while 循环了。

void multiplication(int num1[],int num2[]){//乘法
     int result[Maxn];
    memset(result,0,sizeof(result));
    result[0]=num1[0]+num2[0]+1;
    for(int i=1;i<=num1[0];i++){
        for(int j=1;j<=num2[0];j++){//就是竖式算法一样,一步步来求
            result[i+j-1]+=num1[i]*num2[j];//减1是为了从第一位开始
            result[i+j]+=result[i+j-1]/10000;//进位
            result[i+j-1]%=10000;
        }
    }
    //下面是关键
    while(result[result[0]]==0&&result[0]>0){//就是把前面多余的0删除
        result[0]--;
    }
    cout<<result;
}

 输出:

这次可没有新建了嗷!

这个输出其实也可以用其他的方式来输出,但那样就得自己去看是不是满4位了。

我先说为什么要满4位输出

因为int类型里面存放的时候 “0000” 它是看成 “0”来存放的,比如 10000 放在 int 里面就会变成

int[1]=0,int[2]=1;这样输出的话就会变成10。

所以如果不用流输出的话,就得自己判断 int 里面有几位,然后要补几个0,但是用流输出的话,就可以直接用函数。就很方便,不用自己写,这还不爽?如果不会流的话,可以去学一下,很快的。

还有就是运算符的重载,学一下也很快的。都是模板,套一下就好!

ostream&operator<<(ostream &o,int result[]){
    o<<result[result[0]];
    for(int i=result[0]-1;i>0;i--){
        o.width(4);//每次都要输出4位
        o.fill('0');//如果不够4位则要补齐,因为int类型里面的0000会被当作0
        o<<result[i];
    }
    return o;
}

完整代码:

#include<iostream>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<algorithm>
#include<vector>
using namespace std;
const int Maxn=10000;
ostream&operator<<(ostream &o,int result[]){
    o<<result[result[0]];
    for(int i=result[0]-1;i>0;i--){
        o.width(4);//每次都要输出4位
        o.fill('0');//如果不够4位则要补齐,因为int类型里面的0000会被当作0
        o<<result[i];
    }
    return o;
}
void Initialization(string str,int num[]){//初始化,用数组的第一位来保存里面有几位
    int n=str.length(),k=1,j=1;
    for(int i=1;i<=n;i++){
        if(k==10000){//表示用的10000进制,也可以自己改进制,但是如果太高的话,乘法和除法不好处理
            j++;
            k=1;
        }
        num[j]+=k*(str[n-i]-'0');
        k=k*10;
    }
    num[0]=j;
    return;
}
void addition(int num1[],int num2[]){//加法
    int result[Maxn];
    memset(result,0,sizeof(result));
    result[0]=max(num1[0],num2[0]);
    for(int i=1;i<=result[0];i++){
        result[i]+=num1[i]+num2[i];
        if(result[i]>=10000){//则要进行进位
            result[i]-=10000;
            result[i+1]++;//往前进位
        }
    }
    //下面是关键
    if(result[result[0]+1]>0){//类似于9999+1,则会多一位出来,就要判断是否多了一位。
        result[0]++;
    }
    cout<<result;
}
void subtraction(int num1[],int num2[]){//减法
    int result[Maxn];
    memset(result,0,sizeof(result));
    result[0]=max(num1[0],num2[0]);
    for(int i=1;i<=result[0];i++){
        result[i]+=num1[i]-num2[i];
        if(result[i]<0){//要向前借位
            result[i]+=10000;
            result[i+1]--;
        }
    }
    //下面也是关键
    while(result[result[0]]==0&&result[0]>1){//将前面多余的0删除
        result[0]--;
    }
    cout<<result;
}
void multiplication(int num1[],int num2[]){//乘法
     int result[Maxn];
    memset(result,0,sizeof(result));
    result[0]=num1[0]+num2[0]+1;
    for(int i=1;i<=num1[0];i++){
        for(int j=1;j<=num2[0];j++){//就是竖式算法一样,一步步来求
            result[i+j-1]+=num1[i]*num2[j];//减1是为了从第一位开始
            result[i+j]+=result[i+j-1]/10000;//进位
            result[i+j-1]%=10000;
        }
    }
    //下面是关键
    while(result[result[0]]==0&&result[0]>0){//就是把前面多余的0删除
        result[0]--;
    }
    cout<<result;
}
int main(){
    string str1,str2;
    cin>>str1>>str2;
    int num1[Maxn];
    int num2[Maxn];
    memset(num1,0,sizeof(num1));//将数组里面的全部值变成0
    memset(num1,0,sizeof(num1));//将数组里面的全部值变成0
    Initialization(str1,num1);
    Initialization(str2,num2);
    multiplication(num1,num2);
    system("pause");
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值