高精度与大整数
Posted spciay
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高精度与大整数相关的知识,希望对你有一定的参考价值。
高精度与大整数
1. 高精度
1.1 加法(大数+大数)
#include <bits/stdc++.h>
using namespace std;
// 返回C = A + B
vector<int> add(vector<int> &A, vector<int> &B) // A和B存储的都是逆序
{
int t = 0; // 记录进位情况
vector<int> C; // 记录答案
for (int i = 0; i < A.size() || i < B.size(); ++i)
{
if (i < A.size() ) t += A[i]; // 如果这一位有数字
if (i < B.size()) t += B[i];
C.push_back(t % 10); // 加到这一位上
t /= 10; // 换成下一位的数字
}
if (t) C.push_back(1); // 如果有剩余,在最高位补上一
return C;
}
int main()
{
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‘); // 如果a是123,那么放入vector的顺序为321
for (int j = b.size() - 1; j >= 0; --j) B.push_back(b[j] - ‘0‘);
auto C = add(A, B);
for (int i = C.size() - 1; i >= 0; --i) cout << C[i]; // 如果答案是123,那么答案的vector C内为321
return 0;
}
1.2 减法(大数-大数)
#include <bits/stdc++.h>
using namespace std;
// A >= B:true, A<B:false
bool compare(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;
}
// C = A - B
vector <int> sub(vector<int> &A, vector<int> &B)
{
vector <int> C; // 用来存储答案
int t = 0; // 记录是否去高位借位
for (int i = 0; i < A.size(); ++i)
{
t = A[i] - t;
if (i < B.size() ) t -= B[i];
C.push_back((t + 10) % 10);
if (t < 0) t = 1; // 复原t
else t = 0;
}
while (C.size() > 1 && C.back() == 0) C.pop_back(); // 去除高位的前导0
return C;
}
int main()
{
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‘); // 如果a是123,那么放入vector的顺序为321
for (int i = b.size() - 1; i >= 0; --i) B.push_back(b[i] - ‘0‘);
vector<int> C;
if (!compare(A, B))
{
printf("-");
C = sub(B, A);
}
else C = sub (A, B);
for (int i = C.size() - 1; i >= 0; --i) // 如果答案是123,那么答案的vector C内为321
return 0;
cout << C[i];
return 0;
}
1.3 乘法(大数*小数)
#include <bits/stdc++.h>
using namespace std;
// C = A * n
vector<int> mul(vector<int> &A, int n)
{
vector<int> C; // 存储答案
int t = 0;
for (int i = 0; i < A.size() || t; ++i)
{
if (i < A.size()) t += A[i] * n;
C.push_back(t % 10); // 放入当前位的数字
t /= 10;
}
return C;
}
int main()
{
string a;
int b;
cin >> a >> b;
vector<int> A;
for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - ‘0‘); // 如果a是123,那么放入vector的顺序为321
auto C = mul(A, b);
for (int i = C.size() - 1; i >= 0; --i) // 如果答案是123,那么答案的vector C内为321
cout << C[i];
return 0;
}
1.4 除法(大数/小数)
#include <bits/stdc++.h>
using namespace std;
vector<int > div(vector<int> &A, int b, int &r)
{
r = 0; // 余数
vector<int> C; // 存储答案
for (int i = A.size() - 1; i >= 0; --i)
{
r = r * 10 + A[i];
C.push_back(r / b); // 放入除完的结果到答案中
r = r % b;
}
reverse(C.begin(), C.end()); // C一开始存储的时候是正序,改成反序
while (C.size() > 1 && C.back() == 0) C.pop_back(); // 去掉前导0
return C;
}
int main()
{
string a;
int b, r;
cin >> a >> b;
vector<int> A;
for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - ‘0‘); // 如果a是123,那么放入vector的顺序为321
auto C = div(A, b, r);
for (int i = C.size() - 1; i >= 0; --i) // 商
cout << C[i] ;
cout << endl << r << endl; // 余数
return 0;
}
2. 大整数
#include <bits/stdc++.h>
using namespace std;
//大数
struct BigInteger
{
static const int BASE = 100000000; //和WIDTH保持一致
static const int WIDTH = 8; //八位一存储,如修改记得修改输出中的%08d
bool sign; //符号, 0表示负数
size_t length; //位数
vector<int> num; //反序存
//构造函数
BigInteger(long long x = 0) { *this = x; }
BigInteger(const string &x) { *this = x; }
BigInteger(const BigInteger &x) { *this = x; }
//剪掉前导0,并且求一下数的位数
void cutLeadingZero()
{
while (num.back() == 0 && num.size() != 1)
{
num.pop_back();
}
int tmp = num.back(); // tmp是最高位
if (tmp == 0) // 最高位为0,长度为1
{
length = 1;
} // 最高位不为0
else
{
length = (num.size() - 1) * WIDTH;
while (tmp > 0)
{
length++;
tmp /= 10;
}
}
}
//赋值运算符
BigInteger &operator=(long long x)
{
num.clear();
if (x >= 0)
{
sign = true;
}
else
{
sign = false;
x = -x;
}
do
{
num.push_back(x % BASE);
x /= BASE;
} while (x > 0);
cutLeadingZero();
return *this;
}
BigInteger &operator=(const string &str)
{
num.clear();
sign = (str[0] != ‘-‘); //设置符号
int x, len = (str.size() - 1 - (!sign)) / WIDTH + 1;
for (int i = 0; i < len; i++)
{
int End = str.size() - i * WIDTH;
int start = max((int)(!sign), End - WIDTH); //防止越界
sscanf(str.substr(start, End - start).c_str(), "%d", &x);
num.push_back(x);
}
cutLeadingZero();
return *this;
}
BigInteger &operator=(const BigInteger &tmp)
{
num = tmp.num;
sign = tmp.sign;
length = tmp.length;
return *this;
}
//绝对值
BigInteger abs() const
{
BigInteger ans(*this);
ans.sign = true;
return ans;
}
//正号
const BigInteger &operator+() const { return *this; }
//负号
BigInteger operator-() const
{
BigInteger ans(*this);
if (ans != 0)
ans.sign = !ans.sign;
return ans;
}
// + 运算符
BigInteger operator+(const BigInteger &b) const
{
if (!b.sign)
{
return *this - (-b);
}
if (!sign)
{
return b - (-*this);
}
BigInteger ans;
ans.num.clear();
for (int i = 0, g = 0;; i++)
{
if (g == 0 && i >= num.size() && i >= b.num.size())
break;
int x = g;
if (i < num.size())
x += num[i];
if (i < b.num.size())
x += b.num[i];
ans.num.push_back(x % BASE);
g = x / BASE;
}
ans.cutLeadingZero();
return ans;
}
// - 运算符
BigInteger operator-(const BigInteger &b) const
{
if (!b.sign)
{
return *this + (-b);
}
if (!sign)
{
return -((-*this) + b);
}
if (*this < b)
{
return -(b - *this);
}
BigInteger ans;
ans.num.clear();
for (int i = 0, g = 0;; i++)
{
if (g == 0 && i >= num.size() && i >= b.num.size())
break;
int x = g;
g = 0;
if (i < num.size())
x += num[i];
if (i < b.num.size())
x -= b.num[i];
if (x < 0)
{
x += BASE;
g = -1;
}
ans.num.push_back(x);
}
ans.cutLeadingZero();
return ans;
}
// * 运算符
BigInteger operator*(const BigInteger &b) const
{
int lena = num.size(), lenb = b.num.size();
BigInteger ans;
for (int i = 0; i < lena + lenb; i++)
ans.num.push_back(0);
for (int i = 0, g = 0; i < lena; i++)
{
g = 0;
for (int j = 0; j < lenb; j++)
{
long long x = ans.num[i + j];
x += (long long)num[i] * (long long)b.num[j];
ans.num[i + j] = x % BASE;
g = x / BASE;
ans.num[i + j + 1] += g;
}
}
ans.cutLeadingZero();
ans.sign = (ans.length == 1 && ans.num[0] == 0) || (sign == b.sign);
return ans;
}
//*10^n 大数除大数中用到
BigInteger e(size_t n) const
{
int tmp = n % WIDTH;
BigInteger ans;
ans.length = n + 1;
n /= WIDTH;
while (ans.num.size() <= n)
ans.num.push_back(0);
ans.num[n] = 1;
while (tmp--)
ans.num[n] *= 10;
return ans * (*this);
}
// /运算符 (大数除大数)
BigInteger operator/(const BigInteger &b) const
{
BigInteger aa((*this).abs());
BigInteger bb(b.abs());
if (aa < bb)
return 0;
char *str = new char[aa.length + 1];
memset(str, 0, sizeof(char) * (aa.length + 1));
BigInteger tmp;
int lena = aa.length, lenb = bb.length;
for (int i = 0; i <= lena - lenb; i++)
{
tmp = bb.e(lena - lenb - i);
while (aa >= tmp)
{
str[i]++;
aa = aa - tmp;
}
str[i] += ‘0‘;
}
BigInteger ans(str);
delete[] str;
ans.sign = (ans == 0 || sign == b.sign);
return ans;
}
// %运算符
BigInteger operator%(const BigInteger &b) const
{
return *this - *this / b * b;
}
// ++ 运算符
BigInteger &operator++()
{
*this = *this + 1;
return *this;
}
// -- 运算符
BigInteger &operator--()
{
*this = *this - 1;
return *this;
}
// += 运算符
BigInteger &operator+=(const BigInteger &b)
{
*this = *this + b;
return *this;
}
// -= 运算符
BigInteger &operator-=(const BigInteger &b)
{
*this = *this - b;
return *this;
}
// *=运算符
BigInteger &operator*=(const BigInteger &b)
{
*this = *this * b;
return *this;
}
// /= 运算符
BigInteger &operator/=(const BigInteger &b)
{
*this = *this / b;
return *this;
}
// %=运算符
BigInteger &operator%=(const BigInteger &b)
{
*this = *this % b;
return *this;
}
// < 运算符
bool operator<(const BigInteger &b) const
{
if (sign != b.sign) //正负,负正
{
return !sign;
}
else if (!sign && !b.sign) //负负
{
return -b < -*this;
}
//正正
if (num.size() != b.num.size())
return num.size() < b.num.size();
for (int i = num.size() - 1; i >= 0; i--)
if (num[i] != b.num[i])
return num[i] < b.num[i];
return false;
}
bool operator>(const BigInteger &b) const { return b < *this; } // > 运算符
bool operator<=(const BigInteger &b) const { return !(b < *this); } // <= 运算符
bool operator>=(const BigInteger &b) const { return !(*this < b); } // >= 运算符
bool operator!=(const BigInteger &b) const { return b < *this || *this < b; } // != 运算符
bool operator==(const BigInteger &b) const { return !(b < *this) && !(*this < b); } //==运算符
// 逻辑运算符
bool operator||(const BigInteger &b) const { return *this != 0 || b != 0; } // || 运算符
bool operator&&(const BigInteger &b) const { return *this != 0 && b != 0; } // && 运算符
bool operator!() { return (bool)(*this == 0); } // ! 运算符
//重载<<使得可以直接输出大数
friend ostream &operator<<(ostream &out, const BigInteger &x)
{
if (!x.sign)
out << ‘-‘;
out << x.num.back();
for (int i = x.num.size() - 2; i >= 0; i--)
{
char buf[10];
//如WIDTH和BASR有变化,此处要修改为%0(WIDTH)d
sprintf(buf, "%08d", x.num[i]);
for (int j = 0; j < strlen(buf); j++)
out << buf[j];
}
return out;
}
//重载>>使得可以直接输入大数
friend istream &operator>>(istream &in, BigInteger &x)
{
string str;
in >> str;
size_t len = str.size();
int start = 0;
if (str[0] == ‘-‘)
start = 1;
if (str[start] == ‘ ‘)
return in;
for (int i = start; i < len; i++)
{
if (str[i] < ‘0‘ || str[i] > ‘9‘)
return in;
}
x.sign = !start;
x = str.c_str();
return in;
}
};
struct Tag
{
string name;
BigInteger num;
}tag[1100];
// 可用于sort函数
bool cmp(struct Tag a, struct Tag b)
{
return a.num > b.num;
}
int main()
{
BigInteger n;
cin >> n;
cout << n.e(3) << endl; // 返回n*(10^3)
cout << n.abs() << endl;
string a, b;
cin >> a >> b;
BigInteger c(a), d(b);
cout << c + d << endl;
if (c == 0) cout << "yes
";
return 0;
}
以上是关于高精度与大整数的主要内容,如果未能解决你的问题,请参考以下文章