目录
1.什么是高精度算法
2.高精度加法
3.高精度减法
4.高精度乘法
5.高精度除法 (高精度除以低精度)
6.高精度阶乘(n个低精度数相乘)
1.什么是高精度算法
高精度算法(High Accuracy Algorithm)是处理大数字的数学计算方法。在一般的科学计算中,会经常算到小数点后几百位或者更多,当然也可能是几千亿几百亿的大数字。一般这类数字统称为高精度数,高精度算法是用计算机对于超大数据的一种模拟加,减,乘,除,乘方,阶乘,开方等运算。对于非常庞大无法在计算机中正常存储的数字,将这个数字拆开,拆成一位一位或者是四位四位的存储到一个数组中, 用一个数组去表示一个数字,这样这个数字就被称为是高精度数。高精度算法就是能处理高精度数各种运算的算法,但又因其特殊性,故从普通数的算法中分离,自成一家。
(***下面的讲解分布于注释和图片中***)
2.高精度加法
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
string s1, s2;
int a[N], b[N], c[N];
int main()
{
cin >> s1 >> s2;
int j = 1, k = 1;//a、b数组的下标都是从1开始的
for (int i = s1.size() - 1; i >= 0; i--) a[j++] = s1[i] - '0';//size()函数返回字符串中字符的数量
//字符串的索引是从0开始,s1.size()计算出字符串s1最后一个字符的索引(倒序输入)
//size()是std::string类的一个成员函数,用点运算符进行访问
for (int i = s2.size() - 1; i >= 0; i--) b[k++] = s2[i] - '0';
int ma = max(s1.size(), s2.size());//计算两个输入数字字符串的最大长度ma,确定后续计算的循环次数
int ans = 0;//用于存储每一位相加时的进位
for (int i = 1; i <= ma; i++)
{
ans = ans + (a[i] + b[i]);
c[i] = ans % 10;
ans = ans / 10;
}
if (ans) c[++ma] = ans;//**一定要注意最高位是否还有进位
for (int i = ma; i >= 1; i--)//倒序输出
{
cout << c[i];
}
return 0;
}
3.高精度减法
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5 + 10;
string s1, s2;
int a[N], b[N], c[N], flag = 0;
int main()
{
cin >> s1 >> s2;
if (s1.size() < s2.size() || s1.size() == s2.size() && atoi(s1.c_str()) < atoi(s2.c_str()))
//这个判断是用来s1和s2哪个字符串更大的。atoi(s1.c_str())将s1字符串转化成数字进行比较
/*
atoi是 C/C++ 标准库中的一个函数,
它的全称为 “ASCII to integer”,
主要功能是将字符串转换为整数。
这个函数定义在<stdlib.h>头文件中(在 C++ 中也可以使用<cstdlib>)。
它会扫描字符串参数的起始部分,
跳过前面的空白字符(如空格、制表符、换行符等),
直到遇到第一个非空白字符。
然后,它会尝试将从这个字符开始的连续数字字符序列转换为一个整数。
如果字符串的第一个非空白字符不是有效的数字字符或者字符串为空,atoi函数会返回 0。
*/
/*
在 C/C++ 中,atoi函数的语法格式为int atoi(const char* str);。
它接受一个参数str,这个参数是一个指向以'\0'结尾的字符数组(C 风格字符串)的指针。
函数返回值是转换后的整数。
*/
/*
std::string成员函数c_str()。
这个函数返回一个指向以'\0'结尾的字符数组(C 风格字符串)的指针,
这个指针可以作为参数传递给atoi函数。
*/
{
flag = 1;//表示结果为负
swap(s1, s2);//交换s1,s2,保证s1始终是最大的字符串。
}
int j = 1, k = 1;//a,b下标从1开始
for (int i = s1.size() - 1; i >= 0; i--) a[j++] = s1[i] - '0';
for (int i = s2.size() - 1; i >= 0; i--) b[k++] = s2[i] - '0';
int ma = max(s1.size(), s2.size());//ma用来存最大长度的字符串个数
for (int i = 1; i <= ma; i++)
{
if (a[i] - b[i] < 0)//需要借位
{
a[i] = a[i] + 10;
a[i + 1] = a[i + 1] - 1;
}
c[i] = a[i] - b[i];
}
while (c[ma] == 0 && ma > 1) ma--;//前导0的处理,至少保留一位数字
if (flag == 1) printf("-");//负数的判断
for (int i = ma; i >= 1; i--)//
{
cout << c[i];
}
return 0;
}
4.高精度乘法
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e6 + 10;
string s1, s2;
int a[N], b[N], s[N], c[N];
int main()
{
cin >> s1 >> s2;
int j = 1, k = 1;
for (int i = s1.size() - 1; i >= 0; i--) a[j++] = s1[i] - '0';
for (int i = s2.size() - 1; i >= 0; i--) b[k++] = s2[i] - '0';
for (int i = 1; i <= s1.size(); i++)
{
for (int j = 1; j <= s2.size(); j++)
{
s[i + j - 1] += a[i] * b[j];//单个数组逐一相乘
}
}
int ma = s1.size() + s2.size() - 1;//记录一下最高位数
int ans = 0;
for (int i = 1; i <= ma; i++)//高精度算法的核心
{
ans = ans + s[i];
c[i] = ans % 10;
ans = ans / 10;
}
if (ans) c[++ma] = ans;//考虑进位的情况
while (c[ma] == 0 && ma > 1) ma--;//前导0的处理
for (int i = ma; i >= 1; i--)
{
cout << c[i];
}
return 0;
}
5.高精度除法 (高精度除以低精度)
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e6 + 10;
string s1;
int a[N], x, c[N];
int main()
{
cin >> s1 >> x;//x为低精度
int j = 1;
for (int i = s1.size() - 1; i >= 0; i--) a[j++] = s1[i] - '0';
int ma = s1.size(), ans = 0;
for (int i = ma; i >= 1; i--)//除法的核心运算
{
ans = ans * 10 + a[i];//上一位数*10加到下一位
c[i] = ans / x;
ans = ans % x;
}
while (c[ma] == 0 && ma > 1) ma--;//前导0的处理
for (int i = ma; i >= 1; i--)
{
cout << c[i];
}
cout << endl << ans;//余数的输出
return 0;
}
6.高精度阶乘(n个低精度数相乘)
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 1e6 + 10;
int n, a[N], ans, x, m, d;
int main()
{
while (cin >> n)//每次读取一个 n 后,就会计算 n!
/*
不断从标准输入读取整数 n,
直到输入结束
(例如在终端中使用特定的结束输入方式,
如在 Windows 下按 Ctrl + Z 然后回车,
在 Linux 下按 Ctrl + D)
*/
{
a[0] = 1, d = 1;//d用于记录当前存储在 a 数组中的大整数的位数
for (int i = 1; i <= n; i++)//从1开始一直乘到本数;
{
x = 0;//x 用于存储乘法运算中的进位。
for (int j = 0; j < d; j++)//几位就循环几次
{
ans = a[j] * i + x;//每一位乘上i,加上余数后所得的数
a[j] = ans % 10;//把最后一位给数组,其他的向前进
x = ans / 10;//把ans的最后一位数去掉
}
while (x != 0)//用while把x分配到各个高位,如果 x 不为 0,说明还有进位需要处理
{
a[d++] = x % 10;//每进一位位数加一
x = x / 10;
}
}
for (int i = d - 1; i >= 0; i--)
{
cout << a[i];//存放从后向前存放,输出就要倒序输出
}
cout << endl;
}
return 0;
}
***新人博主创作不易,希望大家多多点赞关注呀~