|  | @@ -4,6 +4,8 @@
 | 
	
		
			
				|  |  |  #include <cinttypes>
 | 
	
		
			
				|  |  |  #include <cmath>
 | 
	
		
			
				|  |  |  #include <utility>
 | 
	
		
			
				|  |  | +#include <array>
 | 
	
		
			
				|  |  | +#include <vector>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  struct Fixed128
 | 
	
		
			
				|  |  |  {
 | 
	
	
		
			
				|  | @@ -99,11 +101,11 @@ struct Fixed128
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  public:
 | 
	
		
			
				|  |  |      inline Fixed128 operator * (const Fixed128& other) const {
 | 
	
		
			
				|  |  | -        if (isNegative()) {
 | 
	
		
			
				|  |  | +        if (this->operator!=(Fixed128{ 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF }) && isNegative()) {
 | 
	
		
			
				|  |  |              return -(other * this->operator-());
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          if (other.isNegative()) {
 | 
	
		
			
				|  |  | -            return -(*this * (-other));
 | 
	
		
			
				|  |  | +            return -((-other) * (*this));
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          auto [uuc, uu] = mulu64(upper, other.upper);
 | 
	
		
			
				|  |  |          auto [ulc, ul] = mulu64(upper, other.lower);
 | 
	
	
		
			
				|  | @@ -331,12 +333,86 @@ private:
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  public:
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    Fixed128 operator / (const Fixed128& other) {
 | 
	
		
			
				|  |  | +    inline Fixed128 operator / (const Fixed128& other) {
 | 
	
		
			
				|  |  | +        if (this->operator!=(Fixed128{ 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF }) && isNegative()) {
 | 
	
		
			
				|  |  | +            return -((-(*this)) / other);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        if (other != Fixed128{ 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF } && other.isNegative()) {
 | 
	
		
			
				|  |  | +            return -((*this) / (-other));
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        using u256 = std::array<uint64_t, 4>;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        u256 bigDividend = { upper, lower, 0, 0 };
 | 
	
		
			
				|  |  | +        u256 bigDivisor = { 0, 0, other.upper, other.lower };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        auto twice = [] (u256& x) {
 | 
	
		
			
				|  |  | +            bool carry = false;
 | 
	
		
			
				|  |  | +            for (int i = 3; i >= 0; i--) {
 | 
	
		
			
				|  |  | +                bool oldCarry = carry;
 | 
	
		
			
				|  |  | +                carry = x[i] & 0x1000000000000000ULL;
 | 
	
		
			
				|  |  | +                x[i] <<= 1;
 | 
	
		
			
				|  |  | +                if (oldCarry) x[i] ++;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        auto geq = [] (const u256& a, const u256& b) -> bool {
 | 
	
		
			
				|  |  | +            for (int i = 0; i < 4; i++) {
 | 
	
		
			
				|  |  | +                if (a[i] > b[i])
 | 
	
		
			
				|  |  | +                    return true;
 | 
	
		
			
				|  |  | +                if (a[i] < b[i])
 | 
	
		
			
				|  |  | +                    return false;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            return true;
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        auto sub = [] (u256& a, const u256& b) -> bool {
 | 
	
		
			
				|  |  | +            bool carry = false;
 | 
	
		
			
				|  |  | +            for (int i = 3; i >= 0; i--) {
 | 
	
		
			
				|  |  | +                uint64_t oldA = a[i];
 | 
	
		
			
				|  |  | +                a[i] -= b[i];
 | 
	
		
			
				|  |  | +                carry = oldA < a[i];
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            return carry;
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        auto add = [] (u256& a, const u256& b) -> bool {
 | 
	
		
			
				|  |  | +            bool carry = false;
 | 
	
		
			
				|  |  | +            for (int i = 3; i >= 0; i--) {
 | 
	
		
			
				|  |  | +                uint64_t oldA = a[i];
 | 
	
		
			
				|  |  | +                a[i] += b[i];
 | 
	
		
			
				|  |  | +                carry = oldA > a[i];
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            return carry;
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        u256 growingCount = { 0, 0, 0, 1 };
 | 
	
		
			
				|  |  | +        u256 quotient = { 0, 0, 0, 0 };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        std::vector<u256> growingStack = { bigDivisor };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        while (true) {
 | 
	
		
			
				|  |  | +            u256 beforeSub = bigDividend;
 | 
	
		
			
				|  |  | +            const u256& gr = growingStack[growingStack.size() - 1];
 | 
	
		
			
				|  |  | +            if (!sub(bigDividend, gr)) {
 | 
	
		
			
				|  |  | +                add(quotient, growingCount);
 | 
	
		
			
				|  |  | +                u256 tw = gr; twice(tw);
 | 
	
		
			
				|  |  | +                growingStack.push_back(tw);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            else if (geq(bigDivisor, bigDividend)) {
 | 
	
		
			
				|  |  | +                break;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            else {
 | 
	
		
			
				|  |  | +                bigDividend = beforeSub;
 | 
	
		
			
				|  |  | +                growingStack.pop_back();
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        return Fixed128{ quotient[2], quotient[3] };
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      bool isNegative(void) const {
 | 
	
		
			
				|  |  | -        return (upper & (uint64_t(1) << 63)) != 0;
 | 
	
		
			
				|  |  | +        return upper >> 63;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      operator double(void) const {
 |