FixMath
Public Member Functions | Static Public Member Functions | Friends | List of all members
SFix< NI, NF, RANGE > Class Template Reference

#include <FixMath.h>

Public Member Functions

constexpr SFix ()
 
constexpr SFix (float fl)
 
constexpr SFix (double fl)
 
template<typename T >
constexpr SFix (T value, bool as_raw=false)
 
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr SFix (const SFix< _NI, _NF, _RANGE > &sf)
 
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr SFix (const UFix< _NI, _NF, _RANGE > &uf)
 
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr FixMathPrivate::SFixByRange_t< FixMathPrivate::FM_max(NF, _NF), FixMathPrivate::rangeAdd(NF, _NF, RANGE, _RANGE)> operator+ (const SFix< _NI, _NF, _RANGE > &op) const
 
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr FixMathPrivate::SFixByRange_t< FixMathPrivate::FM_max(NF, _NF), FixMathPrivate::rangeAdd(NF, _NF, RANGE, _RANGE)> operator+ (const UFix< _NI, _NF, _RANGE > &op2) const
 
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr FixMathPrivate::SFixByRange_t< FixMathPrivate::FM_max(NF, _NF), FixMathPrivate::rangeAdd(NF, _NF, RANGE, _RANGE)> operator- (const SFix< _NI, _NF, _RANGE > &op) const
 
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr FixMathPrivate::SFixByRange_t< FixMathPrivate::FM_max(NF, _NF), FixMathPrivate::rangeAdd(NF, _NF, RANGE, _RANGE)> operator- (const UFix< _NI, _NF, _RANGE > &op) const
 
constexpr FixMathPrivate::SFixByRange_t< NF, RANGE+1 > operator- () const
 
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr FixMathPrivate::SFixByRange_t< NF+_NF, RANGE *_RANGE > operator* (const SFix< _NI, _NF, _RANGE > &op) const
 
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr FixMathPrivate::SFixByRange_t< NF+_NF, RANGE *_RANGE > operator* (const UFix< _NI, _NF, _RANGE > &op2) const
 
constexpr SFix< NF, NI > invFast () const
 
template<int8_t _NF>
constexpr SFix< NF, _NF > inv () const
 
constexpr SFix< NF, FixMathPrivate::FM_min(NI *2+NF, 63-NF)> invFull () const
 
template<int8_t _NF = FixMathPrivate::FM_min(NI*2+NF-1,63-NF)>
constexpr SFix< NF, _NF > invAccurate () const
 
constexpr SFix< NI, NF > operator>> (const int8_t op) const
 
template<int8_t op>
constexpr SFix< FixMathPrivate::FM_max(NI-op, 0), NF+op, FixMathPrivate::rangeShift(NI, op, RANGE)> sR ()
 
template<int8_t op>
constexpr SFix< NI+op, FixMathPrivate::FM_max(NF-op, 0), FixMathPrivate::rangeShift(NF, op, RANGE)> sL ()
 
template<int8_t _NI, int8_t _NF>
constexpr bool operator> (const SFix< _NI, _NF > &op) const
 
template<int8_t _NI, int8_t _NF>
constexpr bool operator< (const SFix< _NI, _NF > &op) const
 
template<int8_t _NI, int8_t _NF>
constexpr bool operator== (const SFix< _NI, _NF > &op) const
 
template<int8_t _NI, int8_t _NF>
constexpr bool operator!= (const SFix< _NI, _NF > &op) const
 
constexpr UFix< NI, NF, RANGE > asUFix () const
 
constexpr float asFloat () const
 
constexpr IntegerType< FixMathPrivate::sBitsToBytes(NI+1)>::signed_type asInt () const
 
constexpr internal_type asRaw () const
 

Static Public Member Functions

template<typename T >
static constexpr SFix< NI, NF > fromRaw (T raw)
 
static constexpr int8_t getNI ()
 
static constexpr int8_t getNF ()
 
static constexpr int8_t getRANGE ()
 
template<int8_t BITS>
static constexpr void assertSize ()
 

Friends

template<int8_t , int8_t , uint64_t >
class UFix
 

Detailed Description

template<int8_t NI, int8_t NF, uint64_t RANGE>
class SFix< NI, NF, RANGE >

Instanciate an signed fixed point math number.

