高精度算法

简介: 本文详细介绍了高精度算法的实现,涵盖加法、减法、乘法、除法及取模等操作。通过字符串与数组结合的方式,解决了大数运算中超出数据类型范围的问题。每种运算均提供完整的C++代码示例,包括输入处理、位运算模拟、进位/借位逻辑以及结果输出。其中,高精度加法和减法通过逆序存储数字简化计算;乘法利用双重循环模拟手算过程;除法分为低精度和高精度两种情况,分别采用逐位试商与减法模拟;取模则通过逐位累加求余实现。这些方法为处理大规模数值运算提供了有效工具,适用于竞赛编程与实际开发场景。

高精度算法

作者:blue

时间:2024.9

1.高精度加法(整数部分模板)

#include <iostream>
#include <string>
using namespace std;
int a1[1000],a2[1000],ans[1000];
int main()
{
   
    string s1,s2;
    cin>>s1>>s2;//字符串存放大数
    //逆序存放在数组中 
    for(int i=0;i<s1.size();i++) a1[s1.size()-i-1]=s1[i]-'0';
    for(int i=0;i<s2.size();i++) a2[s2.size()-i-1]=s2[i]-'0';
    int len=max(s1.size(),s2.size());
    //先相加 
    for(int i=0;i<len;i++){
   
        ans[i]=a1[i]+a2[i];
    }
    //后处理进位 
    for(int i=0;i<len;i++){
   
        ans[i+1]=ans[i+1]+ans[i]/10;
        ans[i]=ans[i]%10;
    }
    //逆序输出先判断len位为不为0(因为最高位可能进位,所以最长到len位)
    for(int i=len;i>=0;i--){
   
        if(i==len&&ans[len]==0) continue;
        cout<<ans[i];
    }
    return 0;
}

2.高精度减法(整数部分模板)

#include <iostream>
#include <string>
using namespace std;
const int N=1e6+10;
int a1[N],a2[N],ans[N];
int main()
{
   
    string s1,s2;
    cin>>s1>>s2;
    char flag='+';//符号判断 
    //判断两个数谁大谁小,大的那个放置在s1,如果交换了位置,就将符号置为'-'
    if(s1.size()<s2.size()||s1.size()==s2.size()&&s1<s2){
   
        swap(s1,s2);
        flag='-';
    } 
    //倒序存放 
    for(int i=0;i<s1.size();i++) a1[i]=s1[s1.size()-i-1]-'0';
    for(int i=0;i<s2.size();i++) a2[i]=s2[s2.size()-i-1]-'0';
    for(int i=0;i<s1.size();i++){
   
        if(a1[i]<a2[i]){
   //模拟借位的过程 
            a1[i]+=10;
            a1[i+1]--;
        }
        ans[i]=a1[i]-a2[i];
    }
    //注意此处index的值设置为0是有考究的,当是两个相等大数相减的话,那就只用输出1位0 
    int index=0;//找答案中第一个不为0的位置,为输出做准备 
    for(int i=s1.size()-1;i>=0;i--){
   
        if(ans[i]>0){
   
            index=i;
            break;
        }
    } 
    if(flag=='-') cout<<flag;
    for(int i=index;i>=0;i--) cout<<ans[i];
    return 0;
}

3.高精度乘法

image-20241019090817352.png

#include <iostream>
#include <string>
using namespace std;
const int N=1e8+10;
int a1[N],a2[N],ans[N];
int main()
{
   
    string s1,s2;
    cin>>s1>>s2;
    //反转两个数 
    for(int i=0;i<s1.size();i++) a1[i]=s1[s1.size()-i-1]-'0'; 
    for(int i=0;i<s2.size();i++) a2[i]=s2[s2.size()-i-1]-'0'; 
    int len=s1.size()+s2.size();//乘法最终的长度不会长于两个常数长度的和 
    //模拟乘法过程
    for(int i=0;i<s1.size();i++){
   
        for(int j=0;j<s2.size();j++){
   
            ans[i+j]+=a1[i]*a2[j];//注意这里不是赋值语句 
            ans[i+j+1]+=ans[i+j]/10;//进位 
            ans[i+j]=ans[i+j]%10;//保留本位 
        }
    } 
    //消除前导0 
    int index=0;
    for(int i=len;i>=0;i--){
   
        if(ans[i]!=0){
   
            index=i;
            break;
        }
    }
    //倒序输出 
    for(int i=index;i>=0;i--){
   
        cout<<ans[i];
    }
    return 0;
}

4.高精度除法

高精度除以低精度

image-20241019092848282.png

