|
|
- #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}
- {{std::cout<<value<< " : "<<backend<<std::endl;}}
-
- public:
- template<class srcT>
- constexpr Q (const srcT value)
- : backend{(integer_type)(value*(1<<degen))}
- {std::cout<<value<< " : "<<backend<<std::endl;}
-
-
- bool constexpr is_negative()
- {
- return backend&(1<<(sizeof(backend)-1));
- }
-
-
- integer_type constexpr data()
- {
- return backend;
- }
-
- bool constexpr is_positive()
- {
- return !is_negative();
- }
-
- Q constexpr operator+=(const Q& oth)
- {
- backend+=oth.backend;
- return this;
- }
-
- Q constexpr operator-=(const Q& oth)
- {
- backend-=oth.backend;
- return this;
- }
-
- Q constexpr operator/=(const Q& oth)
- {
- backend*=1<<Q<integer_type, fractionals>::degen;
- backend/=oth.backend;
- return this;
- }
-
- Q constexpr 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;
- }
-
- Q constexpr operator+(const Q& oth)
- {
- return Q{backend+oth.backend, priv};
- }
-
- Q constexpr operator-(const Q& oth)
- {
- return Q{backend-oth.backend, priv};
- }
-
- Q constexpr operator/(const Q& oth)
- {
- return Q{(1<<Q<integer_type, fractionals>::degen)*backend/oth.backend, priv};
- }
-
- Q constexpr 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};
- }
- }
-
- bool constexpr operator==(const Q& oth)
- {
- return backend == oth.backend;
- }
-
- bool constexpr operator!=(const Q& oth)
- {
- return backend != oth.backend;
- }
-
- bool constexpr operator>=(const Q& oth)
- {
- return backend >= oth.backend;
- }
-
- bool constexpr operator<=(const Q& oth)
- {
- return backend <= oth.backend;
- }
-
- bool constexpr operator>(const Q& oth)
- {
- return backend > oth.backend;
- }
-
- bool constexpr 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
-
- }
|