Parameters
NIThe number of bits encoding the integer part. The integral part can range into [-2^NI, 2^NI -1]
NFThe number of bits encoding the fractional part
RANGEA purely internal parameter that keeps track of the range used by the type. Safer to not define it.
Note
The total number of the underlying int will be NI+NF+1 in order to accomodate the sign. It follows that, if you want something that reproduces the behavior of a int8_t, it should be declared as SFix<7,0>.

Constructor & Destructor Documentation

◆ SFix() [1/6]

template<int8_t NI, int8_t NF, uint64_t RANGE>
constexpr SFix< NI, NF, RANGE >::SFix ( )
inlineconstexpr

Constructor

◆ SFix() [2/6]

template<int8_t NI, int8_t NF, uint64_t RANGE>
constexpr SFix< NI, NF, RANGE >::SFix ( float  fl)
inlineconstexpr

Constructor from a floating point value.

Parameters
flFloating point value
Returns
An signed fixed point number

◆ SFix() [3/6]

template<int8_t NI, int8_t NF, uint64_t RANGE>
constexpr SFix< NI, NF, RANGE >::SFix ( double  fl)
inlineconstexpr

Constructor from a floating point value.

Parameters
flFloating point value
Returns
An signed fixed point number

◆ SFix() [4/6]

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<typename T >
constexpr SFix< NI, NF, RANGE >::SFix ( value,
bool  as_raw = false 
)
inlineconstexpr

Constructor from an integer value which can be interpreted as both a resulting fixed point math number with a fractional part equals to 0, or as a number with decimal, ie as the underlying type behind the fixed point math number.

Parameters
valueInteger value
as_raw=falsewith false value will be interpreted as an integer, with true it will be interpreted as a number with decimals.
Returns
An signed fixed point number

◆ SFix() [5/6]

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr SFix< NI, NF, RANGE >::SFix ( const SFix< _NI, _NF, _RANGE > &  sf)
inlineconstexpr

Constructor from another SFix.

Parameters
ufA signed fixed type number which value can be represented in this type.
Returns
A signed fixed type number

◆ SFix() [6/6]

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr SFix< NI, NF, RANGE >::SFix ( const UFix< _NI, _NF, _RANGE > &  uf)
inlineconstexpr

Constructor from an UFix.

Parameters
ufA unsigned fixed type number which value can be represented in this type.
Returns
A signed fixed type number

Member Function Documentation

◆ asFloat()

template<int8_t NI, int8_t NF, uint64_t RANGE>
constexpr float SFix< NI, NF, RANGE >::asFloat ( ) const
inlineconstexpr

Returns the value as floating point number.

Returns
The floating point value.

◆ asInt()

template<int8_t NI, int8_t NF, uint64_t RANGE>
constexpr IntegerType<FixMathPrivate::sBitsToBytes(NI+1)>::signed_type SFix< NI, NF, RANGE >::asInt ( ) const
inlineconstexpr

Return the integer part of the number, as a standard C type integer (int8_t, int16_t etc) depending on NI.

Note
Because numbers are stored as two's complement, this returns the closest integer towards negative values
Returns
The integer part, as a C integer type.

◆ asRaw()

template<int8_t NI, int8_t NF, uint64_t RANGE>
constexpr internal_type SFix< NI, NF, RANGE >::asRaw ( ) const
inlineconstexpr

Returns the internal integer value

Returns
the internal value

◆ assertSize()

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t BITS>
static constexpr void SFix< NI, NF, RANGE >::assertSize ( )
inlinestaticconstexpr

Check wether this number exceeds the given total size in bits. See UFix::assertSize().

Note
This function counts the number of bits needed, internally, and including the sign bit. E.g. SFix<8,0>::assertSize<8>() will fail, as it requires 9 bits, internally!

◆ asUFix()

template<int8_t NI, int8_t NF, uint64_t RANGE>
constexpr UFix<NI,NF,RANGE> SFix< NI, NF, RANGE >::asUFix ( ) const
inlineconstexpr

Returns the number as a UFix of same (positive) range and precision. The initial value has to be positive to return something correct. This is more optimized than a cast.

Returns
a UFix

◆ fromRaw()

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<typename T >
static constexpr SFix<NI,NF> SFix< NI, NF, RANGE >::fromRaw ( raw)
inlinestaticconstexpr

Set the internal value of the fixed point math number.

Parameters
rawThe new internal value.
Returns
A SFix.

◆ getNF()

template<int8_t NI, int8_t NF, uint64_t RANGE>
static constexpr int8_t SFix< NI, NF, RANGE >::getNF ( )
inlinestaticconstexpr

