C++高精度算法
目录:
前言:
计算机最初、也是最重要的应用就是数值运算。在编程进行数值运算时,有时会遇到运算的精度要求特别高,远远超过各种数据类型的精度范围;有时数据又特别大,远远超过各种数据类型的极限值。这种情况下,就需要进行“高精度运算”。
高精度运算首先要处理好数据的接受和存储问题,其次要处理好运算过程中的“进位”和“借位”问题。
引用自百度百科
高精度算法(High Accuracy Algorithm)是处理大数字的数学计算方法。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字。一般这类数字我们统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算。对于非常庞大的数字无法在计算机中正常存储,于是,将这个数字拆开,拆成一位一位的,或者是四位四位的存储到一个数组中, 用一个数组去表示一个数字,这样这个数字就被称为是高精度数。高精度算法就是能处理高精度数各种运算的算法,但又因其特殊性,故从普通数的算法中分离,自成一家。
思路:
高精度加法:
用字符串输入两个数,再导入数组,然后每位相加,如果某位数字>10,则此位模10,下一位加一,最后用while循环去除前导零再输出即可。
高精度减法:
用字符串输入两个数,再导入数组,判断是否后数比前数,如果是则输出负号再交换数组。然后按位相减不够借1,最后用while循环去除前导零再输出即可。
高精度乘法:
导入方法与前面一样,导入后按乘法竖式思路相乘,再按常规思路进位。最后去除前导零就行了。
高精度除法:
比较复杂不做过多解释。
代码:
一、高精度加法
#include<bits/stdc++.h>
using namespace std;
#define maxx 1145 //最长值(默认1145位)
char sa[maxx], sb[maxx];
int la, lb, lc, a[maxx], b[maxx], c[maxx];
int main() {
scanf("%s %s", sa, sb);//读入字符串
la = strlen(sa);
lb = strlen(sb);
// 格式化字符串,看情况
// memset(a, 0, sizeof(a));
// memset(b, 0, sizeof(b));
// memset(c, 0, sizeof(c));
//正序将字符串写入到数组A,B中
for (int i = 0; i < la; i++) {
a[la - i - 1] = sa[i] - '0';
}
for (int i = 0; i < lb; i++) {
b[lb - i - 1] = sb[i] - '0';
}
lc = la > lb ? la : lb;//更新长度数据
//模拟竖式加法
for (int i = 0; i < lc; i++) {
c[i] = a[i] + b[i] + c[i];
if (c[i] > 10) { //进位
c[i + 1] = 1;
c[i] -= 10;
}
}
if (c[lc] > 0)lc++;//更新长度
//逆序打印输出
for (int i = lc - 1; i >= 0; i--) {
printf("%d", c[i]);
}
return 0;
}
二、高精度减法
#include <bits/stdc++.h>
using namespace std;
#define maxx 1145 //最长值(默认1145位)
char sa[maxx], sb[maxx];
char tmp[maxx];//交换字符串
int la, lb, lc, a[maxx], b[maxx], c[maxx];
int main() {
scanf("%s %s", sa, sb);//读入字符串
la = strlen(sa);
lb = strlen(sb);
//判断最终的结果符号
if ((la < lb) || (la == lb && strcmp(sa, sb) < 0)) {
//被减数小于减数,结果为负数
printf("-");
//交换数据
strcpy(tmp, sa);
strcpy(sa, sb);
strcpy(sb, tmp);
//更新长度数据
la = strlen(sa);
lb = strlen(sb);
}
// 格式化字符串,看情况
// memset(a, 0, sizeof(a));
// memset(b, 0, sizeof(b));
// memset(c, 0, sizeof(c));
//倒序将字符串写入到数组A,B中
for (int i = 0; i < la; i++) {
a[i] = sa[la - i - 1] - '0';
}
for (int i = 0; i < lb; i++) {
b[i] = sb[lb - i - 1] - '0';
}
//模拟竖式减法
for (int i = 0; i < la; i++) {
if (a[i] < b[i]) { //借位
a[i + 1]--;
a[i] += 10;
}
c[i] = a[i] - b[i];
}
//删除前导零
for (int i = la - 1; i >= 0; i--) {
//因为我们是从索引 0 开始,所以最高位是保存在 len-1
if (0 == c[i] && la > 1) {
//注意要有 la>1 这个条件。考虑特殊情况,加法结果为 00,我们实际要输出 0。
la--;
} else {
//第一个不是零的最高位,结束删除
break;
}
}
//逆序打印输出
for (int i = la - 1; i >= 0; i--) {
printf("%d", c[i]);
}
return 0;
}
三、高精度乘法
#include<bits/stdc++.h>
using namespace std;
#define maxx 1145
char sa[maxx], sb[maxx];
int la, lb, lc, jw, f, w, a[maxx], b[maxx], c[maxx * maxx];
int main() {
scanf("%s", sa);
scanf("%s", sb);
la = strlen(sa);
lb = strlen(sb);
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
for (int i = 0; i < la; i++) {
a[la - i - 1] = sa[i] - '0';
}
for (int i = 0; i < lb; i++) {
b[lb - i - 1] = sb[i] - '0';
}
jw = 0;//存储每一次乘法产生的进位
for (int i = 0; i < la; i++) {
for (int j = 0; j < lb; j++) {
f = a[i] * b[j]; //处理逐
jw = f / 10; //位乘,记
f %= 10; //录乘积
w = i + j; //和进位
c[w] = c[w] + f; //a[i]*b[j]的结果存储到c[i+j]
c[w + 1] = c[w + 1] + jw + c[w] / 10;//处理进位
c[w] %= 10;
}
}
lc = la + lb;//找到最高的非0位
while (c[lc] == 0)lc--;
if (lc < 0) {
printf("0\n");
} else for (int i = lc; i >= 0; i--) {
printf("%d", c[i]);
}
return 0;
}
四、高精度除法
#include<bits/stdc++.h>
using namespace std;
#define maxx 1145
char sa[maxx], sb[maxx];
int la, lb, lc, jw, f, w, a[maxx], b[maxx], c[maxx * maxx];
int main() {
scanf("%s", sa);
scanf("%s", sb);
la = strlen(sa);
lb = strlen(sb);
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
for (int i = 0; i < la; i++) {
a[la - i - 1] = sa[i] - '0';
}
for (int i = 0; i < lb; i++) {
b[lb - i - 1] = sb[i] - '0';
}
jw = 0;//存储每一次乘法产生的进位
for (int i = 0; i < la; i++) {
for (int j = 0; j < lb; j++) {
f = a[i] * b[j]; //处理逐
jw = f / 10; //位乘,记
f %= 10; //录乘积
w = i + j; //和进位
c[w] = c[w] + f; //a[i]*b[j]的结果存储到c[i+j]
c[w + 1] = c[w + 1] + jw + c[w] / 10;//处理进位
c[w] %= 10;
}
}
lc = la + lb;//找到最高的非0位
while (c[lc] == 0)lc--;
if (lc < 0) {
printf("0\n");
} else for (int i = lc; i >= 0; i--) {
printf("%d", c[i]);
}
return 0;
}
最后
祝大家国庆快乐!!!
参考自
https://blog.csdn.net/hejx0412/article/details/123667293
https://baike.baidu.com/item/%E9%AB%98%E7%B2%BE%E5%BA%A6%E7%AE%97%E6%B3%95/1024900?fr=aladdin
本文来自博客园,作者:I'm_江河湖海,转载请注明原文链接:https://www.cnblogs.com/jhhh/p/16760628.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)