| @ -0,0 +1,156 @@ | |||||
| #pragma once | |||||
| #include <type_traits> | |||||
| #include <iostream> | |||||
| #pragma GCC diagnostic push | |||||
| #pragma GCC diagnostic ignored "-Wnarrowing" | |||||
| namespace ninefloat{ | |||||
| struct private_t{}; | |||||
| private_t priv; | |||||
| template<class integer_type, int fractionals> | |||||
| 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<integer_type,fractionals>& value) | |||||
| : backend{value.backend} | |||||
| {} | |||||
| template<class srcT> | |||||
| constexpr Q (const srcT value) | |||||
| : backend{(integer_type)(value*(1<<degen))} | |||||
| {} | |||||
| constexpr Q () | |||||
| : backend{0} | |||||
| {} | |||||
| constexpr bool is_negative() | |||||
| { | |||||
| return backend&(1<<(sizeof(backend)-1)); | |||||
| } | |||||
| constexpr integer_type data() | |||||
| { | |||||
| return backend; | |||||
| } | |||||
| constexpr bool is_positive() | |||||
| { | |||||
| return !is_negative(); | |||||
| } | |||||
| constexpr Q<integer_type, fractionals>& operator+=(const Q& oth) | |||||
| { | |||||
| backend+=oth.backend; | |||||
| return *this; | |||||
| } | |||||
| constexpr Q<integer_type, fractionals>& operator-=(const Q& oth) | |||||
| { | |||||
| backend-=oth.backend; | |||||
| return *this; | |||||
| } | |||||
| constexpr Q<integer_type, fractionals>& operator/=(const Q& oth) | |||||
| { | |||||
| backend*=1<<Q<integer_type, fractionals>::degen; | |||||
| backend/=oth.backend; | |||||
| return *this; | |||||
| } | |||||
| constexpr Q<integer_type, fractionals>& operator*=(const Q& oth) | |||||
| { | |||||
| if constexpr(Q<integer_type, fractionals>::degen%2==0) | |||||
| { | |||||
| backend=(backend>>(Q<integer_type, fractionals>::degen/2))*(oth.backend>>(Q<integer_type, fractionals>::degen/2)); | |||||
| }else{ | |||||
| backend=(backend>>(Q<integer_type, fractionals>::degen>>1))*(oth.backend>>((Q<integer_type, fractionals>::degen>>1)+1)); | |||||
| } | |||||
| return *this; | |||||
| } | |||||
| constexpr Q<integer_type, fractionals> operator+(const Q& oth) | |||||
| { | |||||
| return Q{backend+oth.backend, priv}; | |||||
| } | |||||
| constexpr Q<integer_type, fractionals> operator-(const Q& oth) | |||||
| { | |||||
| return Q{backend-oth.backend, priv}; | |||||
| } | |||||
| constexpr Q<integer_type, fractionals> operator/(const Q& oth) | |||||
| { | |||||
| return Q{(1<<Q<integer_type, fractionals>::degen)*backend/oth.backend, priv}; | |||||
| } | |||||
| constexpr Q<integer_type, fractionals> operator*(const Q& oth) | |||||
| { | |||||
| if constexpr(Q<integer_type, fractionals>::degen%2==0) | |||||
| { | |||||
| return Q{(backend>>(Q<integer_type, fractionals>::degen/2))*(oth.backend>>(Q<integer_type, fractionals>::degen/2)),priv}; | |||||
| }else{ | |||||
| return Q{(backend>>(Q<integer_type, fractionals>::degen>>1))*(oth.backend>>((Q<integer_type, fractionals>::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<<Q<integer_type, fractionals>::degen); | |||||
| return n; | |||||
| } | |||||
| constexpr operator double() | |||||
| { | |||||
| double n=backend; | |||||
| n/=(1<<Q<integer_type, fractionals>::degen); | |||||
| return n; | |||||
| } | |||||
| }; | |||||
| #pragma GCC diagnostic pop | |||||
| } | |||||