高精度算法加减乘

本文详细介绍了如何在面临大数计算需求时使用高精度算法,包括数据接收和存储策略,以及针对加法、减法和乘法的进位、错位处理方法。通过实例展示了如何在C++中实现高精度的加减乘运算。
摘要由CSDN通过智能技术生成

一.什么时候使用高精度算法

概念:在我们进行计算的过程中,经常会遇到几十位,甚至几百位的数字的计算问题,也有可能会遇到小数点后几十位,几百位的情况,而我们面对这样的情况下,longlongdouble 的数据范围显然是不够使用的了。因此这时,我们就需要引入一个新的算法,叫做高精度算法 .

这里补充一下 : int 2E9 、long long 9E18;

思想: 高精度算法本质上是用字符串模拟数字进行计算,再利用类似于数学里的竖式的形式,一位一位进行相关计算

二.如何去使用高精度算法

高精度计算中需要处理好以下几个问题:

1)数据的接收方法和存储方法

数据的接收和存储:当输入的数很长时,可采用字符串方式输入,这样可输入位数很长的数,利用字符串函数和操作运算,将每一位取出,存入数组中 .

void init(int a[]) { // 传入数组
    string s;
    cin >> s; 
    len = s.length(); // s.length --> 计算字符串位数
    for(int i=1; i<=len; i++)     
        a[i] = s[len -i] - '0'; //将字符串s转换为数组a, 倒序存储
}

2.1)进位、错位处理(加法)

int carry = 0;//定义一个变量实现进位处理
int len_c = 1; // 这里注意len_c最开始是1
while(len_c <= len_b || len_c <= len_a){ // 两数相加一定不能超过最大数数位加1
        c[len_c] = a[len_c] + b[len_c] + carry;
        carry = c[len_c] / 10;// 如果c[len_c]超10了就赋给carry实现进位
        c[len_c] = c[len_c] % 10;
        len_c++; // 错位处理
}
carry = c[len_c]; // 出现比最大位大的情况
if(carry == 0){ //消去前导0
len_c--;
}

2.1)基本代码(加法)

#include<bits/stdc++.h>
using namespace std;
#define N 10005
#define int long long
int a[N],b[N],c[N],len_a,len_b,len_c=1;
// 数据的接收、储存的办法
void init(){
    string s1,s2;
    getline(cin,s1);
    getline(cin,s2);
    len_a = s1.length();
    len_b = s2.length();
    for (int i = 1;i <= len_a;++i){
        a[i] = s1[len_a-i] - '0';
    }
    for (int i = 1;i <= len_b;++i){
        b[i] = s2[len_b-i] -'0';
    }
}
void myadd(){
    int carry = 0;
    while(len_c <= len_a || len_c <= len_b){
        c[len_c] = a[len_c] + b[len_c] + carry;
        carry = c[len_c]/10;
        c[len_c] = c[len_c]%10;
        len_c++;
    }
    carry = c[len_c];
    if(carry == 0){
        len_c--;
    }
}
void print(){
    for (int i = len_c;i >= 1;i--){
        cout << c[i];
    }
}
signed main(){
    init();
    myadd();
    print();
    return 0;
}

2.2)进位、错位处理(减法)

// 减法就多一个借位处理的问题
while(len_c <= len_b || len_c <= len_a){
if(a[i]<b[i]){
    c[i] = a[i] + 10 - b[i];
    a[i+1]--;
}
else{
    c[i] = a[i] - b[i];
}
    len_c++;
}

2.2)基本代码(减法)

#include<bits/stdc++.h>
using namespace std;
#define N 10005
#define int long long
int a[N],b[N],c[N],len_a,len_b,len_c=1;
// 数据的接收、储存的办法
void init(){
    string s1,s2;
    getline(cin,s1);
    getline(cin,s2);
    len_a = s1.length();
    len_b = s2.length();
    for (int i = 1;i <= len_a;++i){
        a[i] = s1[len_a-i] - '0';
    }
    for (int i = 1;i <= len_b;++i){
        b[i] = s2[len_b-i] -'0';
    }
}
void myjian(){
    while(len_c <= len_a || len_c <= len_b){
        if(a[len_c] < b[len_c]){
            c[len_c] = a[len_c] + 10 - b[len_c];
            a[len_c+1]--;
        }
        else{
            c[len_c] = a[len_c] - b[len_c];
        }
        len_c++;
    }
    while(c[len_c] == 0 && len_c > 1){
        len_c--;
    }
}
void print(){
    for (int i = len_c;i >= 1;i--){
        cout << c[i];
    }
}
signed main(){
    init();
    myjian();
    print();
    return 0;
}

2.3)进位、错位处理(乘法)

//从低位到高位 累加乘积 进位 存余
for (int i = 1;i <= len_a;i++){
    for (int j = 1;j <= len_b;j++){
        c[i+j-1] += a[i]*b[j];   // 累加乘积
        c[i+j] += c[i+j] / 10; // 进位
        c[i+j-1] %= 10; // 存余数
    }
}
//去除前导0
while(len_c>1 && c[len_c]==0){
    len_c--;
}

2.3) 基本代码(乘法)

#include<bits/stdc++.h>
using namespace std;
#define N 10005
#define int long long
int a[N],b[N],c[N],len_a,len_b,len_c=1;
// 数据的接收、储存的办法
void init(){
    string s1,s2;
    getline(cin,s1);
    getline(cin,s2);
    len_a = s1.length();
    len_b = s2.length();
    for (int i = 1;i <= len_a;++i){
        a[i] = s1[len_a-i] - '0';
    }
    for (int i = 1;i <= len_b;++i){
        b[i] = s2[len_b-i] -'0';
    }
}
void myadd(){
    int carry = 0;
    while(len_c <= len_a || len_c <= len_b){
        c[len_c] = a[len_c] + b[len_c] + carry;
        carry = c[len_c]/10;
        c[len_c] = c[len_c]%10;
        len_c++;
    }
    carry = c[len_c];
    if(carry == 0){
        len_c--;
    }
}
void myjian(){
    while(len_c <= len_a || len_c <= len_b){
        if(a[len_c] < b[len_c]){
            c[len_c] = a[len_c] + 10 - b[len_c];
            a[len_c+1]--;
        }
        else{
            c[len_c] = a[len_c] - b[len_c];
        }
        len_c++;
    }
    while(c[len_c] == 0 && len_c > 1){
        len_c--;
    }
}
void mymul(){
    len_c = len_a + len_b;
    for (int i = 1;i <= len_a;i++){
        for (int j = 1;j <= len_b;j++){
            c[i+j-1] += a[i]*b[j];
            c[i+j] += c[i+j]/10;
            c[i+j-1] %= 10;
        }
    }
    while(len_c > 1&&c[len_c]==0){
        len_c--;
    }
}
void print(){
    for (int i = len_c;i >= 1;i--){
        cout << c[i];
    }
}
signed main(){
    init();
    //myadd();
    //myjian();
    mymul();
    print();
    return 0;
}
  • 37
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值