#include <iostream>
#include <string>
using namespace std;
const int N=1e8+10;
int ans[N],a[N];
long long b;
int main()
{
   
    string s;
    long long x=0;//用以承接每次的余数,初始应当为0,因为没有余数,注意这里余数也要开long long 防止余数很大的情况 
    cin>>s>>b;//输入一个高精度数和一个低精度数
    //这里不用倒序存放,因为除法本身就是一个从高位计算到低位的过程 
    for(int i=0;i<s.size();i++) a[i]=s[i]-'0';
    //模拟逐位试商的过程 
    for(int i=0;i<s.size();i++){
   
        ans[i]=(x*10+a[i])/b;
        x=(x*10+a[i])%b;
    }
    int index=0;
    //消除前导0,注意此处,index不能超过被除数的长度 
    while(ans[index]==0&&index<s.size()) index++;
    for(int i=index;i<s.size();i++) cout<<ans[i];
    if(index==s.size()) cout<<"0";//如果index等于被除数的长度,那么说明商就为0,要打印0
    //cout<<" "<<x;//有需要还可以打印余数 
    return 0;
}

高精度除以高精度

高精度除高精度要用减法模拟除法

image-20241019145033990.png

#include <iostream>
#include <string>
#include <cstring>
using namespace std;
const int N=1e6+10;
int a[N],b[N],c[N],tmp[N];
void init(int a[]){
   
    string s;
    cin>>s;
    a[0]=s.size();//a[0]存储字符串的长度 
    for(int i=1;i<=s.size();i++) a[i]=s[s.size()-i]-'0';//逆序存储 
}
void print(int a[]){
   
    if(a[0]==0){
   
        cout<<"0";
        return;
    }
    for(int i=a[0];i>0;i--) cout<<a[i];
    return;
}
int compare(int a[],int b[]){
   //比较两个数的大小,如果a大返回1,如果b大返回-1,一样大返回0 
    if(a[0]>b[0]) return 1;
    if(a[0]<b[0]) return -1;
    for(int i=a[0];i>0;i--){
   
        if(a[i]>b[i]) return 1;
        if(a[i]<b[i]) return -1; 
    }
    return 0;
}
void minu(int a[],int b[]){
   //高精度减法 
    for(int i=1;i<=a[0];i++)
    {
   
        if(a[i]<b[i]){
   
            a[i]+=10;
            a[i+1]--;
        }
        a[i]=a[i]-b[i];
    }
    while(a[a[0]]==0&&a[0]>0) a[0]--;//删除前导0 
    return; 
}
void numcpy(int b[],int tmp[],int n){
   //
    for(int i=1;i<=b[0];i++) tmp[i+n]=b[i];
    tmp[0]=b[0]+n;
}
int main()
{
   
    init(a);
    init(b);
    c[0]=a[0]-b[0]+1;//两位数相除,商最长的长度 
    if(c[0]<0) c[0]=0;
    for(int i=c[0];i>=1;i--){
   
        memset(tmp,0,sizeof(tmp));
        numcpy(b,tmp,i-1);//减法模拟除法,扩展减数,和被减数一样长 
        while(compare(a,tmp)>=0){
   //减干净 
            c[i]++;
            minu(a,tmp);
        }
    }
    while(c[c[0]]==0&&c[0]>0) c[0]--;//消去前导0 
    print(c);
    //print(a);//余数 
}

5.高精度取模

蛐蛐取mod,直接拿下

4.字符串加法【算法赛】 - 蓝桥云课 (lanqiao.cn)

#include <iostream>
#include <string>
#define int long long
using namespace std;
const int mod=1e9+7;
long long long_mod(string a)
{
   
  int ans=0;
  for(int i=0;i<a.size();i++){
   
    ans=(ans*10+(a[i]-'0'))%mod;
  }
  return ans;
}

signed main()
{
   
  string a,b,res;
  cin>>a>>b;
  res=a+b;
  cout<<long_mod(res);
  return 0;
}

6.高精度

第十五届蓝桥杯C/C++B组题解——R格式_第十五届蓝桥杯c语言b组答案-CSDN博客