The number of bits used to encode the fractional part.

Returns
The number of bits used to encode the fractional part.

◆ getNI()

template<int8_t NI, int8_t NF, uint64_t RANGE>
static constexpr int8_t SFix< NI, NF, RANGE >::getNI ( )
inlinestaticconstexpr

The number of bits used to encode the integral part.

Returns
The number of bits used to encode the integral part.

◆ getRANGE()

template<int8_t NI, int8_t NF, uint64_t RANGE>
static constexpr int8_t SFix< NI, NF, RANGE >::getRANGE ( )
inlinestaticconstexpr

The (absolute) range of the integral part of the number, as far as it can be determined at compile time. The true range of the number will typically be lower than (at most the same as) this, so it is not recommended to use this in computations. Available with #define FIXMATH_DEBUG

Returns
The range of the number

◆ inv()

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t _NF>
constexpr SFix<NF,_NF> SFix< NI, NF, RANGE >::inv ( ) const
inlineconstexpr

Compute the inverse of a SFix<NI,NF>, as a SFix<NF,_NF>. _NF is the number of precision bits for the output. Can be any number but especially useful for case between invFast() (_NF=NI) and invFull() (_NF=2*NI+NF)

Returns
The inverse of the number.

◆ invAccurate()

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t _NF = FixMathPrivate::FM_min(NI*2+NF-1,63-NF)>
constexpr SFix<NF,_NF> SFix< NI, NF, RANGE >::invAccurate ( ) const
inlineconstexpr

Compute the inverse of a SFix<NI,NF>, as a SFix<NF,NI*2+NF-1> (default) or as a SFix<NF,_NF> with _NF the template parameter of invAccurate<_NF>.

Note
This uses a number of width NF+_NF+1 internally. If you are seeking for performances, you should try to aim for this number to not require a too big a type internally. For instance SFix<0,15> a; a.invAccurate<16>() will use a 64 bits internally whereas a.invAccurate<15>() will only use a 32 bits. It can be called as a.invAccurate() (default) or a.invAccurate<16> for instance.

◆ invFast()

template<int8_t NI, int8_t NF, uint64_t RANGE>
constexpr SFix<NF,NI> SFix< NI, NF, RANGE >::invFast ( ) const
inlineconstexpr

Compute the inverse of a SFix<NI,NF>, as a SFix<NF,NI> (not a typo). This inverse is able to represent accurately the inverse of the smallest and biggest of the initial number, but might lead to a lot of duplicates in between. Good if precision is not a premium but type conservation and speeds are. This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division.

Returns
The inverse of the number.

◆ invFull()

template<int8_t NI, int8_t NF, uint64_t RANGE>
constexpr SFix<NF,FixMathPrivate::FM_min(NI*2+NF,63-NF)> SFix< NI, NF, RANGE >::invFull ( ) const
inlineconstexpr

Compute the inverse of a SFix<NI,NF>, as a SFix<NF,NI*2+NF>. This inverse is more accurate than invFast, and usually leads to non common values on the whole input range. This comes at the cost of a way bigger resulting type. This is still slower than a multiplication, hence the suggested workflow is to compute the inverse when time is not critical, for instance in updateControl(), and multiply it afterward, for instance in updateAudio(), if you need a division.

Returns
The inverse of the number.

◆ operator!=()

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t _NI, int8_t _NF>
constexpr bool SFix< NI, NF, RANGE >::operator!= ( const SFix< _NI, _NF > &  op) const
inlineconstexpr

Comparison with another SFix.

Parameters
opA UFix
Returns
true if this is not equal to op, false otherwise

◆ operator*() [1/2]

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr FixMathPrivate::SFixByRange_t<NF+_NF, RANGE*_RANGE> SFix< NI, NF, RANGE >::operator* ( const SFix< _NI, _NF, _RANGE > &  op) const
inlineconstexpr

Multiplication with another SFix. Safe.

Parameters
opThe SFix to be multiplied.
Returns
The result of the multiplication as a SFix.

◆ operator*() [2/2]

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr FixMathPrivate::SFixByRange_t<NF+_NF, RANGE*_RANGE> SFix< NI, NF, RANGE >::operator* ( const UFix< _NI, _NF, _RANGE > &  op2) const
inlineconstexpr

Multiplication between a SFix and a UFix. Safe.

