Last active
November 30, 2025 11:01
-
-
Save thecompez/90cbf5109baaa98f6b3e3eb6dd032395 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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; } | |
| 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