FIXED_POINTS_BEGIN_NAMESPACE // // Constructors // template< unsigned Integer, unsigned Fraction > constexpr SFixed::SFixed(void) : Base() { } template< unsigned Integer, unsigned Fraction > constexpr SFixed::SFixed(const IntegerType & integer) : Base(RawType(static_cast(integer) << FractionSize)) { } template< unsigned Integer, unsigned Fraction > constexpr SFixed::SFixed(const IntegerType & integer, const FractionType & fraction) : Base(RawType((static_cast(integer) << FractionSize) | fraction)) { } // // Getters // template< unsigned Integer, unsigned Fraction > constexpr typename SFixed::InternalType SFixed::getInternal(void) const { return this->value; } template< unsigned Integer, unsigned Fraction > constexpr typename SFixed::IntegerType SFixed::getInteger(void) const { return static_cast(this->value >> IntegerShift) & IntegerMask | ((this->value < 0) ? ~IntegerMask : 0); } template< unsigned Integer, unsigned Fraction > constexpr typename SFixed::FractionType SFixed::getFraction(void) const { return static_cast(this->value >> FractionShift) & FractionMask; } // // Cast Operators // template< unsigned Integer, unsigned Fraction > constexpr SFixed::operator IntegerType(void) const { return this->getInteger(); } template< unsigned Integer, unsigned Fraction > constexpr SFixed::operator float(void) const { /*return (1.0f / Scale) * (this->value < 0) ? -((-this->value) & IdentityMask) : this->value & IdentityMask; */ return (1.0f / Scale) * static_cast ((this->value & IdentityMask) | ((this->value < 0) ? ~IdentityMask : 0)); } template< unsigned Integer, unsigned Fraction > constexpr SFixed::operator double(void) const { /*return (1.0 / Scale) * (this->value < 0) ? -((-this->value) & IdentityMask) : this->value & IdentityMask; */ return (1.0 / Scale) * static_cast ((this->value & IdentityMask) | ((this->value < 0) ? ~IdentityMask : 0)); } template< unsigned Integer, unsigned Fraction > template< unsigned IntegerOut, unsigned FractionOut > constexpr SFixed::operator SFixed(void) const { using OutputType = UFixed; using OutputInternalType = typename OutputType::InternalType; using OutputShiftType = typename OutputType::ShiftType; using InputType = UFixed; using InputInternalType = typename InputType::InternalType; using InputShiftType = typename InputType::ShiftType; return (FractionOut > FractionSize) ? OutputType::fromInternal(static_cast(static_cast(this->value) << ((FractionOut > FractionSize) ? (FractionOut - FractionSize) : 0))) : (FractionSize > FractionOut) ? OutputType::fromInternal(static_cast(static_cast(this->value) >> ((FractionSize > FractionOut) ? (FractionSize - FractionOut) : 0))) : OutputType::fromInternal(this->value); } // // Static Functions // template< unsigned Integer, unsigned Fraction > constexpr SFixed SFixed::fromInternal(const typename SFixed::InternalType & value) { return SFixed(RawType(value)); } template< unsigned Integer, unsigned Fraction > constexpr SFixed SFixed::operator -(void) const { return SFixed::fromInternal(-this->value); } // // Member Operators // template< unsigned Integer, unsigned Fraction > SFixed & SFixed::operator ++(void) { this->value += (1 << FractionSize); return *this; } template< unsigned Integer, unsigned Fraction > SFixed & SFixed::operator --(void) { this->value -= (1 << FractionSize); return *this; } // // Compound Assignment Operators // template< unsigned Integer, unsigned Fraction > SFixed & SFixed::operator +=(const SFixed & other) { this->value += other.value; return *this; } template< unsigned Integer, unsigned Fraction > SFixed & SFixed::operator -=(const SFixed & other) { this->value -= other.value; return *this; } template< unsigned Integer, unsigned Fraction > SFixed & SFixed::operator *=(const SFixed & other) { using InternalType = typename SFixed::InternalType; using PrecisionType = typename SFixed::InternalType; const PrecisionType temp = (static_cast(this->value) * static_cast(other.value)) >> Fraction; this->value = static_cast(temp); return *this; } template< unsigned Integer, unsigned Fraction > SFixed & SFixed::operator /=(const SFixed & other) { using InternalType = typename SFixed::InternalType; using PrecisionType = typename SFixed::InternalType; const PrecisionType temp = (static_cast(this->value) << Fraction) / static_cast(other.value); this->value = static_cast(temp); return *this; } FIXED_POINTS_END_NAMESPACE