Skip to content

Instantly share code, notes, and snippets.

@thecompez
Last active November 30, 2025 11:01
Show Gist options
  • Select an option

  • Save thecompez/90cbf5109baaa98f6b3e3eb6dd032395 to your computer and use it in GitHub Desktop.

Select an option

Save thecompez/90cbf5109baaa98f6b3e3eb6dd032395 to your computer and use it in GitHub Desktop.
export module uint256;
import <array>;
import <iostream>;
import <string>;
import <algorithm>;
/**
* @brief uint256 class.
*
* Fully supports addition, subtraction, multiplication, division and modulus.
* Stores the number as 4 uint64_t parts (little-endian).
*/
export class uint256 {
public:
std::array<uint64_t, 4> parts{}; // 4*64 = 256 bits
// Constructors
constexpr uint256() = default;
constexpr uint256(uint64_t low) : parts{low,0,0,0} {}
constexpr uint256(const std::array<uint64_t,4>& p) : parts(p) {}
// Addition
constexpr uint256 operator+(const uint256& other) const {
uint256 result{};
uint64_t carry = 0;
for(size_t i = 0; i < 4; ++i) {
__uint128_t sum = static_cast<__uint128_t>(parts[i]) + other.parts[i] + carry;
result.parts[i] = static_cast<uint64_t>(sum);
carry = static_cast<uint64_t>(sum >> 64);
}
return result;
}
// Subtraction (assumes *this >= other)
constexpr uint256 operator-(const uint256& other) const {
uint256 result{};
uint64_t borrow = 0;
for(size_t i = 0; i < 4; ++i) {
__uint128_t diff = static_cast<__uint128_t>(parts[i]) - other.parts[i] - borrow;
result.parts[i] = static_cast<uint64_t>(diff);
borrow = (diff >> 127) & 1;
}
return result;
}
// Multiplication (full uint256 * uint256)
uint256 operator*(const uint256& other) const {
uint256 result{};
for(size_t i = 0; i < 4; ++i) {
uint64_t carry = 0;
for(size_t j = 0; j + i < 4; ++j) {
__uint128_t prod = static_cast<__uint128_t>(parts[i]) * other.parts[j]
+ result.parts[i+j] + carry;
result.parts[i+j] = static_cast<uint64_t>(prod);
carry = static_cast<uint64_t>(prod >> 64);
}
}
return result;
}
// Comparison operators
constexpr bool operator==(const uint256& other) const { return parts == other.parts; }
constexpr bool operator!=(const uint256& other) const { return !(*this == other); }
constexpr bool operator<(const uint256& other) const {
for(int i=3;i>=0;--i) if(parts[i] != other.parts[i]) return parts[i]<other.parts[i];
return false;
}
constexpr bool operator>(const uint256& other) const { return other < *this; }
constexpr bool operator<=(const uint256& other) const { return !(*this>other); }
constexpr bool operator>=(const uint256& other) const { return !(*this<other); }
// Division and modulus (long division)
std::pair<uint256,uint256> divmod(const uint256& divisor) const {
if(divisor==uint256{}) throw std::runtime_error("Division by zero");
uint256 quotient{};
uint256 remainder{};
for(int i=255;i>=0;--i) {
remainder <<= 1;
remainder.parts[0] |= (bit_at(i) ? 1 : 0);
if(remainder >= divisor) {
remainder = remainder - divisor;
set_bit(quotient, i);
}
}
return {quotient,remainder};
}
uint256 operator/(const uint256& divisor) const { return divmod(divisor).first; }
uint256 operator%(const uint256& divisor) const { return divmod(divisor).second; }
// Shift left
uint256& operator<<=(unsigned n) {
if(n>=256){ parts.fill(0); return *this; }
unsigned q=n/64, r=n%64;
if(q) { for(int i=3;i>=0;--i) parts[i] = (i>=q ? parts[i-q]:0); }
if(r) {
uint64_t prev=0;
for(int i=0;i<4;i++){
uint64_t tmp=parts[i];
parts[i] = (tmp<<r) | prev;
prev = (r ? tmp>>(64-r) : 0);
}
}
return *this;
}
uint256 operator<<(unsigned n) const { uint256 res=*this; res<<=n; return res; }
// Print
void print() const {
if(*this==uint256{}) { std::cout<<"0\n"; return; }
uint256 temp=*this;
std::string s;
while(temp!=uint256{}) { s=char('0'+temp.divmod10())+s; }
std::cout<<s<<"\n";
}
private:
uint64_t divmod10() {
__uint128_t r=0;
for(int i=3;i>=0;--i){
__uint128_t current = (r<<64)|parts[i];
parts[i]=static_cast<uint64_t>(current/10);
r=current%10;
}
return static_cast<uint64_t>(r);
}
bool bit_at(int pos) const {
int idx=pos/64;
int offset=pos%64;
return (parts[idx]>>offset)&1;
}
void set_bit(uint256& n,int pos) const {
int idx=pos/64;
int offset=pos%64;
n.parts[idx]|=(1ull<<offset);
}
};
// Overload << for ostream
export std::ostream& operator<<(std::ostream& os,const uint256& val){
val.print(); return os;
}
usage:
import uint256;
auto main() ->int {
// Initial wallet balance — already large
uint256 balance({5'000'000'000ULL, 0, 0, 0}); // 5B units (e.g. tokens, credits)
// Incoming payments
uint256 deposit1({2'000'000'000ULL, 0, 0, 0});
uint256 deposit2({750'000'000ULL, 0, 0, 0});
balance = balance + deposit1;
balance = balance + deposit2;
// System applies daily reward multiplier (interest-like growth)
uint256 growth({3,0,0,0}); // x3 growth multiplier
balance = balance * growth;
// Fees (withdrawal or network processing)
uint256 networkFee({1'250'000ULL, 0, 0, 0});
balance = balance - networkFee;
std::cout << "================ WALLET REPORT ================\n";
std::cout << "Final Wallet Balance: " << balance << "\n";
std::cout << "================================================\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment