绝大部分来自@代号4101的 这篇博客
随更新可能部分描述失效
第一个轮子~
现支持
1. 高精度加减乘除及 mod 运算
2. 单精度除法
3. 小范围下按位右移
4. 高精度直接输入输出
5. 字符串 / Long long 转 高精度格式
6. 自动压位及去前缀0还有一大堆有的没的玩意儿
2017.8.6. Updata
1. 支持较小范围下右移运算 ( 卡常 )
2. 支持单精度除法
#include <algorithm> // max
#include <cassert> // assert
#include <cstdio> // printf,sprintf
#include <cstring> // strlen
#include <iostream> // cin,cout
#include <string> // string类
#include <vector> // vector类
using namespace std;
struct bign {
typedef unsigned long long ULL;
static const int BASE = 100000000;
static const int WIDTH = 8;
static const int TOTDIT = 10000;//最多总共10000位
vector<int> s;
void write() {
printf("%d", s.back());
for (int i = s.size() - 2;i >= 0;-- i)
{
char buf[WIDTH + 2];
sprintf(buf,"%08d", s[i]);
for (int j = 0;j < strlen(buf);++ j) printf("%c", buf[j]);
}
}
void read() {
char buf[TOTDIT];//位数 最高位
scanf("%s", buf + 1);
s.clear();
int len = (strlen(buf + 1) - 1) / WIDTH + 1;
int num = 0,tmp = 0;
for (int i = len - 1;i >= 1;-- i)
{
int en = strlen(buf + 1) - tmp,st = en - WIDTH + 1;
tmp += WIDTH;
num = 0;
for (int i = st;i <= en;++ i)
num = num * 10 + buf[i] - '0';
s.push_back(num);
}
if (strlen(buf + 1) - tmp > 0)
{
num = 0;
int en = strlen(buf + 1) - tmp,st = 1;
for (int i = st;i <= en;++ i)
num = num * 10 + buf[i] - '0';
s.push_back(num);
}
}
bign& clean(){while(!s.back()&&s.size()>1)s.pop_back(); return *this;}
bign(ULL num = 0) {*this = num;}
bign(string s) {*this = s;}
bign& operator = (long long num) {
s.clear();
do {
s.push_back(num % BASE);
num /= BASE;
} while (num > 0);
return *this;
}
bign& operator = (const string& str) {
s.clear();
int x, len = (str.length() - 1) / WIDTH + 1;
for (int i = 0; i < len; i++) {
int end = str.length() - i*WIDTH;
int start = max(0, end - WIDTH);
sscanf(str.substr(start,end-start).c_str(), "%d", &x);
s.push_back(x);
}
return (*this).clean();
}
bign operator + (const bign& b) const {
bign c; c.s.clear();
for (int i = 0, g = 0; ; i++) {
if (g == 0 && i >= s.size() && i >= b.s.size()) break;
int x = g;
if (i < s.size()) x += s[i];
if (i < b.s.size()) x += b.s[i];
c.s.push_back(x % BASE);
g = x / BASE;
}
return c;
}
bign operator - (const bign& b) const {
assert(b <= *this); // 减数不能大于被减数
bign c; c.s.clear();
for (int i = 0, g = 0; ; i++) {
if (g == 0 && i >= s.size() && i >= b.s.size()) break;
int x = s[i] + g;
if (i < b.s.size()) x -= b.s[i];
if (x < 0) {g = -1; x += BASE;} else g = 0;
c.s.push_back(x);
}
return c.clean();
}
bign operator * (const bign& b) const {
int i, j; ULL g;
vector<ULL> v(s.size()+b.s.size(), 0);
bign c; c.s.clear();
for(i=0;i<s.size();i++) for(j=0;j<b.s.size();j++) v[i+j]+=ULL(s[i])*b.s[j];
for (i = 0, g = 0; ; i++) {
if (g ==0 && i >= v.size()) break;
ULL x = v[i] + g;
c.s.push_back(x % BASE);
g = x / BASE;
}
return c.clean();
}
bign operator >> (const int& b) const {
assert(b > 0);
ll p = (1 << b) - 1,q = p + 1;
bign c = *this;
ll m = 0;//余数
for (int i = s.size()-1; i >= 0; i--) {
m = m*BASE + s[i];
c.s[i] = (1ll * m) >> b;
m &= p;
}
return c.clean();
}
bign operator / (const int& b) const {
assert(b > 0); // 除数必须大于0
bign c = *this;
ll m = 0;//余数
for (int i = s.size()-1; i >= 0; i--) {
m = 1ll * m * BASE + s[i];
c.s[i] = 1ll * m / b;
m %= b;
}
return c.clean();
}
bign operator / (const bign& b) const {
assert(b > 0); // 除数必须大于0
bign c = *this; // 商:主要是让c.s和(*this).s的vector一样大
bign m; // 余数:初始化为0
for (int i = s.size()-1; i >= 0; i--) {
m = m*BASE + s[i];
c.s[i] = bsearch(b, m);
m -= b*c.s[i];
}
return c.clean();
}
bign operator % (const bign& b) const { //方法与除法相同
bign c = *this;
bign m;
for (int i = s.size()-1; i >= 0; i--) {
m = m*BASE + s[i];
c.s[i] = bsearch(b, m);
m -= b*c.s[i];
}
return m;
}
// 二分法找出满足bx<=m的最大的x
int bsearch(const bign& b, const bign& m) const{
int L = 0, R = BASE-1, x;
while (1) {
x = (L+R)>>1;
if (b*x<=m) {if (b*(x+1)>m) return x; else L = x;}
else R = x;
}
}
bign& operator += (const bign& b) {*this = *this + b; return *this;}
bign& operator -= (const bign& b) {*this = *this - b; return *this;}
bign& operator *= (const bign& b) {*this = *this * b; return *this;}
bign& operator /= (const bign& b) {*this = *this / b; return *this;}
bign& operator %= (const bign& b) {*this = *this % b; return *this;}
bign& operator /= (const int& b) {*this = *this / b; return *this;}
bign& operator >>= (const int& b) {*this = *this >> b; return *this;}
bool operator < (const bign& b) const {
if (s.size() != b.s.size()) return s.size() < b.s.size();
for (int i = s.size()-1; i >= 0; i--)
if (s[i] != b.s[i]) return s[i] < b.s[i];
return false;
}
bool operator >(const bign& b) const{return b < *this;}
bool operator<=(const bign& b) const{return !(b < *this);}
bool operator>=(const bign& b) const{return !(*this < b);}
bool operator!=(const bign& b) const{return b < *this || *this < b;}
bool operator==(const bign& b) const{return !(b < *this) && !(b > *this);}
};