目录
相关文章
|
8月前
|
SQL 关系型数据库 MySQL
菜鸟之路Day30一一MySQL之DML&DQL
本文介绍了MySQL中DML(数据操作语言)和DQL(数据查询语言)的核心用法。DML主要包括插入(insert)、更新(update)和删除(delete)语句,通过具体示例演示了如何对表数据进行增删改操作。DQL则聚焦于数据查询,涵盖基本查询、条件查询、聚合函数、分组查询、排序查询和分页查询等内容。文章通过丰富的SQL语句实例,帮助读者掌握如何高效查询和操作数据库中的数据,适合初学者学习和实践。
307 12
|
8月前
|
SQL 存储 关系型数据库
菜鸟之路Day29一一MySQL之DDL
本文《菜鸟之路Day29——MySQL之DDL》由作者blue于2025年5月2日撰写,主要介绍了MySQL中的数据定义语言(DDL)。文章详细讲解了DDL在数据库和表操作中的应用,包括数据库的查询、创建、使用与删除,以及表的创建、修改与删除。同时,文章还深入探讨了字段约束(如主键、外键、非空等)、常见数据类型(数值、字符串、日期时间类型)及表结构的查询与调整方法。通过示例代码,读者可以更好地理解并实践MySQL中DDL的相关操作。
287 11
|
存储 算法 C++
高精度算法(加、减、乘、除,使用c++实现)
高精度算法(加、减、乘、除,使用c++实现)
3194 0
高精度算法(加、减、乘、除,使用c++实现)
|
10月前
|
算法
蓝桥杯16天刷题计划一一Day02
这是蓝桥杯16天刷题计划的第二天内容,由作者blue于2025年3月28日整理。当天训练重点为二分法,包含多道经典题目解析与代码实现,如有序数组查找、砍树问题、木材加工等。文章针对二分法的应用场景进行了深入讲解,并通过实例演示了如何优化算法效率,适合对二分法不熟悉的初学者学习和练习。
257 5
|
7月前
|
算法
数论基础一一同余定理
同余定理是数论中的重要概念,用于判断两数对同一模数的余数是否相同,记作 \(a \equiv b \ (\text{mod } m)\)。其核心性质包括加减性和乘性,广泛应用于优化前缀和相关问题。本文通过三道例题详细解析同余定理的应用:1)蓝“k倍区间”,利用哈希表记录余数出现次数,将时间复杂度从 \(O(n^2)\) 降至 \(O(n+k)\);2)题“Subsequences Summing to Sevens S”,通过正序与倒序遍历寻找最长区间;3)AtCoder D题“Pedometer”,断环为链结合同余定理解决环形步数统计问题。这些实例展示了同余定理在算法竞赛中的高效应用。
393 0
|
9月前
|
存储 网络协议 API
Cpp网络编程Winsock API
本文详细介绍了使用Winsock API进行C++网络编程的过程,通过具体实例实现了一个基于TCP协议的C/S架构通信demo。文章从服务端与客户端两方面展开,涵盖网络库初始化、套接字创建、绑定IP与端口、监听与连接、数据收发到关闭连接等关键步骤。重点解析了`WSAStartup`、`socket`、`bind`、`listen`、`accept`、`connect`、`send`和`recv`等函数的使用方法及注意事项,并对比了标准库与Winsock库在链接时的区别。适合初学者了解Winsock网络编程基础。
476 35
|
9月前
|
前端开发 Java 程序员
菜鸟之路Day28一一分层解耦
本文《菜鸟之路Day28——分层解耦》由作者blue撰写于2025年4月29日,主要探讨软件开发中的三层架构与分层解耦概念。文章首先介绍了三层架构:Controller(控制层)、Service(业务逻辑层)和DAO(数据访问层),并深入讲解了“高内聚低耦合”的软件设计原则。接着,文章详细说明了控制反转(IOC)与依赖注入(DI)的实现方式,包括如何通过注解声明Bean对象、组件扫描以及解决多Bean冲突的方法(如@Primary、@Qualifier和@Resource)。内容结合实际开发场景,为初学者提供了清晰的指导。
294 15
|
9月前
|
存储 API C++
Cpp实现window上cmd执行效果
这段代码实现了一个简单的 Windows 命令行模拟器,支持用户输入命令并显示执行结果。程序通过 `GetCurrentDirectoryA` 获取当前目录,并用 `_popen` 执行命令,支持 `cd` 切换目录和 `exit` 退出功能。用户输入的命令会通过管道捕获输出并打印,返回码用于判断命令执行是否成功。代码结合了 C++ 标准库与 Windows API,展示了如何在 Windows 环境下操作命令行。
227 19
|
9月前
|
关系型数据库 MySQL 数据安全/隐私保护
MySQL下载与安装
本文介绍了MySQL的下载与安装流程(2025.4.29,作者:blue)。主要内容包括:1) 从官方地址下载MySQL;2) 解压文件并配置环境变量;3) 注册MySQL服务并通过命令行验证;4) 启动和停止MySQL服务;5) 修改默认账户密码;6) 登录MySQL。通过详细步骤和截图,帮助用户顺利完成安装与初始配置。
2368 13
|
10月前
|
JavaScript 前端开发 应用服务中间件
菜鸟之路Day24一一前端工程化(一)
本文详细介绍了从零开始搭建Vue前端项目并部署到Nginx服务器的全流程。首先,通过配置Node.js和vue-cli环境,为项目创建打好基础。接着,利用vue-cli快速生成Vue项目,可通过命令行或图形化界面完成配置,如添加路由功能等。文章还解析了Vue项目的结构,重点讲解组件的概念及实现方式,并通过编写登录页面组件演示开发过程。最后,展示了如何修改端口、启动项目以及组件挂载的原理,帮助读者深入理解Vue工程化开发的核心思想。
285 4
菜鸟之路Day24一一前端工程化(一)