高精度算法

高精度算法

高精度的主要思路是:

  • 用数组保存数位
  • 模拟人的计算方式,计算各个数位

高精度加法

求 A + B

#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e6+6;

int a[N],b[N],c[N];
char s[N];
int L;
int la,lb;
void add(int *a,int *b){
    int t;
    for(int i=0;i<la||i<lb;i++){
        t = a[i] + b[i] + c[i];
        c[i] = t%10;
        c[i+1] = t/10;
        L = i;
    }
    if(c[L+1])L++;
}

int main(){

    scanf("%s",s);
    la = int(strlen(s));
    for(int i=0,j=la-1;i<la;i++)
        a[j--] = s[i] - '0'; 

    scanf("%s",s);
    lb = int(strlen(s));
    for(int i=0,j=lb-1;i<lb;i++)
        b[j--] = s[i] - '0';

    add(a,b);

    for(int i=L;i>=0;i--)
        printf("%d",c[i]);

}

高精度减法

求 A - B

#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e6+6;
int a[N],b[N],c[N];
char sa[N],sb[N];
int la,lb,lc;

bool big(int *a,int *b){
    // a>=b;
    
    if(la!=lb)return la>=lb;
    for(int i=la-1;i>=0;i--){
        if(a[i]==b[i])
            continue;
        return a[i] > b[i]; 
        
    }
    return true;
}

void sub(int *a,int *b){
    if(!big(a,b)) swap(a,b);
    int cnt=0,t;
    int L = max(la,lb);
    for(int i=0;i<L;i++){
        t = a[i] - b[i] - cnt;
        c[i] = (t+10)%10;
        cnt = t<0? 1:0;
        lc = i;
    }
    for(;c[lc]==0&&lc>0;lc--);
    
}

int main(){
    
    scanf("%s",sa);
    la = strlen(sa);
    for(int i=0,j=la-1;i<la;i++)
        a[j--] = sa[i] - '0';
    
    scanf("%s",sb);
    lb = strlen(sb);
    for(int i=0,j=lb-1;i<lb;i++)
        b[j--] = sb[i] - '0';
    
    sub(a,b);
    if(!big(a,b))printf("-");
    for(int i=lc;i>=0;i--)
        printf("%d",c[i]);
}

说来惭愧,sub那里最开始我写的是

void sub(int* a,int *b){
	if(!big(a,b)) return sub(a,b);
	...

因为这个一直在memory limit exceed 的报错误,真的憨憨,最后是在Xcode里检查出来错,发现一直死循环。

高精度乘法

计算A x b
A是大数,且假定b不超过10000

#include <iostream>
#include <cstring>
using namespace std;

#define ll long long
const int N = 1e6+6;
int a[N],b,c[N],la,lc;
char s[N];

void mulitply(){
    int cnt=0,t;
    lc = 0;
    for(int i = 0;i<la+6;i++){
    // 因为b最大是10000,所以a的一个位乘b最大是90000,最多进5位,我们取到6位,如果有多的0,在后面处理就行。
        t = a[i] * b + cnt;
        c[i] = t % 10;
        cnt = t / 10;
        lc++;
    }
    // 处理多余的前导0,至少保留一个0
    while(c[lc] == 0 && lc > 0)lc--;
    return;
}

int main(){
    
    scanf("%s",s);
    scanf("%d",&b);
    
    la = (int)strlen(s);
    for(int i = 0,j = la-1;i<la;i++)a[i] = s[j--]-'0';
    
    mulitply();
    
    for(int i=lc;i>=0;i--)
        printf("%d",c[i]);
    printf("\n");
    
    return 0;
}

高精度除法

A / b
求商和余数

这个我感觉写的好烂,代码功底太差了

#include <iostream>
#include <cstring>
using namespace std;

#define ll long long
const int N = 1e6+6;
int a[N],b,c[N],la,lc,r,extra;
char s[N];

void division(){
    int cnt=0,t;
    for (int i=la-1; i>=0; i--) {
        t  = cnt * 10 + a[i];
        c[lc++] = t / b;
        cnt = t % b;
    }
    //前导 0 的处理
    while(c[extra] == 0 && extra<lc)extra++;
    
    r = cnt;
    return;
}

int main(){
    
    scanf("%s%d",s,&b);
    la = (int)strlen(s);
    
    for(int i = 0,j = la-1;i<la;i++)a[i] = s[j--]-'0';
    
    division();
    
    if(extra==lc)printf("0\n");
    else{
        for(int i=extra;i<lc;i++)
            printf("%d",c[i]);
        printf("\n");
    }
    
    printf("%d\n",r);
    
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值