Small tests i share because why not
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

156 lines
3.7 KiB

#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
}