Parameters
op1A SFix
op2A UFix
Returns
The result of the multiplication of op1 and op2. As a SFix

◆ operator+() [1/2]

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr FixMathPrivate::SFixByRange_t<FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> SFix< NI, NF, RANGE >::operator+ ( const SFix< _NI, _NF, _RANGE > &  op) const
inlineconstexpr

Addition with another SFix. Safe.

Parameters
opThe SFix to be added.
Returns
The result of the addition as a SFix.

◆ operator+() [2/2]

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr FixMathPrivate::SFixByRange_t<FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> SFix< NI, NF, RANGE >::operator+ ( const UFix< _NI, _NF, _RANGE > &  op2) const
inlineconstexpr

Addition between a SFix and a UFix. Safe.

Parameters
op1A SFix
op2A UFix
Returns
The result of the addition of op1 and op2. As a SFix

◆ operator-() [1/3]

template<int8_t NI, int8_t NF, uint64_t RANGE>
constexpr FixMathPrivate::SFixByRange_t<NF,RANGE+1> SFix< NI, NF, RANGE >::operator- ( ) const
inlineconstexpr

Opposite of the number (unary minus operator).

Returns
The opposite numberas a SFix.

◆ operator-() [2/3]

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr FixMathPrivate::SFixByRange_t<FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> SFix< NI, NF, RANGE >::operator- ( const SFix< _NI, _NF, _RANGE > &  op) const
inlineconstexpr

Subtraction with another SFix. Safe.

Parameters
opThe SFix to be subtracted.
Returns
The result of the subtraction as a SFix.

◆ operator-() [3/3]

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t _NI, int8_t _NF, uint64_t _RANGE>
constexpr FixMathPrivate::SFixByRange_t<FixMathPrivate::FM_max(NF,_NF),FixMathPrivate::rangeAdd(NF,_NF,RANGE,_RANGE)> SFix< NI, NF, RANGE >::operator- ( const UFix< _NI, _NF, _RANGE > &  op) const
inlineconstexpr

Subtraction with a UFix. Safe.

Parameters
opThe SFix to be subtracted.
Returns
The result of the subtraction as a SFix.

◆ operator<()

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t _NI, int8_t _NF>
constexpr bool SFix< NI, NF, RANGE >::operator< ( const SFix< _NI, _NF > &  op) const
inlineconstexpr

Comparison with another SFix.

Parameters
opA UFix
Returns
true if this is smaller than op, false otherwise

◆ operator==()

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t _NI, int8_t _NF>
constexpr bool SFix< NI, NF, RANGE >::operator== ( const SFix< _NI, _NF > &  op) const
inlineconstexpr

Comparison with another SFix.

Parameters
opA UFix
Returns
true if this is equal to op, false otherwise

◆ operator>()

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t _NI, int8_t _NF>
constexpr bool SFix< NI, NF, RANGE >::operator> ( const SFix< _NI, _NF > &  op) const
inlineconstexpr

Comparison with another SFix.

Parameters
opA UFix
Returns
true if this is bigger than op, false otherwise

◆ operator>>()

template<int8_t NI, int8_t NF, uint64_t RANGE>
constexpr SFix<NI,NF> SFix< NI, NF, RANGE >::operator>> ( const int8_t  op) const
inlineconstexpr

Right shift. This won't overflow but will not leverage on the bits freed by the shift. Better to use .sR<shift>() if possible instead.

Parameters
opThe shift number
Returns
The result of the shift as a SFix.

◆ sL()

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t op>
constexpr SFix<NI+op,FixMathPrivate::FM_max(NF-op,0),FixMathPrivate::rangeShift(NF,op,RANGE)> SFix< NI, NF, RANGE >::sL ( )
inlineconstexpr

Safe and optimal left shift. The returned type will be adjusted accordingly

Parameters
opThe shift number
Returns
The result of the shift as a UFix of bigger size.

◆ sR()

template<int8_t NI, int8_t NF, uint64_t RANGE>
template<int8_t op>
constexpr SFix<FixMathPrivate::FM_max(NI-op,0), NF+op, FixMathPrivate::rangeShift(NI,op,RANGE)> SFix< NI, NF, RANGE >::sR ( )
inlineconstexpr

Safe and optimal right shift. The returned type will be adjusted accordingly

Parameters
opThe shift number
Returns
The result of the shift as a UFix of smaller size.

The documentation for this class was generated from the following file: