@ -24,18 +24,37 @@ constexpr SFixed<Integer, Fraction>::SFixed(const RawType & value)
{
}
template < unsigned Fraction >
constexpr SFixed < 0 , Fraction > : : SFixed ( const RawType & value )
: value ( static_cast < InternalType > ( value ) )
{
}
template < unsigned Integer , unsigned Fraction >
constexpr SFixed < Integer , Fraction > : : SFixed ( void )
: value ( 0 )
{
}
template < unsigned Fraction >
constexpr SFixed < 0 , Fraction > : : SFixed ( void )
: value ( 0 )
{
}
template < unsigned Integer , unsigned Fraction >
constexpr SFixed < Integer , Fraction > : : SFixed ( const IntegerType & integer , const FractionType & fraction )
: value ( ( static_cast < InternalType > ( integer ) < < FractionSize ) | fraction )
{
}
// The comma operator and void cast are used to circumvent an unused parameter warning
template < unsigned Fraction >
constexpr SFixed < 0 , Fraction > : : SFixed ( const IntegerType & integer , const FractionType & fraction )
: value ( ( ( void ) integer , fraction ) )
{
}
template < unsigned Integer , unsigned Fraction >
constexpr SFixed < Integer , Fraction > : : SFixed ( const char & value )
: value ( static_cast < InternalType > ( static_cast < FIXED_POINTS_DETAILS : : LargerType < char , InternalType > > ( value ) < < FractionSize ) )
@ -108,18 +127,36 @@ constexpr SFixed<Integer, Fraction>::SFixed(const double & value)
{
}
template < unsigned Fraction >
constexpr SFixed < 0 , Fraction > : : SFixed ( const double & value )
: value ( static_cast < InternalType > ( value * static_cast < double > ( Scale ) ) )
{
}
template < unsigned Integer , unsigned Fraction >
constexpr SFixed < Integer , Fraction > : : SFixed ( const float & value )
: value ( static_cast < InternalType > ( value * static_cast < float > ( Scale ) ) )
{
}
template < unsigned Fraction >
constexpr SFixed < 0 , Fraction > : : SFixed ( const float & value )
: value ( static_cast < InternalType > ( value * static_cast < float > ( Scale ) ) )
{
}
template < unsigned Integer , unsigned Fraction >
constexpr SFixed < Integer , Fraction > : : SFixed ( const long double & value )
: value ( static_cast < InternalType > ( value * static_cast < long double > ( Scale ) ) )
{
}
template < unsigned Fraction >
constexpr SFixed < 0 , Fraction > : : SFixed ( const long double & value )
: value ( static_cast < InternalType > ( value * static_cast < long double > ( Scale ) ) )
{
}
//
// Getters
//
@ -130,18 +167,36 @@ constexpr typename SFixed<Integer, Fraction>::InternalType SFixed<Integer, Fract
return this - > value ;
}
template < unsigned Fraction >
constexpr typename SFixed < 0 , Fraction > : : InternalType SFixed < 0 , Fraction > : : getInternal ( void ) const
{
return this - > value ;
}
template < unsigned Integer , unsigned Fraction >
constexpr typename SFixed < Integer , Fraction > : : IntegerType SFixed < Integer , Fraction > : : getInteger ( void ) const
{
return ( static_cast < IntegerType > ( this - > value > > IntegerShift ) & IntegerMask ) | ( ( this - > value < 0 ) ? ~ IntegerMask : 0 ) ;
}
template < unsigned Fraction >
constexpr typename SFixed < 0 , Fraction > : : IntegerType SFixed < 0 , Fraction > : : getInteger ( void ) const
{
return ( static_cast < IntegerType > ( this - > value > > IntegerShift ) & IntegerMask ) | ( ( this - > value < 0 ) ? ~ IntegerMask : 0 ) ;
}
template < unsigned Integer , unsigned Fraction >
constexpr typename SFixed < Integer , Fraction > : : FractionType SFixed < Integer , Fraction > : : getFraction ( void ) const
{
return static_cast < FractionType > ( this - > value > > FractionShift ) & FractionMask ;
}
template < unsigned Fraction >
constexpr typename SFixed < 0 , Fraction > : : FractionType SFixed < 0 , Fraction > : : getFraction ( void ) const
{
return static_cast < FractionType > ( this - > value > > FractionShift ) & FractionMask ;
}
//
// Cast Operators
//
@ -152,6 +207,12 @@ constexpr SFixed<Integer, Fraction>::operator IntegerType(void) const
return this - > getInteger ( ) ;
}
template < unsigned Fraction >
constexpr SFixed < 0 , Fraction > : : operator IntegerType ( void ) const
{
return this - > getInteger ( ) ;
}
template < unsigned Integer , unsigned Fraction >
constexpr SFixed < Integer , Fraction > : : operator float ( void ) const
{
@ -161,6 +222,15 @@ constexpr SFixed<Integer, Fraction>::operator float(void) const
( ( this - > value < 0 ) ? ~ IdentityMask : 0 ) ) ;
}
template < unsigned Fraction >
constexpr SFixed < 0 , Fraction > : : operator float ( void ) const
{
return ( 1.0F / Scale ) *
static_cast < InternalType >
( ( this - > value & IdentityMask ) |
( ( this - > value < 0 ) ? ~ IdentityMask : 0 ) ) ;
}
template < unsigned Integer , unsigned Fraction >
constexpr SFixed < Integer , Fraction > : : operator double ( void ) const
{
@ -170,6 +240,15 @@ constexpr SFixed<Integer, Fraction>::operator double(void) const
( ( this - > value < 0 ) ? ~ IdentityMask : 0 ) ) ;
}
template < unsigned Fraction >
constexpr SFixed < 0 , Fraction > : : operator double ( void ) const
{
return ( 1.0 / Scale ) *
static_cast < InternalType >
( ( this - > value & IdentityMask ) |
( ( this - > value < 0 ) ? ~ IdentityMask : 0 ) ) ;
}
template < unsigned Integer , unsigned Fraction >
constexpr SFixed < Integer , Fraction > : : operator long double ( void ) const
{
@ -179,6 +258,15 @@ constexpr SFixed<Integer, Fraction>::operator long double(void) const
( ( this - > value < 0 ) ? ~ IdentityMask : 0 ) ) ;
}
template < unsigned Fraction >
constexpr SFixed < 0 , Fraction > : : operator long double ( void ) const
{
return ( 1.0 L / Scale ) *
static_cast < InternalType >
( ( this - > value & IdentityMask ) |
( ( this - > value < 0 ) ? ~ IdentityMask : 0 ) ) ;
}
template < unsigned Integer , unsigned Fraction >
template < unsigned IntegerOut , unsigned FractionOut >
constexpr SFixed < Integer , Fraction > : : operator SFixed < IntegerOut , FractionOut > ( void ) const
@ -198,6 +286,25 @@ constexpr SFixed<Integer, Fraction>::operator SFixed<IntegerOut, FractionOut>(vo
OutputType : : fromInternal ( this - > value ) ;
}
template < unsigned Fraction >
template < unsigned IntegerOut , unsigned FractionOut >
constexpr SFixed < 0 , Fraction > : : operator SFixed < IntegerOut , FractionOut > ( void ) const
{
using OutputType = SFixed < IntegerOut , FractionOut > ;
using OutputInternalType = typename OutputType : : InternalType ;
using OutputShiftType = typename OutputType : : ShiftType ;
using InputType = SFixed < 0 , Fraction > ;
using InputShiftType = typename InputType : : ShiftType ;
return
( FractionOut > FractionSize ) ?
OutputType : : fromInternal ( static_cast < OutputInternalType > ( static_cast < OutputShiftType > ( this - > value ) < < ( ( FractionOut > FractionSize ) ? ( FractionOut - FractionSize ) : 0 ) ) ) :
( FractionSize > FractionOut ) ?
OutputType : : fromInternal ( static_cast < OutputInternalType > ( static_cast < InputShiftType > ( this - > value ) > > ( ( FractionSize > FractionOut ) ? ( FractionSize - FractionOut ) : 0 ) ) ) :
OutputType : : fromInternal ( this - > value ) ;
}
//
// Static Functions
//
@ -208,12 +315,24 @@ constexpr SFixed<Integer, Fraction> SFixed<Integer, Fraction>::fromInternal(cons
return SFixed < Integer , Fraction > ( RawType ( value ) ) ;
}
template < unsigned Fraction >
constexpr SFixed < 0 , Fraction > SFixed < 0 , Fraction > : : fromInternal ( const typename SFixed < 0 , Fraction > : : InternalType & value )
{
return SFixed < 0 , Fraction > ( RawType ( value ) ) ;
}
template < unsigned Integer , unsigned Fraction >
constexpr SFixed < Integer , Fraction > SFixed < Integer , Fraction > : : operator - ( void ) const
{
return SFixed < Integer , Fraction > : : fromInternal ( - this - > value ) ;
}
template < unsigned Fraction >
constexpr SFixed < 0 , Fraction > SFixed < 0 , Fraction > : : operator - ( void ) const
{
return SFixed < 0 , Fraction > : : fromInternal ( - this - > value ) ;
}
//
// Member Operators
//
@ -243,6 +362,13 @@ SFixed<Integer, Fraction> & SFixed<Integer, Fraction>::operator +=(const SFixed<
return * this ;
}
template < unsigned Fraction >
SFixed < 0 , Fraction > & SFixed < 0 , Fraction > : : operator + = ( const SFixed < 0 , Fraction > & other )
{
this - > value + = other . value ;
return * this ;
}
template < unsigned Integer , unsigned Fraction >
SFixed < Integer , Fraction > & SFixed < Integer , Fraction > : : operator - = ( const SFixed < Integer , Fraction > & other )
{
@ -250,6 +376,13 @@ SFixed<Integer, Fraction> & SFixed<Integer, Fraction>::operator -=(const SFixed<
return * this ;
}
template < unsigned Fraction >
SFixed < 0 , Fraction > & SFixed < 0 , Fraction > : : operator - = ( const SFixed < 0 , Fraction > & other )
{
this - > value - = other . value ;
return * this ;
}
template < unsigned Integer , unsigned Fraction >
SFixed < Integer , Fraction > & SFixed < Integer , Fraction > : : operator * = ( const SFixed < Integer , Fraction > & other )
{
@ -260,6 +393,16 @@ SFixed<Integer, Fraction> & SFixed<Integer, Fraction>::operator *=(const SFixed<
return * this ;
}
template < unsigned Fraction >
SFixed < 0 , Fraction > & SFixed < 0 , Fraction > : : operator * = ( const SFixed < 0 , Fraction > & other )
{
using InternalType = typename SFixed < 0 , Fraction > : : InternalType ;
using PrecisionType = typename SFixed < 0 , Fraction * 2 > : : InternalType ;
const PrecisionType temp = ( static_cast < PrecisionType > ( this - > value ) * static_cast < PrecisionType > ( other . value ) ) > > Fraction ;
this - > value = static_cast < InternalType > ( temp ) ;
return * this ;
}
template < unsigned Integer , unsigned Fraction >
SFixed < Integer , Fraction > & SFixed < Integer , Fraction > : : operator / = ( const SFixed < Integer , Fraction > & other )
{
@ -270,4 +413,14 @@ SFixed<Integer, Fraction> & SFixed<Integer, Fraction>::operator /=(const SFixed<
return * this ;
}
template < unsigned Fraction >
SFixed < 0 , Fraction > & SFixed < 0 , Fraction > : : operator / = ( const SFixed < 0 , Fraction > & other )
{
using InternalType = typename SFixed < 0 , Fraction > : : InternalType ;
using PrecisionType = typename SFixed < 0 , Fraction * 2 > : : InternalType ;
const PrecisionType temp = ( static_cast < PrecisionType > ( this - > value ) < < Fraction ) / static_cast < PrecisionType > ( other . value ) ;
this - > value = static_cast < InternalType > ( temp ) ;
return * this ;
}
FIXED_POINTS_END_NAMESPACE