#pragma once #include #include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnarrowing" namespace ninefloat{ struct private_t{}; private_t priv; template class Q{ integer_type backend; static constexpr int degen=fractionals; constexpr Q (const integer_type value, private_t) : backend{value} {} public: constexpr Q(const Q& value) : backend{value.backend} {} template constexpr Q (const srcT value) : backend{(integer_type)(value*(1<& operator+=(const Q& oth) { backend+=oth.backend; return *this; } constexpr Q& operator-=(const Q& oth) { backend-=oth.backend; return *this; } constexpr Q& operator/=(const Q& oth) { backend*=1<::degen; backend/=oth.backend; return *this; } constexpr Q& operator*=(const Q& oth) { if constexpr(Q::degen%2==0) { backend=(backend>>(Q::degen/2))*(oth.backend>>(Q::degen/2)); }else{ backend=(backend>>(Q::degen>>1))*(oth.backend>>((Q::degen>>1)+1)); } return *this; } constexpr Q operator+(const Q& oth) { return Q{backend+oth.backend, priv}; } constexpr Q operator-(const Q& oth) { return Q{backend-oth.backend, priv}; } constexpr Q operator/(const Q& oth) { return Q{(1<::degen)*backend/oth.backend, priv}; } constexpr Q operator*(const Q& oth) { if constexpr(Q::degen%2==0) { return Q{(backend>>(Q::degen/2))*(oth.backend>>(Q::degen/2)),priv}; }else{ return Q{(backend>>(Q::degen>>1))*(oth.backend>>((Q::degen>>1)+1)),priv}; } } constexpr bool operator==(const Q& oth) { return backend == oth.backend; } constexpr bool operator!=(const Q& oth) { return backend != oth.backend; } constexpr bool operator>=(const Q& oth) { return backend >= oth.backend; } constexpr bool operator<=(const Q& oth) { return backend <= oth.backend; } constexpr bool operator>(const Q& oth) { return backend > oth.backend; } constexpr bool operator<(const Q& oth) { return backend < oth.backend; } constexpr operator float() { float n=backend; n/=(1<::degen); return n; } constexpr operator double() { double n=backend; n/=(1<::degen); return n; } }; #pragma GCC diagnostic pop }