Project

General

Profile

Download (5.17 KB) Statistics
| Branch: | Tag: | Revision:

#ifndef FIXED_H_
#define FIXED_H_

#include <cmath>
#include <cstdint>
#include <limits>
#include <type_traits>

template <typename IntegerType, typename FractionalType>
class fixed
{
static_assert(std::is_integral<IntegerType>::value, "IntegerType must be an integral type");
static_assert(std::is_integral<FractionalType>::value, "FractionalType must be an integral type");
static_assert(std::is_signed<IntegerType>::value, "IntegerType must be a signed type");
static_assert(std::is_unsigned<FractionalType>::value, "FractionalType must be an unsigned type");
public:

static constexpr size_t integer_bits = sizeof(IntegerType) * 8;
static constexpr size_t fractional_bits = sizeof(FractionalType) * 8;
static constexpr size_t integer_decimal_digits = std::floor(std::log10(std::numeric_limits<IntegerType>::max()));
static constexpr size_t fractional_decimal_digits = std::floor(std::log10(std::numeric_limits<FractionalType>::max()));
static constexpr size_t MAX_INTEGER_VALUE = (static_cast<uint64_t>(std::pow(10, integer_decimal_digits)) - 1);
static constexpr size_t MIN_INTEGER_VALUE = 0;
static constexpr size_t MAX_FRACTIONAL_VALUE = (static_cast<uint64_t>(std::pow(10, fractional_decimal_digits)) - 1);
static constexpr size_t MIN_FRACTIONAL_VALUE = 0;
fixed()
: m_integer(0), m_fractional(0) {}
fixed(IntegerType integerVal, FractionalType fractionalVal)
: m_integer(integerVal), m_fractional(fractionalVal) {}
// Default copy constructor, and assignment operator
fixed(const fixed&) = default;
fixed& operator=(const fixed&) = default;
void parse(const char* input)
{
}
constexpr inline fixed operator-() const noexcept = delete;
inline fixed& operator+=(const fixed& y) noexcept = delete;
inline fixed& operator-=(const fixed& y) noexcept = delete;
inline fixed& operator*=(const fixed& y) noexcept = delete;
inline fixed& operator/=(const fixed& y) noexcept = delete;
// Comparison operators
template <typename I, typename F>
friend constexpr inline bool operator==(const fixed<I, F>& x, const fixed<I, F>& y) noexcept;
template <typename I, typename F>
friend constexpr inline bool operator!=(const fixed<I, F>& x, const fixed<I, F>& y) noexcept;
template <typename I, typename F>
friend constexpr inline bool operator<(const fixed<I, F>& x, const fixed<I, F>& y) noexcept;
template <typename I, typename F>
friend constexpr inline bool operator>(const fixed<I, F>& x, const fixed<I, F>& y) noexcept;
template <typename I, typename F>
friend constexpr inline bool operator<=(const fixed<I, F>& x, const fixed<I, F>& y) noexcept;
template <typename I, typename F>
friend constexpr inline bool operator>=(const fixed<I, F>& x, const fixed<I, F>& y) noexcept;
private:

IntegerType m_integer;
FractionalType m_fractional;
};

using fixed_64_64 = fixed<int64_t, uint64_t>;

template <typename I, typename F>
constexpr inline bool operator==(const fixed<I, F>& x, const fixed<I, F>& y) noexcept
{
return (x.m_integer == y.m_integer && x.m_fractional == y.m_fractional);
}

template <typename I, typename F>
constexpr inline bool operator!=(const fixed<I, F>& x, const fixed<I, F>& y) noexcept
{
return (! x == y);
}

template <typename I, typename F>
constexpr inline bool operator<(const fixed<I, F>& x, const fixed<I, F>& y) noexcept
{
if (x.m_integer == y.m_integer)
{
return (x.m_fractional < y.m_fractional);
}
else
{
return (x.m_integer < y.m_integer);
}
return false;
}

template <typename I, typename F>
constexpr inline bool operator>(const fixed<I, F>& x, const fixed<I, F>& y) noexcept
{
if (x.m_integer == y.m_integer)
{
return (x.m_fractional > y.m_fractional);
}
else
{
return (x.m_integer > y.m_integer);
}
return false;
}

template <typename I, typename F>
constexpr inline bool operator<=(const fixed<I, F>& x, const fixed<I, F>& y) noexcept
{
if (x.m_integer == y.m_integer)
{
return (x.m_fractional <= y.m_fractional);
}
else
{
return (x.m_integer < y.m_integer);
}
return false;
}

template <typename I, typename F>
constexpr inline bool operator>=(const fixed<I, F>& x, const fixed<I, F>& y) noexcept
{
if (x.m_integer == y.m_integer)
{
return (x.m_fractional > y.m_fractional);
}
else
{
return (x.m_integer > y.m_integer);
}
return false;
}

// Addition
template <typename I, typename F>
constexpr inline fixed<I, F> operator+(const fixed<I, F>& x, const fixed<I, F>& y) noexcept = delete;

// Subtraction
template <typename I, typename F>
constexpr inline fixed<I, F> operator-(const fixed<I, F>& x, const fixed<I, F>& y) noexcept = delete;

// Multiplication
template <typename I, typename F>
constexpr inline fixed<I, F> operator*(const fixed<I, F>& x, const fixed<I, F>& y) noexcept = delete;

// Division
template <typename I, typename F>
constexpr inline fixed<I, F> operator/(const fixed<I, F>& x, const fixed<I, F>& y) noexcept = delete;


#endif // FIXED_H_
(1-1/2)