God·Hero
2021-08-19 20:54:05
一个适用于正负高精度算法的模板(原创)
想拿就自己拿吧,省的再写高精度了。
使用方法见代码下方
struct node{
int num[10005],len;
bool Positive_and_negative_attributes,Error;
node(){//初始化
len = 1;
memset(num,0,sizeof(num));
Positive_and_negative_attributes = 1;
Error = 0;
}
/*逻辑运算部分begin*/
bool operator>(node b){
if(Positive_and_negative_attributes != b.Positive_and_negative_attributes)
return Positive_and_negative_attributes > b.Positive_and_negative_attributes;
if(Positive_and_negative_attributes == 0){
if(len > b.len)
return 0;
if(len < b.len)
return 1;
for(int i = len;i >= 1;i --){
if(num[i] > b.num[i])
return 0;
if(num[i] < b.num[i])
return 1;
}
return 0;
}
if(len > b.len)
return 1;
if(len < b.len)
return 0;
for(int i = len;i >= 1;i --){
if(num[i] > b.num[i])
return 1;
if(num[i] < b.num[i])
return 0;
}
return 0;
}
bool operator>(int b){
node c;
c = b;
if(*this > c)
return 1;
return 0;
}
bool operator<(node b){
if(Positive_and_negative_attributes != b.Positive_and_negative_attributes)
return Positive_and_negative_attributes < b.Positive_and_negative_attributes;
if(Positive_and_negative_attributes == 0){
if(len > b.len)
return 1;
if(len < b.len)
return 0;
for(int i = len;i >= 1;i --){
if(num[i] > b.num[i])
return 1;
if(num[i] < b.num[i])
return 0;
}
return 0;
}
if(len > b.len)
return 0;
if(len < b.len)
return 1;
for(int i = len;i >= 1;i --){
if(num[i] > b.num[i])
return 0;
if(num[i] < b.num[i])
return 1;
}
return 0;
}
bool operator<(int b){
node c;
c = b;
if(*this < c)
return 1;
return 0;
}
bool operator==(node b){
if(len != b.len || Positive_and_negative_attributes != b.Positive_and_negative_attributes)
return 0;
for(int i = len;i >= 1;i --)
if(num[i] != b.num[i])
return 0;
return 1;
}
bool operator==(int b){
node c;
c = b;
if(*this == c)
return 1;
return 0;
}
bool operator>=(node b){
if(*this > b || *this == b)
return 1;
return 0;
}
bool operator>=(int b){
node c;
c = b;
return *this >= c;
}
bool operator<=(node b){
if(*this < b || *this == b)
return 1;
return 0;
}
bool operator<=(int b){
node c;
c = b;
return *this <= c;
}
bool operator!=(node b){
if(*this == b)
return 0;
return 1;
}
bool operator!=(int b){
node c;
c = b;
return *this != c;
}
/*逻辑运算部分end*/
/*算数运算部分begin*/
void operator++(){
*this = *this + 1;
}
void operator++(int){
*this = *this + 1;
}
void operator--(){
*this = *this - 1;
}
void operator--(int){
*this = *this - 1;
}
void operator+=(node b){
*this = *this + b;
}
void operator+=(int b){
*this = *this + b;
}
void operator-=(node b){
*this = *this - b;
}
void operator-=(int b){
*this = *this - b;
}
void operator*=(node b){
*this = *this * b;
}
void operator*=(int b){
*this = *this * b;
}
void operator/=(node b){
*this = *this / b;
}
void operator/=(int b){
*this = *this / b;
}
void operator%=(node b){
*this = *this % b;
}
void operator%=(int b){
*this = *this % b;
}
void operator=(int b){
node c;
if(b < 0){
c.Positive_and_negative_attributes = 0;
b *= -1;
}
while(b != 0){
c.num[c.len] = b % 10;
b /= 10;
c.len ++;
}
c.rule();
*this = c;
}
node operator+(int b){
node c;
c = b;
return *this + c;
}
node operator+(node b){
node c;
if(Positive_and_negative_attributes == 0 || b.Positive_and_negative_attributes == 0){
if(Positive_and_negative_attributes == b.Positive_and_negative_attributes)
c.Positive_and_negative_attributes = 0;
else{
if(Abs() > b.Abs()){
if(Positive_and_negative_attributes == 0){
Positive_and_negative_attributes = 1;
c = b - *this;
Positive_and_negative_attributes = 0;
c.Positive_and_negative_attributes = 0;
return c;
}
else{
b.Positive_and_negative_attributes = 1;
c = *this - b;
return c;
}
}
else {
if(Positive_and_negative_attributes == 0){
Positive_and_negative_attributes = 1;
c = b - *this;
Positive_and_negative_attributes = 0;
return c;
}
else{
b.Positive_and_negative_attributes = 1;
c = b - *this;
if(c != 0)
c.Positive_and_negative_attributes = 0;
return c;
}
}
}
}
c.len = std::max(b.len,len) + 1;
for(int i = 1;i <= c.len;i ++){
c.num[i] += num[i] + b.num[i];
c.num[i + 1] = c.num[i] / 10;
c.num[i] %= 10;
}
c.rule();
return c;
}
node operator-(int b){
node c;
c = b;
return *this - c;
}
node operator-(node b){
node c,d;
if(Positive_and_negative_attributes == 0 || b.Positive_and_negative_attributes == 0){
if(b.Positive_and_negative_attributes == 0){
b.Positive_and_negative_attributes = 1;
c = *this + b;
return c;
}
Positive_and_negative_attributes = 1;
c = *this + b;
Positive_and_negative_attributes = 0;
c.Positive_and_negative_attributes = 0;
return c;
}
d = *this;
if(d < b){
c.Positive_and_negative_attributes = 0;
std::swap(d,b);
}
c.len = std::max(b.len,d.len);
for(int i = 1;i <= c.len;i ++){
if(d.num[i] < b.num[i]){
d.num[i] += 10;
d.num[i + 1] -= 1;
}
c.num[i] = d.num[i] - b.num[i];
}
c.rule();
return c;
}
node operator*(int b){
node c;
c = b;
return *this * c;
}
node operator*(node b){
node c;
if(Positive_and_negative_attributes != b.Positive_and_negative_attributes)
c.Positive_and_negative_attributes = 0;
c.len = len + b.len;
for(int i = 1;i <= len;i ++){
for(int j = 1;j <= b.len;j ++){
c.num[i + j - 1] += num[i] * b.num[j];
c.num[i + j] += c.num[i + j - 1] / 10;
c.num[i + j - 1] %= 10;
}
}
c.rule();
return c;
}
node operator/(int b){
node c;
c = b;
return *this / c;
}
node operator/(node b){
if(b == 0){
b.Error = 1;
return b;
}
node c,d,e;
e = *this;
bool flag = false,b_Positive_and_negative_attributes = b.Positive_and_negative_attributes;
int used_len;
if(Abs() < b.Abs())
return c;
e.Positive_and_negative_attributes = b.Positive_and_negative_attributes = 1;
d = e.Peek(1,b.len);used_len = b.len;
while(used_len <= e.len){
while(d < b){
if(used_len < e.len)
d = d * 10 + e.Peek(++ used_len,used_len);
else{
flag = true;
break;
}
c *= 10;
}
if(flag)
break;
while(d >= b){
d -= b;
c ++;
}
}
if(Positive_and_negative_attributes != b_Positive_and_negative_attributes)
c.Positive_and_negative_attributes = 0;
c.Reverse();
c.rule();
return c;
}
node operator%(node b){
return *this - (*this / b) * b;
}
node operator%(int b){
node c;
c = b;
return *this % c;
}
/*算数运算部分end*/
/*成员函数begin*/
node Max(node b){
if(*this > b)
return *this;
return b;
}
node Max(int b){
node c;
c = b;
return Max(c);
}
node Min(node b){
if(*this < b)
return *this;
return b;
}
node Min(int b){
node c;
c = b;
return Min(c);
}
node Abs(){
node b;
b = *this;
b.Positive_and_negative_attributes = 1;
return b;
}
node Pow(int b){
node c,d;
c = 1;
if(b == 0 && *this != 0)
return c;
if(*this == 0)
return d;
d = *this;
while(-- b)
d *= *this;
return d;
}
node Reverse(){
node b = *this;
int l = 1,r = b.len;
while(l < r){
std::swap(b.num[l],b.num[r]);
l ++;r --;
}
return b;
}
node Peek(int b,int c){
node d;
d.len = c - b + 1;
d.Positive_and_negative_attributes = Positive_and_negative_attributes;
for(int i = b;i <= c;i ++)
d.num[c - i + 1] = num[len - i + 1];
d.rule();
return d;
}
node Sqrt(){
node l,r,mid,b;
l = 0;
r = *this;
mid = (l + r) / 2;
while(l < r - 1){
b = mid.Pow(2);
if(b == *this)
break;
else if(b > *this)
r = mid;
else
l = mid;
mid = (l + r) / 2;
}
return mid;
}
void rule(){
while(len != 1 && num[len] == 0) len --;
if(len == 1 && num[1] == 0)
Positive_and_negative_attributes = 1;
}
bool Prime(){
if(*this == 1 || (*this % 2 == 0 && *this != 2))
return 0;
node c,d;
d = Sqrt();
for(c = 3;c <= d;c += 2)
if(*this % c == 0)
return 0;
return 1;
}
/*成员函数end*/
/*输入/出begin*/
void Input(){
std::string d;
std::cin >> d;
len = d.size();
if(d[0] == '-'){
Positive_and_negative_attributes = 0;
len -= 1;
for(int i = 1;i <= len;i ++)
num[len - i + 1] = d[i] - '0';
return;
}
for(int i = 0;i < len;i ++)
num[len - i] = d[i] - '0';
return;
}
void Output(){
if(Error){
printf("[Error] -> 运算过程中除数为0!\n");
return;
}
if(!Positive_and_negative_attributes)
printf("-");
for(int i = len;i >= 1;i --)
printf("%d",num[i]);
return;
}
/*输入/出end*/
};
使用方法:
#include <iostream>
#include <cstdio>
#include <cstring>
node a;
a.Input();
a.Output();
可直接使用 > / < / == / >= / <= / !=进行比较
若为真返回值为1
若为假返回值为0
调用函数:
a.Max(b);
函数作用:
返回a和b中较大的数
调用函数:
a.Min(b);
函数作用:
返回a和b中较小的数
调用函数:
a.Abs();
函数作用:
返回a的绝对值
调用函数
a.Peek(b,c);
函数作用:
1、取数a中第b个到第c个数,符号与a保持一致
例:
a -> -1234 (a的值)
b = a.Peek_front(2,3);
b -> -23 (b的值)
调用函数
a.rule()
函数作用:
1、删除前导0
2、防止-0出现
调用函数
a.Sqrt()
函数作用:
1、计算数a的算术平方根(若无法开尽,则向下取整)
例:
a -> 50 (a的值)
b = a.Sqrt();
b -> 7 (b的值)(说明: √50 ≈ 7.0710678118654752440084436210485,向下取整为7)
调用函数
a.Prime()
函数作用:
1、判断a是否是质数,若是则返回1,否则返回0
调用函数
a.Reverse()
函数作用:
1、将数a反转,若有前导0会被删除 例:
a -> 3210 (a的值)
a.Reverse();
a -> 123
调用函数
a.Pow(b)
函数作用:
1、计算数a的b次方
a / b(b可为node类型或常数类型或int类型)
1、运算结果及数不可超过10000位
2、暂不支持小数运算
3、进行运算或逻辑运算时若有int类型参数需将node类型置于int类型前面(当然你要是不信可以试试)
例:
a为node类型
b为int类型
❌ b == a 错误
✔ a == b 正确
以此类推
4、返回类函数: 返回值为操作后的结果,若无特殊说明返回值均为node类型;不会修改原数据。
修改类函数: 无返回值,在原数据的基础上进行修改。
1.1 内容:
1.增加了node类型内部>、<、==等逻辑运算
1.2 内容:
1.增加了node类型成员函数Max、Min
1.3 内容:
1.增加了node类型与int类型的单向赋值(int类型赋值给node类型)
2.增加了node类型与int类型的运算(返回值为node类型)
2.0 内容:
1.增加了node类型的除法运算(Lv.1)(除法运算目前使用了较笨的持续减法来计算商,所以效率低下,请谨慎使用)
2.增加了node类型+=、-=、*=、/=、++、--等运算符号
3.增加了node类型>=、<=、!=等逻辑运算
4.node类型与int类型全面对接
2.3 内容:
1.优化了node类型的除法运算(Lv.2)(平均运行时间较Lv.1版本大大缩减)
2.增加了node类型成员函数Peek_front、Peek_between、Peek_behind、Add_front、Add_behind、rule
优化了输出函数Output
2.4 内容:
修复了在一些版本编译器下存在无法编译的bug 3.0 内容:
1.修复 + - * / 正负性 bug
2.修复 + - * / 修改原参数 bug
3.修复Abs()修改原参数 bug
4.修复rule()负0不改为0 bug
5.增添 "除数为0警告"
6.增添新函数Sqrt()
7.增添新函数Prime()
8.增添新函数Reverse()
9.增添新函数Pow()
10.将Peek_***()函数整合为Peek()