高精度类(正式1.1)
2026-07-04 11:42:54
发布于:香港
更新内容:
· 增加int, unsigned int, unsigned long long的构造函数
· 新增自增自减函数(后置自增自减libli::bigint::operator++()不返回任何值)
· 可以隐式转换为bool
· 新增input(FILE*)和print(FILE*)函数(input(FILE*)函数会吃掉空格)
头文件bigint.h:
#ifndef BIGINT_H
#define BIGINT_H
#if __cplusplus<201103L
#define noexcept throw()
#endif
#include<cstdio>
#include<string>
namespace libli{
class bigint{
private:
std::string _data;
bool _is_neg;
void from_string(const std::string& str);
public:
bigint() noexcept;
explicit bigint(int) noexcept;
explicit bigint(long long) noexcept;
explicit bigint(unsigned int) noexcept;
explicit bigint(unsigned long long) noexcept;
explicit bigint(const char*);
explicit bigint(const std::string&);
bigint(const bigint&) noexcept;
bigint& operator=(int) noexcept;
bigint& operator=(long long) noexcept;
bigint& operator=(unsigned int) noexcept;
bigint& operator=(unsigned long long) noexcept;
bigint& operator=(const char*);
bigint& operator=(const std::string&);
bigint& operator=(const bigint&) noexcept;
#if __cplusplus>=201103L
bigint(bigint&&) noexcept;
bigint& operator=(bigint&&) noexcept;
#endif
~bigint() noexcept;
bool operator==(const bigint&) const noexcept;
bool operator!=(const bigint&) const noexcept;
bool operator<(const bigint&) const noexcept;
bool operator>(const bigint&) const noexcept;
bool operator<=(const bigint&) const noexcept;
bool operator>=(const bigint&) const noexcept;
bigint operator+(const bigint&) const noexcept;
bigint operator-(const bigint&) const noexcept;
bigint operator*(const bigint&) const noexcept;
bigint operator/(const bigint&) const;
bigint operator%(const bigint&) const;
bigint& operator+=(const bigint&) noexcept;
bigint& operator-=(const bigint&) noexcept;
bigint& operator*=(const bigint&) noexcept;
bigint& operator/=(const bigint&);
bigint& operator%=(const bigint&);
bigint& operator++() noexcept;
void operator++(int) noexcept;
bigint& operator--() noexcept;
void operator--(int) noexcept;
bigint operator+() const noexcept;
bigint operator-() const noexcept;
bigint abs(void) const noexcept;
const char* cdata(void) const noexcept;
std::string data(void) const noexcept;
bool is_zero(void) const noexcept;
bigint& input(std::FILE* =stdin);
bigint& print(std::FILE* =stdout) noexcept;
operator bool() const noexcept;
};
}
#endif
源文件bigint.cpp
#include"bigint.h"
#include<algorithm>
#include<stdexcept>
#include<climits>
#if __cplusplus<201103
#if defined(__GNUC__)||defined(__clang__)
#define thread_local __thread
#elif defined(_MSC_VER)
#define thread_local __declspec(thread)
#else
#define thread_local
#endif
#endif
namespace libli{
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
bigint::bigint() noexcept: _data("0"),_is_neg(false){
}
bigint::bigint(int value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return ;
}
if(value==INT_MIN){
_data.assign("8463847412");
_is_neg=true;
return ;
}
value=_is_neg?-value:value;
_data.clear();
while(value>0){
_data.push_back((value%10)+'0');
value/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
}
bigint::bigint(long long value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return ;
}
if(value==LLONG_MIN){
_data.assign("8085774586302733229");
_is_neg=true;
return ;
}
value=_is_neg?-value:value;
_data.clear();
while(value>0){
_data.push_back((value%10)+'0');
value/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
}
bigint::bigint(unsigned int value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return ;
}
_data.clear();
while(value>0){
_data.push_back((value%10)+'0');
value/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
}
bigint::bigint(unsigned long long value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return ;
}
_data.clear();
while(value>0){
_data.push_back((value%10)+'0');
value/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
}
bigint::bigint(const char* cstring){
from_string(std::string(cstring));
}
bigint::bigint(const std::string& string){
from_string(string);
}
bigint::bigint(const bigint& other) noexcept: _data(other._data),_is_neg(other._is_neg){
}
bigint& bigint::operator=(int value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return *this;
}
if(value==INT_MIN){
_data.assign("8463847412");
_is_neg=true;
return *this;
}
value=_is_neg?-value:value;
_data.clear();
while(value>0){
_data.push_back((value%10)+'0');
value/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
return *this;
}
bigint& bigint::operator=(long long value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return *this;
}
if(value==LLONG_MIN){
_data.assign("8085774586302733229");
_is_neg=true;
return *this;
}
unsigned long long v=_is_neg?-value:value;
_data.clear();
while(v>0){
_data.push_back((v%10)+'0');
v/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
return *this;
}
bigint& bigint::operator=(unsigned int value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return *this;
}
_data.clear();
while(value>0){
_data.push_back((value%10)+'0');
value/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
return *this;
}
bigint& bigint::operator=(unsigned long long value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return *this;
}
_data.clear();
while(value>0){
_data.push_back((value%10)+'0');
value/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
return *this;
}
bigint& bigint::operator=(const char* cstring){
from_string(std::string(cstring));
return *this;
}
bigint& bigint::operator=(const std::string& string){
from_string(string);
return *this;
}
bigint& bigint::operator=(const bigint& other) noexcept{
if(this!=&other){
_data=other._data;
_is_neg=other._is_neg;
}
return *this;
}
#if __cplusplus>=201103L
bigint::bigint(bigint&& moving) noexcept{
_data=static_cast<std::string&&>(moving._data);
_is_neg=static_cast<bool&&>(moving._is_neg);
}
bigint& bigint::operator=(bigint&& moving) noexcept{
if(this!=&moving){
_data=std::move(moving._data);
_is_neg=moving._is_neg;
moving._is_neg=false;
}
return *this;
}
#endif
bigint::~bigint() noexcept{}
bool bigint::operator==(const bigint& other) const noexcept{
return _is_neg==other._is_neg&&_data==other._data;
}
bool bigint::operator!=(const bigint& other) const noexcept{
return !(*this==other);
}
bool bigint::operator<(const bigint& other) const noexcept{
if(_is_neg!=other._is_neg){
return _is_neg;
}
if(_data.size()!=other._data.size()){
bool smaller=_data.size()<other._data.size();
return _is_neg?!smaller:smaller;
}
for(int i=(int)_data.size()-1;i>=0;i--){
if(_data[i]!=other._data[i]){
bool smaller=_data[i]<other._data[i];
return _is_neg?!smaller:smaller;
}
}
return false;
}
bool bigint::operator>(const bigint& other) const noexcept{
return other<*this&&*this!=other;
}
bool bigint::operator<=(const bigint& other) const noexcept{
return !(*this>other);
}
bool bigint::operator>=(const bigint& other) const noexcept{
return !(*this<other);
}
bigint bigint::operator+(const bigint& other) const noexcept{
if(is_zero())return other;
if(other.is_zero())return *this;
bigint result;
result._data.clear();
if(_is_neg==other._is_neg){
result._is_neg=_is_neg;
size_t len=std::max(_data.size(),other._data.size());
uint8_t carry=0;
for(size_t i=0;i<len;i++){
uint8_t a=0,b=0;
if(i<_data.size())a=static_cast<uint8_t>(_data[i]-'0');
if(i<other._data.size())b=static_cast<uint8_t>(other._data[i]-'0');
uint8_t sum=a+b+carry;
result._data.push_back((sum%10)+'0');
carry=sum/10;
}
if(carry>0)result._data.push_back(carry+'0');
}else{
bigint a=*this,b=other;
const bigint& greater=a>b?a:b;
const bigint& less=a>b?b:a;
result._is_neg=(greater==a)?_is_neg:other._is_neg;
a._is_neg=false,b._is_neg=false;
size_t len=greater._data.size();
int8_t borrow=0;
for(size_t i=0;i<len;i++){
uint8_t g=0,l=0;
if(i<greater._data.size())g=static_cast<uint8_t>(greater._data[i]-'0');
if(i<less._data.size())l=static_cast<uint8_t>(less._data[i]-'0');
g-=borrow;
borrow=0;
if(g<l){
g+=10;
borrow=1;
}
result._data.push_back((g-l)+'0');
}
}
while(!result._data.empty()&&result._data[result._data.size()-1]=='0')result._data.resize(result._data.size()-1);
if(result._data.empty()){
result._data.push_back('0');
result._is_neg=false;
}
return result;
}
bigint bigint::operator-(const bigint& other) const noexcept{
if(*this==other) return bigint(0LL);
return *this+(-other);
}
bigint bigint::operator*(const bigint& other) const noexcept{
if(is_zero()||other.is_zero())return bigint(0LL);
bigint result;
result._is_neg=_is_neg!=other._is_neg;
size_t len1=_data.size();
size_t len2=other._data.size();
result._data.assign(len1+len2,'0');
for(size_t i=0;i<len1;i++){
uint8_t a=static_cast<uint8_t>(_data[i]-'0');
uint8_t carry=0;
for(size_t j=0;j<len2||carry>0;j++){
uint8_t b=0;
if(j<len2)b=static_cast<uint8_t>(other._data[j]-'0');
uint32_t curr=(result._data[i+j]-'0')+a*b+carry;
result._data[i+j]=(curr%10)+'0';
carry=curr/10;
}
}
while(!result._data.empty()&&result._data[result._data.size()-1]=='0')result._data.resize(result._data.size()-1);
if(result._data.empty()){
result._data.push_back('0');
result._is_neg=false;
}
return result;
}
bigint bigint::operator/(const bigint& other) const{
if(other.is_zero()){
throw std::invalid_argument("");
}
bigint dividend=*this;
bigint divisor=other;
dividend._is_neg=false;
divisor._is_neg=false;
if(dividend<divisor)return bigint(0LL);
bigint quotient;
bigint current;
quotient._data.clear();
quotient._is_neg=_is_neg!=other._is_neg;
for(int i=(int)dividend._data.size()-1;i>=0;i--){
current._data.insert(current._data.begin(),dividend._data[i]);
while(!current._data.empty()&¤t._data[current._data.size()-1]=='0')
current._data.resize(current._data.size()-1);
if(current._data.empty())current._data.push_back('0');
uint8_t digit=0;
while(current>=divisor){
current=current-divisor;
digit++;
}
if(!quotient._data.empty()||digit!=0){
quotient._data.push_back(digit+'0');
}
}
if(quotient._data.empty())quotient._data="0";
std::reverse(quotient._data.begin(),quotient._data.end());
while(!quotient._data.empty()&"ient._data[quotient._data.size()-1]=='0')
quotient._data.resize(quotient._data.size()-1);
if(quotient._data.empty()){
quotient._data.push_back('0');
quotient._is_neg=false;
}
return quotient;
}
bigint bigint::operator%(const bigint& other) const{
if(other.is_zero()){
throw std::invalid_argument("");
}
bigint div=*this/other;
bigint rem=*this-div*other;
rem._is_neg=_is_neg;
while(!rem._data.empty()&&rem._data[rem._data.size()-1]=='0')rem._data.resize(rem._data.size()-1);
if(rem._data.empty()){
rem._data.push_back('0');
rem._is_neg=false;
}
return rem;
}
bigint& bigint::operator+=(const bigint& other) noexcept{
*this=*this+other;
return *this;
}
bigint& bigint::operator-=(const bigint& other) noexcept{
*this=*this-other;
return *this;
}
bigint& bigint::operator*=(const bigint& other) noexcept{
*this=*this*other;
return *this;
}
bigint& bigint::operator/=(const bigint& other){
*this=*this/other;
return *this;
}
bigint& bigint::operator++() noexcept{
*this=*this+bigint(1LL);
return *this;
}
void bigint::operator++(int) noexcept{
*this=*this+bigint(1LL);
}
bigint& bigint::operator--() noexcept{
*this=*this-bigint(1LL);
return *this;
}
void bigint::operator--(int) noexcept{
*this=*this-bigint(1LL);
}
bigint bigint::operator+() const noexcept{
return *this;
}
bigint bigint::operator-() const noexcept{
bigint res=*this;
res._is_neg=!res._is_neg;
return res;
}
bigint bigint::abs(void) const noexcept{
bigint result=bigint(_data);
result._is_neg=false;
return result;
}
const char* bigint::cdata(void) const noexcept{
static thread_local std::string result;
result=_data;
if(_is_neg)result+='-';
std::reverse(result.begin(),result.end());
return result.c_str();
}
std::string bigint::data(void) const noexcept{
static thread_local std::string result;
result=_data;
if(_is_neg)result+='-';
std::reverse(result.begin(),result.end());
return result;
}
bool bigint::is_zero(void) const noexcept{
return _data=="0";
}
bigint& bigint::input(FILE* stream){
while(true){
int chr=std::fgetc(stream);
if(!std::isspace(static_cast<unsigned char>(chr))){
std::ungetc(chr,stream);
break;
}
}
while(true){
int chr=std::fgetc(stream);
if(chr=='+') ;
else if(chr=='-') _is_neg^=true;
else{
std::ungetc(chr,stream);
break;
}
}
while(true){
int chr=std::fgetc(stream);
if(chr==EOF||std::isspace(static_cast<int>(chr))) break;
else if(std::isdigit(chr)) _data.push_back(static_cast<char>(chr));
else{
std::ungetc(chr,stream);
break;
}
}
std::reverse(_data.begin(),_data.end());
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.assign("0");
_is_neg=false;
}
return *this;
}
bigint& bigint::print(FILE* stream) noexcept{
if(_is_neg) std::fputc(static_cast<int>('-'),stream);
std::string::size_type len=_data.size();
for(std::string::size_type i=len-1;~i;i--)
std::fputc(static_cast<int>(_data[i]),stream);
return *this;
}
bigint::operator bool() const noexcept{
return !is_zero();
}
void bigint::from_string(const std::string& str){
if(str.empty()) throw std::invalid_argument("");
_data.clear();
std::string::const_iterator it=str.begin();
for(;it!=str.end();it++){
if(*it=='+') ;
else if(*it=='-') _is_neg^=true;
else break;
}
if(it==str.end()){
_data.assign("0");
_is_neg=false;
return ;
}
for(;it!=str.end();it++){
if(*it<'0'||*it>'9') throw std::invalid_argument("");
_data.push_back(*it);
}
while(!_data.empty()&&_data[_data.size()-1]=='0')_data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
}
}
#if __cplusplus<201303L
#undef noexcept
#undef thread_local
#endif
懒人包
#ifndef BIGINT_H
#define BIGINT_H
#if __cplusplus<201103L
#define noexcept throw()
#endif
#include<cstdio>
#include<string>
namespace libli{
class bigint{
private:
std::string _data;
bool _is_neg;
void from_string(const std::string& str);
public:
bigint() noexcept;
explicit bigint(int) noexcept;
explicit bigint(long long) noexcept;
explicit bigint(unsigned int) noexcept;
explicit bigint(unsigned long long) noexcept;
explicit bigint(const char*);
explicit bigint(const std::string&);
bigint(const bigint&) noexcept;
bigint& operator=(int) noexcept;
bigint& operator=(long long) noexcept;
bigint& operator=(unsigned int) noexcept;
bigint& operator=(unsigned long long) noexcept;
bigint& operator=(const char*);
bigint& operator=(const std::string&);
bigint& operator=(const bigint&) noexcept;
#if __cplusplus>=201103L
bigint(bigint&&) noexcept;
bigint& operator=(bigint&&) noexcept;
#endif
~bigint() noexcept;
bool operator==(const bigint&) const noexcept;
bool operator!=(const bigint&) const noexcept;
bool operator<(const bigint&) const noexcept;
bool operator>(const bigint&) const noexcept;
bool operator<=(const bigint&) const noexcept;
bool operator>=(const bigint&) const noexcept;
bigint operator+(const bigint&) const noexcept;
bigint operator-(const bigint&) const noexcept;
bigint operator*(const bigint&) const noexcept;
bigint operator/(const bigint&) const;
bigint operator%(const bigint&) const;
bigint& operator+=(const bigint&) noexcept;
bigint& operator-=(const bigint&) noexcept;
bigint& operator*=(const bigint&) noexcept;
bigint& operator/=(const bigint&);
bigint& operator%=(const bigint&);
bigint& operator++() noexcept;
void operator++(int) noexcept;
bigint& operator--() noexcept;
void operator--(int) noexcept;
bigint operator+() const noexcept;
bigint operator-() const noexcept;
bigint abs(void) const noexcept;
const char* cdata(void) const noexcept;
std::string data(void) const noexcept;
bool is_zero(void) const noexcept;
bigint& input(std::FILE* =stdin);
bigint& print(std::FILE* =stdout) noexcept;
operator bool() const noexcept;
};
}
#include<algorithm>
#include<stdexcept>
#include<climits>
#if __cplusplus<201103
#if defined(__GNUC__)||defined(__clang__)
#define thread_local __thread
#elif defined(_MSC_VER)
#define thread_local __declspec(thread)
#else
#define thread_local
#endif
#endif
namespace libli{
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
bigint::bigint() noexcept: _data("0"),_is_neg(false){
}
bigint::bigint(int value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return ;
}
if(value==INT_MIN){
_data.assign("8463847412");
_is_neg=true;
return ;
}
value=_is_neg?-value:value;
_data.clear();
while(value>0){
_data.push_back((value%10)+'0');
value/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
}
bigint::bigint(long long value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return ;
}
if(value==LLONG_MIN){
_data.assign("8085774586302733229");
_is_neg=true;
return ;
}
value=_is_neg?-value:value;
_data.clear();
while(value>0){
_data.push_back((value%10)+'0');
value/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
}
bigint::bigint(unsigned int value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return ;
}
_data.clear();
while(value>0){
_data.push_back((value%10)+'0');
value/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
}
bigint::bigint(unsigned long long value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return ;
}
_data.clear();
while(value>0){
_data.push_back((value%10)+'0');
value/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
}
bigint::bigint(const char* cstring){
from_string(std::string(cstring));
}
bigint::bigint(const std::string& string){
from_string(string);
}
bigint::bigint(const bigint& other) noexcept: _data(other._data),_is_neg(other._is_neg){
}
bigint& bigint::operator=(int value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return *this;
}
if(value==INT_MIN){
_data.assign("8463847412");
_is_neg=true;
return *this;
}
value=_is_neg?-value:value;
_data.clear();
while(value>0){
_data.push_back((value%10)+'0');
value/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
return *this;
}
bigint& bigint::operator=(long long value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return *this;
}
if(value==LLONG_MIN){
_data.assign("8085774586302733229");
_is_neg=true;
return *this;
}
unsigned long long v=_is_neg?-value:value;
_data.clear();
while(v>0){
_data.push_back((v%10)+'0');
v/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
return *this;
}
bigint& bigint::operator=(unsigned int value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return *this;
}
_data.clear();
while(value>0){
_data.push_back((value%10)+'0');
value/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
return *this;
}
bigint& bigint::operator=(unsigned long long value) noexcept{
_is_neg=value<0;
if(value==0){
_data.assign("0");
return *this;
}
_data.clear();
while(value>0){
_data.push_back((value%10)+'0');
value/=10;
}
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
return *this;
}
bigint& bigint::operator=(const char* cstring){
from_string(std::string(cstring));
return *this;
}
bigint& bigint::operator=(const std::string& string){
from_string(string);
return *this;
}
bigint& bigint::operator=(const bigint& other) noexcept{
if(this!=&other){
_data=other._data;
_is_neg=other._is_neg;
}
return *this;
}
#if __cplusplus>=201103L
bigint::bigint(bigint&& moving) noexcept{
_data=static_cast<std::string&&>(moving._data);
_is_neg=static_cast<bool&&>(moving._is_neg);
}
bigint& bigint::operator=(bigint&& moving) noexcept{
if(this!=&moving){
_data=std::move(moving._data);
_is_neg=moving._is_neg;
moving._is_neg=false;
}
return *this;
}
#endif
bigint::~bigint() noexcept{}
bool bigint::operator==(const bigint& other) const noexcept{
return _is_neg==other._is_neg&&_data==other._data;
}
bool bigint::operator!=(const bigint& other) const noexcept{
return !(*this==other);
}
bool bigint::operator<(const bigint& other) const noexcept{
if(_is_neg!=other._is_neg){
return _is_neg;
}
if(_data.size()!=other._data.size()){
bool smaller=_data.size()<other._data.size();
return _is_neg?!smaller:smaller;
}
for(int i=(int)_data.size()-1;i>=0;i--){
if(_data[i]!=other._data[i]){
bool smaller=_data[i]<other._data[i];
return _is_neg?!smaller:smaller;
}
}
return false;
}
bool bigint::operator>(const bigint& other) const noexcept{
return other<*this&&*this!=other;
}
bool bigint::operator<=(const bigint& other) const noexcept{
return !(*this>other);
}
bool bigint::operator>=(const bigint& other) const noexcept{
return !(*this<other);
}
bigint bigint::operator+(const bigint& other) const noexcept{
if(is_zero())return other;
if(other.is_zero())return *this;
bigint result;
result._data.clear();
if(_is_neg==other._is_neg){
result._is_neg=_is_neg;
size_t len=std::max(_data.size(),other._data.size());
uint8_t carry=0;
for(size_t i=0;i<len;i++){
uint8_t a=0,b=0;
if(i<_data.size())a=static_cast<uint8_t>(_data[i]-'0');
if(i<other._data.size())b=static_cast<uint8_t>(other._data[i]-'0');
uint8_t sum=a+b+carry;
result._data.push_back((sum%10)+'0');
carry=sum/10;
}
if(carry>0)result._data.push_back(carry+'0');
}else{
bigint a=*this,b=other;
const bigint& greater=a>b?a:b;
const bigint& less=a>b?b:a;
result._is_neg=(greater==a)?_is_neg:other._is_neg;
a._is_neg=false,b._is_neg=false;
size_t len=greater._data.size();
int8_t borrow=0;
for(size_t i=0;i<len;i++){
uint8_t g=0,l=0;
if(i<greater._data.size())g=static_cast<uint8_t>(greater._data[i]-'0');
if(i<less._data.size())l=static_cast<uint8_t>(less._data[i]-'0');
g-=borrow;
borrow=0;
if(g<l){
g+=10;
borrow=1;
}
result._data.push_back((g-l)+'0');
}
}
while(!result._data.empty()&&result._data[result._data.size()-1]=='0')result._data.resize(result._data.size()-1);
if(result._data.empty()){
result._data.push_back('0');
result._is_neg=false;
}
return result;
}
bigint bigint::operator-(const bigint& other) const noexcept{
if(*this==other) return bigint(0LL);
return *this+(-other);
}
bigint bigint::operator*(const bigint& other) const noexcept{
if(is_zero()||other.is_zero())return bigint(0LL);
bigint result;
result._is_neg=_is_neg!=other._is_neg;
size_t len1=_data.size();
size_t len2=other._data.size();
result._data.assign(len1+len2,'0');
for(size_t i=0;i<len1;i++){
uint8_t a=static_cast<uint8_t>(_data[i]-'0');
uint8_t carry=0;
for(size_t j=0;j<len2||carry>0;j++){
uint8_t b=0;
if(j<len2)b=static_cast<uint8_t>(other._data[j]-'0');
uint32_t curr=(result._data[i+j]-'0')+a*b+carry;
result._data[i+j]=(curr%10)+'0';
carry=curr/10;
}
}
while(!result._data.empty()&&result._data[result._data.size()-1]=='0')result._data.resize(result._data.size()-1);
if(result._data.empty()){
result._data.push_back('0');
result._is_neg=false;
}
return result;
}
bigint bigint::operator/(const bigint& other) const{
if(other.is_zero()){
throw std::invalid_argument("");
}
bigint dividend=*this;
bigint divisor=other;
dividend._is_neg=false;
divisor._is_neg=false;
if(dividend<divisor)return bigint(0LL);
bigint quotient;
bigint current;
quotient._data.clear();
quotient._is_neg=_is_neg!=other._is_neg;
for(int i=(int)dividend._data.size()-1;i>=0;i--){
current._data.insert(current._data.begin(),dividend._data[i]);
while(!current._data.empty()&¤t._data[current._data.size()-1]=='0')
current._data.resize(current._data.size()-1);
if(current._data.empty())current._data.push_back('0');
uint8_t digit=0;
while(current>=divisor){
current=current-divisor;
digit++;
}
if(!quotient._data.empty()||digit!=0){
quotient._data.push_back(digit+'0');
}
}
if(quotient._data.empty())quotient._data="0";
std::reverse(quotient._data.begin(),quotient._data.end());
while(!quotient._data.empty()&"ient._data[quotient._data.size()-1]=='0')
quotient._data.resize(quotient._data.size()-1);
if(quotient._data.empty()){
quotient._data.push_back('0');
quotient._is_neg=false;
}
return quotient;
}
bigint bigint::operator%(const bigint& other) const{
if(other.is_zero()){
throw std::invalid_argument("");
}
bigint div=*this/other;
bigint rem=*this-div*other;
rem._is_neg=_is_neg;
while(!rem._data.empty()&&rem._data[rem._data.size()-1]=='0')rem._data.resize(rem._data.size()-1);
if(rem._data.empty()){
rem._data.push_back('0');
rem._is_neg=false;
}
return rem;
}
bigint& bigint::operator+=(const bigint& other) noexcept{
*this=*this+other;
return *this;
}
bigint& bigint::operator-=(const bigint& other) noexcept{
*this=*this-other;
return *this;
}
bigint& bigint::operator*=(const bigint& other) noexcept{
*this=*this*other;
return *this;
}
bigint& bigint::operator/=(const bigint& other){
*this=*this/other;
return *this;
}
bigint& bigint::operator++() noexcept{
*this=*this+bigint(1LL);
return *this;
}
void bigint::operator++(int) noexcept{
*this=*this+bigint(1LL);
}
bigint& bigint::operator--() noexcept{
*this=*this-bigint(1LL);
return *this;
}
void bigint::operator--(int) noexcept{
*this=*this-bigint(1LL);
}
bigint bigint::operator+() const noexcept{
return *this;
}
bigint bigint::operator-() const noexcept{
bigint res=*this;
res._is_neg=!res._is_neg;
return res;
}
bigint bigint::abs(void) const noexcept{
bigint result=bigint(_data);
result._is_neg=false;
return result;
}
const char* bigint::cdata(void) const noexcept{
static thread_local std::string result;
result=_data;
if(_is_neg)result+='-';
std::reverse(result.begin(),result.end());
return result.c_str();
}
std::string bigint::data(void) const noexcept{
static thread_local std::string result;
result=_data;
if(_is_neg)result+='-';
std::reverse(result.begin(),result.end());
return result;
}
bool bigint::is_zero(void) const noexcept{
return _data=="0";
}
bigint& bigint::input(FILE* stream){
while(true){
int chr=std::fgetc(stream);
if(!std::isspace(static_cast<unsigned char>(chr))){
std::ungetc(chr,stream);
break;
}
}
while(true){
int chr=std::fgetc(stream);
if(chr=='+') ;
else if(chr=='-') _is_neg^=true;
else{
std::ungetc(chr,stream);
break;
}
}
while(true){
int chr=std::fgetc(stream);
if(chr==EOF||std::isspace(static_cast<int>(chr))) break;
else if(std::isdigit(chr)) _data.push_back(static_cast<char>(chr));
else{
std::ungetc(chr,stream);
break;
}
}
std::reverse(_data.begin(),_data.end());
while(!_data.empty()&&_data[_data.size()-1]=='0') _data.resize(_data.size()-1);
if(_data.empty()){
_data.assign("0");
_is_neg=false;
}
return *this;
}
bigint& bigint::print(FILE* stream) noexcept{
if(_is_neg) std::fputc(static_cast<int>('-'),stream);
std::string::size_type len=_data.size();
for(std::string::size_type i=len-1;~i;i--)
std::fputc(static_cast<int>(_data[i]),stream);
return *this;
}
bigint::operator bool() const noexcept{
return !is_zero();
}
void bigint::from_string(const std::string& str){
if(str.empty()) throw std::invalid_argument("");
_data.clear();
std::string::const_iterator it=str.begin();
for(;it!=str.end();it++){
if(*it=='+') ;
else if(*it=='-') _is_neg^=true;
else break;
}
if(it==str.end()){
_data.assign("0");
_is_neg=false;
return ;
}
for(;it!=str.end();it++){
if(*it<'0'||*it>'9') throw std::invalid_argument("");
_data.push_back(*it);
}
while(!_data.empty()&&_data[_data.size()-1]=='0')_data.resize(_data.size()-1);
if(_data.empty()){
_data.push_back('0');
_is_neg=false;
}
}
}
#if __cplusplus<201303L
#undef noexcept
#undef thread_local
#endif
#endif
这里空空如也




















有帮助,赞一个