///////////////////////////////////////////////////////////////////////////////////
// (C) Copyright 2007 Anthony Williams //
// //
// Distributed under the Boost Software License, Version 1.0. //
// See: http://www.boost.org/LICENSE_1_0.txt) //
// //
// Copyright (C) 2018 Edouard Griffiths, F4EXB //
// //
// Modified as fully templatized class with variable size and type internal //
// representation //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see . //
///////////////////////////////////////////////////////////////////////////////////
#ifndef SDRBASE_UTIL_FIXED_H_
#define SDRBASE_UTIL_FIXED_H_
#include
#include
#include
#include "fixedtraits.h"
// Internally 1 is 2^28. 28 is the highest power of two that can represent 9.99999... safely on 64 bits internally
unsigned const fixed_resolution_shift=28;
int64_t const fixed_resolution=1LL<
class Fixed
{
private:
IntType m_nVal;
public:
struct internal
{};
Fixed():
m_nVal(0)
{}
Fixed(internal, IntType nVal):
m_nVal(nVal)
{}
Fixed(int64_t nVal):
m_nVal(nVal << FixedTraits::fixed_resolution_shift)
{}
Fixed(int nVal):
m_nVal(int64_t(nVal) << FixedTraits::fixed_resolution_shift)
{}
Fixed(short nVal):
m_nVal(int64_t(nVal) << FixedTraits::fixed_resolution_shift)
{}
Fixed(uint64_t nVal):
m_nVal(nVal << FixedTraits::fixed_resolution_shift)
{}
Fixed(unsigned int nVal):
m_nVal(int64_t(nVal) << FixedTraits::fixed_resolution_shift)
{}
Fixed(unsigned short nVal):
m_nVal(int64_t(nVal) << FixedTraits::fixed_resolution_shift)
{}
Fixed(double nVal):
m_nVal(static_cast(nVal*static_cast(FixedTraits::fixed_resolution)))
{}
Fixed(float nVal):
m_nVal(static_cast(nVal*static_cast(FixedTraits::fixed_resolution)))
{}
template
Fixed& operator=(T other)
{
m_nVal = Fixed(other).m_nVal;
return *this;
}
Fixed& operator=(Fixed const& other)
{
m_nVal = other.m_nVal;
return *this;
}
friend bool operator==(Fixed const& lhs,Fixed const& rhs)
{
return lhs.m_nVal == rhs.m_nVal;
}
friend bool operator!=(Fixed const& lhs,Fixed const& rhs)
{
return lhs.m_nVal != rhs.m_nVal;
}
friend bool operator<(Fixed const& lhs,Fixed const& rhs)
{
return lhs.m_nVal < rhs.m_nVal;
}
friend bool operator>(Fixed const& lhs,Fixed const& rhs)
{
return lhs.m_nVal > rhs.m_nVal;
}
friend bool operator<=(Fixed const& lhs,Fixed const& rhs)
{
return lhs.m_nVal <= rhs.m_nVal;
}
friend bool operator>=(Fixed const& lhs,Fixed const& rhs)
{
return lhs.m_nVal >= rhs.m_nVal;
}
operator bool() const
{
return m_nVal?true:false;
}
inline operator double() const
{
return as_double();
}
int64_t as_internal() const
{
return m_nVal;
}
float as_float() const
{
return m_nVal/(float)fixed_resolution;
}
double as_double() const
{
return m_nVal/(double)fixed_resolution;
}
int64_t as_long() const
{
return (int64_t)(m_nVal/fixed_resolution);
}
int64_t as_int64() const
{
return m_nVal/fixed_resolution;
}
int as_int() const
{
return (int)(m_nVal/fixed_resolution);
}
uint64_t as_unsigned_long() const
{
return (uint64_t)(m_nVal/fixed_resolution);
}
uint64_t as_unsigned_int64() const
{
return (uint64_t)m_nVal/fixed_resolution;
}
unsigned int as_unsigned_int() const
{
return (unsigned int)(m_nVal/fixed_resolution);
}
short as_short() const
{
return (short)(m_nVal/fixed_resolution);
}
unsigned short as_unsigned_short() const
{
return (unsigned short)(m_nVal/fixed_resolution);
}
Fixed operator++()
{
m_nVal += fixed_resolution;
return *this;
}
Fixed operator--()
{
m_nVal -= fixed_resolution;
return *this;
}
Fixed floor() const;
Fixed ceil() const;
Fixed sqrt() const;
Fixed exp() const;
Fixed log() const;
Fixed& operator%=(Fixed const& other);
Fixed& operator*=(Fixed const& val);
Fixed& operator/=(Fixed const& val);
Fixed& operator-=(Fixed const& val)
{
m_nVal -= val.m_nVal;
return *this;
}
Fixed& operator+=(Fixed const& val)
{
m_nVal += val.m_nVal;
return *this;
}
Fixed& operator*=(double val)
{
return (*this)*=Fixed(val);
}
Fixed& operator*=(float val)
{
return (*this)*=Fixed(val);
}
Fixed& operator*=(int64_t val)
{
m_nVal*=val;
return *this;
}
Fixed& operator*=(int val)
{
m_nVal*=val;
return *this;
}
Fixed& operator*=(short val)
{
m_nVal*=val;
return *this;
}
Fixed& operator*=(char val)
{
m_nVal*=val;
return *this;
}
Fixed& operator*=(uint64_t val)
{
m_nVal*=val;
return *this;
}
Fixed& operator*=(unsigned int val)
{
m_nVal*=val;
return *this;
}
Fixed& operator*=(unsigned short val)
{
m_nVal*=val;
return *this;
}
Fixed& operator*=(unsigned char val)
{
m_nVal*=val;
return *this;
}
Fixed& operator/=(double val)
{
return (*this)/=Fixed(val);
}
Fixed& operator/=(float val)
{
return (*this)/=Fixed(val);
}
Fixed& operator/=(int64_t val)
{
m_nVal/=val;
return *this;
}
Fixed& operator/=(int val)
{
m_nVal/=val;
return *this;
}
Fixed& operator/=(short val)
{
m_nVal/=val;
return *this;
}
Fixed& operator/=(char val)
{
m_nVal/=val;
return *this;
}
Fixed& operator/=(uint64_t val)
{
m_nVal/=val;
return *this;
}
Fixed& operator/=(unsigned int val)
{
m_nVal/=val;
return *this;
}
Fixed& operator/=(unsigned short val)
{
m_nVal/=val;
return *this;
}
Fixed& operator/=(unsigned char val)
{
m_nVal/=val;
return *this;
}
bool operator!() const
{
return m_nVal==0;
}
Fixed modf(Fixed* integral_part) const;
Fixed atan() const;
static void sin_cos(Fixed const& theta,Fixed* s,Fixed*c);
static void to_polar(Fixed const& x,Fixed const& y,Fixed* r,Fixed*theta);
Fixed sin() const;
Fixed cos() const;
Fixed tan() const;
Fixed operator-() const;
Fixed abs() const;
};
/* why always as double ?
inline std::ostream& operator<<(std::ostream& os,fixed const& value)
{
return os<
inline Fixed operator-(double a, Fixed const& b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(float a, Fixed const& b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(uint64_t a, Fixed const& b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(int64_t a, Fixed const& b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(unsigned a, Fixed const& b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(int a, Fixed const& b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(unsigned short a, Fixed const& b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(short a, Fixed const& b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(unsigned char a, Fixed const& b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(char a, Fixed const& b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(Fixed const& a, double b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(Fixed const& a, float b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(Fixed const& a,uint64_t b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(Fixed const& a, int64_t b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(Fixed const& a, unsigned b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(Fixed const& a, int b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(Fixed const& a, unsigned short b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(Fixed const& a, short b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(Fixed const& a, unsigned char b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(Fixed const& a, char b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator-(Fixed const& a, Fixed const& b)
{
Fixed temp(a);
return temp -= b;
}
template
inline Fixed operator%(double a, Fixed const& b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(float a, Fixed const& b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(uint64_t a, Fixed const& b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(int64_t a, Fixed const& b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(unsigned a, Fixed const& b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(int a, Fixed const& b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(unsigned short a, Fixed const& b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(short a, Fixed const& b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(unsigned char a, Fixed const& b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(char a, Fixed const& b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(Fixed const& a,double b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(Fixed const& a, float b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(Fixed const& a, uint64_t b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(Fixed const& a, int64_t b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(Fixed const& a, unsigned b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(Fixed const& a, int b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(Fixed const& a, unsigned short b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(Fixed const& a, short b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(Fixed const& a, unsigned char b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(Fixed const& a, char b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator%(Fixed const& a, Fixed const& b)
{
Fixed temp(a);
return temp %= b;
}
template
inline Fixed operator+(double a, Fixed const& b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(float a, Fixed const& b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(uint64_t a, Fixed const& b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(int64_t a, Fixed const& b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(unsigned a, Fixed const& b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(int a, Fixed const& b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(unsigned short a, Fixed const& b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(short a, Fixed const& b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(unsigned char a, Fixed const& b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(char a, Fixed const& b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(Fixed const& a, double b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(Fixed const& a, float b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(Fixed const& a, uint64_t b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(Fixed const& a, int64_t b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(Fixed const& a, unsigned b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(Fixed const& a, int b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(Fixed const& a, unsigned short b)
{
Fixed temp(a);
return temp += b;
}
template
inline Fixed operator+(Fixed