As you know, in [this](https://codeforces.net/blog/entry/126654) reason, 64-bit C++ compilers are temporarily disabled.↵
↵
In order to keep using __int128 (at least partially) in 32-bit compilers, I'm trying writing a template of the **unsigned** version of __int128.↵
↵
**UPD**:↵
↵
2024/3/14: added (maybe) all operators that an __int128 has except for `operator/` / fixed infinite-recursion bug in several operators↵
↵
Here's it (not completed yet):↵
↵
<spoiler summary="integer_128_impl.cpp">↵
↵
~~~~~↵
#include<tuple>↵
#include<iostream>↵
#include<climits>↵
↵
namespace RedshiftShine{↵
↵
using ll=unsigned long long;↵
const ll ulmx=ULLONG_MAX;↵
const ll shift=3264;↵
↵
ll min(ll x,ll y){↵
return x<y?x:y;↵
}↵
↵
ll max(ll x,ll y){↵
return x>y?x:y;↵
}↵
↵
bool detect_overflow_add(ll x,ll y){↵
return x+y<min(x,y);↵
}↵
↵
bool detect_overflow_minus(ll x,ll y){↵
return x-y>max(x,y);↵
}↵
↵
class Custom_Unsigned_int128{↵
private:↵
ll higherInt,lowerInt;↵
public:↵
Custom_Unsigned_int128(){}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128(_Tp x):↵
higherInt(0),↵
lowerInt(x){}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128(_Tp x,_Tp y):↵
higherInt(x),↵
lowerInt(y){}↵
↵
Custom_Unsigned_int128↵
(const Custom_Unsigned_int128& ele):↵
higherInt(ele.higherInt),↵
lowerInt(ele.lowerInt){}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator=(const _Tp& x){↵
higherInt=0;↵
lowerInt=x;↵
}↵
↵
Custom_Unsigned_int128↵
operator=(const Custom_Unsigned_int128& x){↵
higherInt=x.higherInt;↵
lowerInt=x.lowerInt;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator+(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt+↵
detect_overflow_add(lowerInt,x),↵
lowerInt+x↵
};↵
}↵
↵
Custom_Unsigned_int128↵
operator+(const Custom_Unsigned_int128& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt+x.higherInt+↵
detect_overflow_add(lowerInt,x.lowerInt),↵
lowerInt+x.lowerInt↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator-(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt-↵
detect_overflow_minus(lowerInt,x),↵
lowerInt-xstd::pair<ll,ll>↵
base_access(){↵
return std::pair<ll,ll>{↵
higherInt,↵
lowerInt↵
};↵
}↵
↵
Custom_Unsigned_int128&↵
operator=(const Custom_Unsigned_int128& x){↵
higherInt=x.higherInt,↵
lowerInt=x.lowerInt;↵
return *this;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator=(const _Tp& x){↵
*this=Custom_Unsigned_int128↵
{↵
0,x↵
};↵
return *this;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator+(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt+↵
detect_overflow_add(lowerInt,x),↵
lowerInt+x↵
};↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator+(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return Custom_Unsigned_int128↵
{↵
ele.higherInt+↵
detect_overflow_add(ele.lowerInt,x),↵
ele.lowerInt+x↵
};↵
}↵
↵
Custom_Unsigned_int128↵
operator+(const Custom_Unsigned_int128& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt+x.higherInt+↵
detect_overflow_add(lowerInt,x.lowerInt),↵
lowerInt+x.lowerInt↵
};↵
}↵
↵
template<typename _Tp>↵
bool↵
operator==(const _Tp& x)const{↵
return ↵
(↵
!higherInt and ↵
lowerInt==x↵
);↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator==(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return ele==x;↵
}↵
↵
bool↵
operator==(const Custom_Unsigned_int128& x)const{↵
return ↵
(↵
higherInt==x.higherInt and ↵
lowerInt==x.lowerInt↵
);↵
}↵
↵
template<typename _Tp>↵
bool↵
operator!=(const _Tp& x)const{↵
return !(*this==x);↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator!=(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return !(ele==x);↵
}↵
↵
template<typename _Tp>↵
bool↵
operator<(const _Tp& x)const{↵
return ↵
(↵
!higherInt and ↵
lowerInt<x↵
);↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator<(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return ele<x;↵
}↵
↵
bool↵
operator<(const Custom_Unsigned_int128& x)const{↵
return ↵
(↵
higherInt<x.higherInt or ↵
(↵
higherInt==x.higherInt and ↵
lowerInt<x.lowerInt↵
)↵
);↵
}↵
↵
template<typename _Tp>↵
bool↵
operator<=(const _Tp& x)const{↵
return ↵
(↵
*this<x or ↵
*this==x↵
);↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator<=(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return ele<=x;↵
}↵
↵
bool↵
operator<=(const Custom_Unsigned_int128& x)const{↵
return ↵
(↵
*this<x or ↵
*this==x↵
);↵
}↵
↵
template<typename _Tp>↵
bool↵
operator>(const _Tp& x)const{↵
return ↵
!(↵
*this<=x↵
);↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator>(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return !(ele<=x);↵
}↵
↵
bool↵
operator>(const Custom_Unsigned_int128& x)const{↵
return ↵
!(↵
*this<=x↵
);↵
}↵
↵
template<typename _Tp>↵
bool↵
operator>=(const _Tp& x)const{↵
return ↵
!(↵
*this<x↵
);↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator>=(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return !(ele<x);↵
}↵
↵
bool↵
operator>=(const Custom_Unsigned_int128& x)const{↵
return ↵
!(↵
*this<x↵
);↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator+=(const _Tp& x){↵
return *this=*this+x;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator-(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt-↵
detect_overflow_minus(lowerInt,x),↵
lowerInt-x↵
};↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator-(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return Custom_Unsigned_int128↵
{↵
-ele.higherInt+↵
detect_overflow_minus(x,ele.lowerInt),↵
x-ele.lowerInt↵
};↵
}↵
↵
Custom_Unsigned_int128↵
operator-(const Custom_Unsigned_int128& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt-x.higherInt-↵
detect_overflow_minus(lowerInt,x.lowerInt),↵
lowerInt-x.lowerInt↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator-=(const _Tp& x){↵
return *this=*this-x;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator&(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt,↵
lowerInt&x↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
friend operator&(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return Custom_Unsigned_int128↵
{↵
ele.higherInt,↵
ele.lowerInt&x↵
};↵
}↵
↵
Custom_Unsigned_int128↵
operator&(const Custom_Unsigned_int128& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt&x.higherInt,↵
lowerInt&x.lowerInt↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator&=(const _Tp& x){↵
return *this=*this&x;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator|(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt,↵
lowerInt|x↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
friend operator|(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return Custom_Unsigned_int128↵
{↵
ele.higherInt,↵
ele.lowerInt|x↵
};↵
}↵
↵
Custom_Unsigned_int128↵
operator|(const Custom_Unsigned_int128& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt|x.higherInt,↵
lowerInt|x.lowerInt↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator|=(const _Tp& x){↵
return *this=*this|x;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator^(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt,↵
lowerInt^x↵
};↵
}↵
↵
Custom_Unsigned_int128↵
operator^(const Custom_Unsigned_int128& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt^x.higherInt,↵
lowerInt^x.lowerInt↵
};↵
}↵
↵
};↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
friend operator^(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return Custom_Unsigned_int128↵
{↵
ele.higherInt,↵
ele.lowerInt^x↵
};↵
}↵
↵
Custom_Unsigned_int128↵
operator^(const Custom_Unsigned_int128& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt^x.higherInt,↵
lowerInt^x.lowerInt↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator^=(const _Tp& x){↵
return *this=*this^x;↵
}↵
↵
Custom_Unsigned_int128↵
operator~(){↵
return Custom_Unsigned_int128{↵
~higherInt,↵
~lowerInt↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator<<(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt<<x|(lowerInt>>(shift-x)),↵
lowerInt<<x↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator<<=(const _Tp& x){↵
return *this=*this<<x;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator>>(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt>>x,↵
lowerInt>>x|(higherInt<<(shift-x))↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator>>=(const _Tp& x){↵
return *this=*this>>x;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator*(const _Tp& x)const{↵
Custom_Unsigned_int128 ret(0),pr(*this);↵
_Tp tm(x);↵
for(;tm;tm>>=1){↵
if(tm&1)ret+=pr;↵
pr+=pr;↵
}↵
return ret;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
friend operator*(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return ele*x;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator*=(const _Tp& x){↵
return *this=*this*x;↵
}↵
↵
};↵
↵
}↵
↵
void test(){↵
RedshiftShine::Custom_Unsigned_int128 ci(1,1);↵
auto [a,b]=ci.base_access();↵
std::printf("%llu %llu\n",a,b);↵
}↵
↵
int main(){↵
test();↵
}↵
~~~~~↵
↵
↵
</spoiler>↵
↵
Hope it helps.
↵
In order to keep using __int128 (at least partially) in 32-bit compilers, I'm trying writing a template of the **unsigned** version of __int128.↵
↵
**UPD**:↵
↵
2024/3/14: added (maybe) all operators that an __int128 has except for `operator/` / fixed infinite-recursion bug in several operators↵
↵
Here's it (not completed yet):↵
↵
<spoiler summary="integer_128_impl.cpp">↵
↵
~~~~~↵
#include<tuple>↵
#include<iostream>↵
#include<climits>↵
↵
namespace RedshiftShine{↵
↵
using ll=unsigned long long;↵
const ll ulmx=ULLONG_MAX;↵
const ll shift=
↵
ll min(ll x,ll y){↵
return x<y?x:y;↵
}↵
↵
ll max(ll x,ll y){↵
return x>y?x:y;↵
}↵
↵
bool detect_overflow_add(ll x,ll y){↵
return x+y<min(x,y);↵
}↵
↵
bool detect_overflow_minus(ll x,ll y){↵
return x-y>max(x,y);↵
}↵
↵
class Custom_Unsigned_int128{↵
private:↵
ll higherInt,lowerInt;↵
public:↵
Custom_Unsigned_int128(){}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128(_Tp x):↵
higherInt(0),↵
lowerInt(x){}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128(_Tp x,_Tp y):↵
higherInt(x),↵
lowerInt(y){}↵
↵
Custom_Unsigned_int128↵
(const Custom_Unsigned_int128& ele):↵
higherInt(ele.higherInt),↵
lowerInt(ele.lowerInt){}↵
↵
Custom_Unsigned_int128↵
operator=(const _Tp& x){↵
higherInt=0;↵
lowerInt=x;↵
}↵
↵
Custom_Unsigned_int128↵
operator=(const Custom_Unsigned_int128& x){↵
higherInt=x.higherInt;↵
lowerInt=x.lowerInt;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator+(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt+↵
detect_overflow_add(lowerInt,x),↵
lowerInt+x↵
};↵
}↵
↵
Custom_Unsigned_int128↵
operator+(const Custom_Unsigned_int128& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt+x.higherInt+↵
detect_overflow_add(lowerInt,x.lowerInt),↵
lowerInt+x.lowerInt↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator-(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt-↵
detect_overflow_minus(lowerInt,x),↵
lowerInt-x
base_access(){↵
return std::pair<ll,ll>{↵
higherInt,↵
lowerInt↵
};↵
}↵
↵
Custom_Unsigned_int128&↵
operator=(const Custom_Unsigned_int128& x){↵
higherInt=x.higherInt,↵
lowerInt=x.lowerInt;↵
return *this;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator=(const _Tp& x){↵
*this=Custom_Unsigned_int128↵
{↵
0,x↵
};↵
return *this;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator+(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt+↵
detect_overflow_add(lowerInt,x),↵
lowerInt+x↵
};↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator+(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return Custom_Unsigned_int128↵
{↵
ele.higherInt+↵
detect_overflow_add(ele.lowerInt,x),↵
ele.lowerInt+x↵
};↵
}↵
↵
Custom_Unsigned_int128↵
operator+(const Custom_Unsigned_int128& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt+x.higherInt+↵
detect_overflow_add(lowerInt,x.lowerInt),↵
lowerInt+x.lowerInt↵
};↵
}↵
↵
template<typename _Tp>↵
bool↵
operator==(const _Tp& x)const{↵
return ↵
(↵
!higherInt and ↵
lowerInt==x↵
);↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator==(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return ele==x;↵
}↵
↵
bool↵
operator==(const Custom_Unsigned_int128& x)const{↵
return ↵
(↵
higherInt==x.higherInt and ↵
lowerInt==x.lowerInt↵
);↵
}↵
↵
template<typename _Tp>↵
bool↵
operator!=(const _Tp& x)const{↵
return !(*this==x);↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator!=(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return !(ele==x);↵
}↵
↵
template<typename _Tp>↵
bool↵
operator<(const _Tp& x)const{↵
return ↵
(↵
!higherInt and ↵
lowerInt<x↵
);↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator<(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return ele<x;↵
}↵
↵
bool↵
operator<(const Custom_Unsigned_int128& x)const{↵
return ↵
(↵
higherInt<x.higherInt or ↵
(↵
higherInt==x.higherInt and ↵
lowerInt<x.lowerInt↵
)↵
);↵
}↵
↵
template<typename _Tp>↵
bool↵
operator<=(const _Tp& x)const{↵
return ↵
(↵
*this<x or ↵
*this==x↵
);↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator<=(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return ele<=x;↵
}↵
↵
bool↵
operator<=(const Custom_Unsigned_int128& x)const{↵
return ↵
(↵
*this<x or ↵
*this==x↵
);↵
}↵
↵
template<typename _Tp>↵
bool↵
operator>(const _Tp& x)const{↵
return ↵
!(↵
*this<=x↵
);↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator>(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return !(ele<=x);↵
}↵
↵
bool↵
operator>(const Custom_Unsigned_int128& x)const{↵
return ↵
!(↵
*this<=x↵
);↵
}↵
↵
template<typename _Tp>↵
bool↵
operator>=(const _Tp& x)const{↵
return ↵
!(↵
*this<x↵
);↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator>=(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return !(ele<x);↵
}↵
↵
bool↵
operator>=(const Custom_Unsigned_int128& x)const{↵
return ↵
!(↵
*this<x↵
);↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator+=(const _Tp& x){↵
return *this=*this+x;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator-(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt-↵
detect_overflow_minus(lowerInt,x),↵
lowerInt-x↵
};↵
}↵
↵
template<typename _Tp>↵
friend Custom_Unsigned_int128↵
operator-(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return Custom_Unsigned_int128↵
{↵
-ele.higherInt+↵
detect_overflow_minus(x,ele.lowerInt),↵
x-ele.lowerInt↵
};↵
}↵
↵
Custom_Unsigned_int128↵
operator-(const Custom_Unsigned_int128& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt-x.higherInt-↵
detect_overflow_minus(lowerInt,x.lowerInt),↵
lowerInt-x.lowerInt↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator-=(const _Tp& x){↵
return *this=*this-x;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator&(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt,↵
lowerInt&x↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
friend operator&(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return Custom_Unsigned_int128↵
{↵
ele.higherInt,↵
ele.lowerInt&x↵
};↵
}↵
↵
Custom_Unsigned_int128↵
operator&(const Custom_Unsigned_int128& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt&x.higherInt,↵
lowerInt&x.lowerInt↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator&=(const _Tp& x){↵
return *this=*this&x;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator|(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt,↵
lowerInt|x↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
friend operator|(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return Custom_Unsigned_int128↵
{↵
ele.higherInt,↵
ele.lowerInt|x↵
};↵
}↵
↵
Custom_Unsigned_int128↵
operator|(const Custom_Unsigned_int128& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt|x.higherInt,↵
lowerInt|x.lowerInt↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator|=(const _Tp& x){↵
return *this=*this|x;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator^(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt,↵
lowerInt^x↵
};↵
}↵
↵
operator^(const Custom_Unsigned_int128& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt^x.higherInt,↵
lowerInt^x.lowerInt↵
};↵
}↵
↵
};↵
Custom_Unsigned_int128↵
friend operator^(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return Custom_Unsigned_int128↵
{↵
ele.higherInt,↵
ele.lowerInt^x↵
};↵
}↵
↵
Custom_Unsigned_int128↵
operator^(const Custom_Unsigned_int128& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt^x.higherInt,↵
lowerInt^x.lowerInt↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator^=(const _Tp& x){↵
return *this=*this^x;↵
}↵
↵
Custom_Unsigned_int128↵
operator~(){↵
return Custom_Unsigned_int128{↵
~higherInt,↵
~lowerInt↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator<<(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt<<x|(lowerInt>>(shift-x)),↵
lowerInt<<x↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator<<=(const _Tp& x){↵
return *this=*this<<x;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator>>(const _Tp& x){↵
return Custom_Unsigned_int128↵
{↵
higherInt>>x,↵
lowerInt>>x|(higherInt<<(shift-x))↵
};↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator>>=(const _Tp& x){↵
return *this=*this>>x;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
operator*(const _Tp& x)const{↵
Custom_Unsigned_int128 ret(0),pr(*this);↵
_Tp tm(x);↵
for(;tm;tm>>=1){↵
if(tm&1)ret+=pr;↵
pr+=pr;↵
}↵
return ret;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128↵
friend operator*(const _Tp& x,const Custom_Unsigned_int128& ele){↵
return ele*x;↵
}↵
↵
template<typename _Tp>↵
Custom_Unsigned_int128&↵
operator*=(const _Tp& x){↵
return *this=*this*x;↵
}↵
↵
};↵
↵
}↵
↵
void test(){↵
RedshiftShine::Custom_Unsigned_int128 ci(1,1);↵
auto [a,b]=ci.base_access();↵
std::printf("%llu %llu\n",a,b);↵
}↵
↵
int main(){↵
test();↵
}↵
~~~~~↵
↵
↵
</spoiler>↵
↵
Hope it helps.