Skip to content

Instantly share code, notes, and snippets.

@ciniml
Created February 1, 2020 06:01
Show Gist options
  • Save ciniml/c2f969596524ad1bab748e7193179222 to your computer and use it in GitHub Desktop.
Save ciniml/c2f969596524ad1bab748e7193179222 to your computer and use it in GitHub Desktop.
simple C++ fixed point type
#ifndef FIXEDPOINT_HPP_
#define FIXEDPOINT_HPP_
#include <stdint.h>
template<typename TBaseIntegral, std::size_t TFractionBits>
class fixedpoint
{
private:
TBaseIntegral value;
public:
typedef fixedpoint<TBaseIntegral, TFractionBits> self_type;
explicit fixedpoint(TBaseIntegral baseIntegral) : value(baseIntegral) {}
fixedpoint(TBaseIntegral integerPart, TBaseIntegral fractionPart) : value((integerPart << TFractionBits) | fractionPart) {}
fixedpoint(const self_type& base) : value(base.value) {}
template<std::size_t TOtherBits>
fixedpoint(const fixedpoint<TBaseIntegral, TOtherBits>& base)
{
if (TOtherBits <= TFractionBits)
{
this->value = base.value << (TFractionBits - TOtherBits);
}
else
{
this->value = base.value >> (TOtherBits - TFractionBits);
}
}
operator TBaseIntegral() const { return this->value; }
TBaseIntegral getIntegerPart() const { return this->value >> TFractionBits; }
TBaseIntegral getFractionPart() const { return this->value & (((TBaseIntegral)1 << TFractionBits) - 1); }
self_type operator+(const self_type& rhs) { return self_type(this->value + rhs.value); }
self_type operator-(const self_type& rhs) { return self_type(this->value - rhs.value); }
template<std::size_t TOtherBits> self_type operator+(const fixedpoint<TBaseIntegral, TOtherBits>& rhs) { return *this + self_type(rhs); }
template<std::size_t TOtherBits> self_type operator-(const fixedpoint<TBaseIntegral, TOtherBits>& rhs) { return *this - self_type(rhs); }
template<std::size_t TOtherBits> self_type operator*(const fixedpoint<TBaseIntegral, TOtherBits>& rhs) { return self_type((this->value * rhs.value) >> TOtherBits); }
template<std::size_t TOtherBits> self_type operator/(const fixedpoint<TBaseIntegral, TOtherBits>& rhs) { return self_type((this->value << TOtherBits) / rhs.value); }
};
// Predefined signed fixed point real number
typedef fixedpoint<int32_t, 2> fixedpoint32_2_t;
typedef fixedpoint<int32_t, 4> fixedpoint32_4_t;
typedef fixedpoint<int32_t, 8> fixedpoint32_8_t;
typedef fixedpoint<int32_t, 16> fixedpoint32_16_t;
// Predefined unsigned fixed point real number
typedef fixedpoint<uint32_t, 2> ufixedpoint32_2_t;
typedef fixedpoint<uint32_t, 4> ufixedpoint32_4_t;
typedef fixedpoint<uint32_t, 8> ufixedpoint32_8_t;
typedef fixedpoint<uint32_t, 16> ufixedpoint32_16_t;
#endif // FIXEDPOINT_HPP_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment