news 2026/6/2 12:23:55

高精度算法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
高精度算法

(1)高精度加法

首先,对字符串进行处理

string a,b; cin>>a>>b; vector<int>A(a.size()); vector<int>B(b.size()); for(int i=0;i<a.size();i++)A.push_back(a[i]-'0'); for(int i =0;i<.size();i++)B.push_back(b[i]-'0');

转换为vector数组并倒转数字{
//为什么?:1.在处理加法时,如果顺序存储,最高位就是A[0],如果最高位要进位,需要在a[0]前加一个数,显然会很麻烦(要移动数组每一位),换一种想法,只需要将数字倒过来相加,最高位在数组最末位,进位时只需要在数组最后添加一个数,显然大大提升了效率

接下来处理高精度加法函数

vector<int> add(vector<int> &A,vector<int> &B){ vector<int>C; int carry=0;//处理进位 for(int i=0;i<A.size()||i<B.size();i++){ if(i<A.size())carry+=A[i]; if(i<B.size())carry+=B[i]; C.push_back(carry%10); carry/=10; } if(carry!=0)C.push_back(carry); return C; }

将ab的每一位拿出来相加,存储carry的个位数存入C数组即可,假设从开始相加,carry为0,此时a与b的个位数相加,没进位,直接存入carry/=10;carry归零,如果进位,将carry个位数取出存入后,carry/=10;将进位存储在下一次加法的初始carry中,即可完成进位

最后,输出总结:

#include <bits/stdc++.h> using namespace std; // 高精度加法:C = A + B vector<int> add(vector<int> &A, vector<int> &B) { vector<int> C; int carry = 0; // 进位 for (int i = 0; i < A.size() || i < B.size(); i++) { if (i < A.size()) carry += A[i]; if (i < B.size()) carry += B[i]; C.push_back(carry % 10); carry /= 10; } if (carry) C.push_back(carry); // 最后的进位 return C; } int main() { string a, b; cin >> a >> b; // 转换为vector,低位在前 vector<int> A, B; for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0'); for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0'); vector<int> C = add(A, B); // 输出结果(从高位到低位) for (int i = C.size() - 1; i >= 0; i--) cout << C[i]; cout << "\n"; return 0; }

(2)高精度减法

第一步与加法相同,存储数字进入数组即可

string a, b; cin >> a >> b; vector<int> A, B; for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0'); for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');

接下来,写一个函数判断a,b大小再进行减法

bool compare(string a, string b) { if (a.length() != b.length()) return a.length() > b.length(); return a > b; }

接下来我们写减法函数,对于减法函数,在这里我们只考虑a>=b的情况,因为我们的vector数组不能存储负数,对于a<b的情况,我们在主函数中分情况讨论,a<b时,就交换计算b-a的情况,然后再添加负号

vector<int> sub(vector<int> &A, vector<int> &B) { vector<int> C; for (int i = 0, t = 0; i < A.size(); i++) { t = A[i] - t; // 先减去上一位的借位 if (i < B.size()) t -= B[i]; // 再减去B[i] C.push_back((t + 10) % 10); // 结果 t = t < 0 ? 1 : 0; // 如果t<0,需要借位 } // 去掉前导零 while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; }

为什么要(t+10)%10?:这是因为在减法的时候有两种情况,这一位够减了,对于+10再%10没有影响,而这一位不够减时,加10再%10就是向前借一位再减

前导零?:在减法时,可能会出现减法后由原本的位数减为少一位的情况,这时候就会产生前导零

最后,减法模板

#include <iostream> #include <vector> using namespace std; bool cmp(vector<int> &A, vector<int> &B) { if (A.size() != B.size()) return A.size() > B.size(); for (int i = A.size() - 1; i >= 0; i--) { if (A[i] != B[i]) return A[i] > B[i]; } return true; } // 高精度减法 A - B(要求 A >= B) vector<int> sub(vector<int> &A, vector<int> &B) { vector<int> C; for (int i = 0, t = 0; i < A.size(); i++) { t = A[i] - t; // 先减去上一位的借位 if (i < B.size()) t -= B[i]; // 再减去B[i] C.push_back((t + 10) % 10); // 结果 t = t < 0 ? 1 : 0; // 如果t<0,需要借位 } // 去掉前导零 while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; } int main() { string a, b; vector<int> A, B; cin >> a >> b; // 读取A(倒序存储) for (int i = a.length() - 1; i >= 0; i--) A.push_back(a[i] - '0'); // 读取B(倒序存储) for (int i = b.length() - 1; i >= 0; i--) B.push_back(b[i] - '0'); // 判断大小并计算 if (cmp(A, B)) { vector<int> C = sub(A, B); for (int i = C.size() - 1; i >= 0; i--) cout << C[i]; } else { cout << "-"; vector<int> C = sub(B, A); for (int i = C.size() - 1; i >= 0; i--) cout << C[i]; } return 0; }

(3)高精度乘法

高精度乘法一般分两种,一种高精度X低精度,一种高精度X高精度

1.高精度×低精度

这种比较简单,列出处理进位即可

与前面几种类似;

#include<iostream> #include<vector> using namespace std; vector<int> multiply(const vector<int>&A,long long b) { vector<int> C; long long t=0; for(int i=0;i<A.size()||t;i++) { if (i < A.size()) t += A[i] * b; C.push_back(t%10); t/=10; } while(C.size()>1&&C.back()==0)C.pop_back(); return C; } int main(){ string a; long long b; cin>>a>>b; vector<int>A; for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0'); vector<int> ans=multiply(A,b); for(int i=ans.size()-1;i>=0;i--)cout<<ans[i]<<" "; return 0; }

2.高精度×高精度

这里有一个比较重要的地方:竖式乘法中A的第i位置乘以B的第j位得到的数字应该在第i+j位置上,其余基本与前几项相同,不过要单独处理进位

#include<iostream> #include<vector> using namespace std; vector<int> multiply(const vector<int>&A,const vector<int>&B) { vector<int>C(A.size()+B.size(),0); for(int i=0;i<A.size();i++) { for (int j=0;j<B.size();j++) { C[i+j]+=A[i]*B[j]; } } int t=0; for (int i=0;i<A.size()+B.size();i++) { t+=C[i]; C[i]=t%10; t/=10; } while (C.size()>1&&C.back()==0)C.pop_back(); return C; } int main() { string a,b; cin>>a>>b; vector<int>A; vector<int>B; for (int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0'); for (int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0'); vector<int>ans=multiply(A,B); for (int i=ans.size()-1;i>=0;i--)cout<<ans[i]<<" "; return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/2 12:19:56

WechatDecrypt:三步解密微信聊天记录的终极免费工具

WechatDecrypt&#xff1a;三步解密微信聊天记录的终极免费工具 【免费下载链接】WechatDecrypt 微信消息解密工具 项目地址: https://gitcode.com/gh_mirrors/we/WechatDecrypt 你是否曾因无法查看本地加密的微信聊天记录而感到困扰&#xff1f;微信作为我们日常沟通的…

作者头像 李华
网站建设 2026/6/2 12:18:55

记录AI学习之路Day05:Prompt 优化技巧。

引言&#xff1a;在人工智能时代&#xff0c;尤其是大语言模型&#xff08;LLM&#xff09;应用日益广泛的今天&#xff0c;Prompt&#xff08;提示词&#xff09;的质量直接决定了我们与AI交互的效率和效果。一个精心设计的Prompt可以激发模型的最佳性能&#xff0c;生成精准、…

作者头像 李华
网站建设 2026/6/2 12:17:56

如何在本地搭建天气智能体项目

如何在本地搭建天气智能体项目 项目概述 本文将介绍如何在本地搭建一个完整的天气智能体项目。项目主要分为两部分&#xff1a; 使用 Ollama 部署通义千问 3.5&#xff08;Qwen 3.5&#xff09;大模型并完成连接测试实现天气查询功能&#xff0c;让大模型调用工具并给出智能回复…

作者头像 李华
网站建设 2026/6/2 12:13:48

互联网营销中流量赛道选择与选品策略的量化分析

在数字营销中&#xff0c;常常遇到一个问题&#xff1a;100万的预算&#xff0c;花到哪条赛道&#xff0c;回报更高&#xff1f;这个问题困扰过每一个运营人。2026年&#xff0c;随着各平台算法持续升级&#xff0c;传统的“广撒网”投放模式已经彻底失效。本文将从量化视角&am…

作者头像 李华
网站建设 2026/6/2 12:13:47

微软翻译新架构:Z-code MoE模型如何实现高效精准的多语言翻译

1. 项目概述&#xff1a;当翻译遇上“专家委员会”如果你和我一样&#xff0c;在跨国协作、阅读前沿论文或者处理多语言客户支持时&#xff0c;深度依赖过机器翻译&#xff0c;那你一定对翻译质量的“天花板”有过切身体会。常规的翻译模型就像一个全科医生&#xff0c;什么病都…

作者头像 李华