diff --git a/README.md b/README.md index d6173af..8093173 100644 --- a/README.md +++ b/README.md @@ -176,11 +176,11 @@ This means that you may write code such as `UFixed<8, 8> value = 0.5;` without i - `double`. - The smallest unsigned type capable of holding its integer part. I.e. a type of at least `I` bits. - Another `UFixed` type of a different scale. E.g. `UFixed<4, 4>` may be converted to `UFixed<8, 8>` and vice versa. +- Another `SFixed` type of a different scale. E.g. `UFixed<4, 4>` may be converted to `SFixed<7, 8>` and vice versa. `SFixed` is explicitly convertible to: - `float`. - `double`. - The smallest signed type capable of holding its integer part. I.e. a type of at least `I + 1` bits. - Another `SFixed` type of a different scale. E.g. `SFixed<3, 4>` may be converted to `SFixed<7, 8>` and vice versa. - - +- Another `UFixed` type of a different scale. E.g. `SFixed<3, 4>` may be converted to `UFixed<8, 8>` and vice versa. diff --git a/src/FixedPoints/SFixed.h b/src/FixedPoints/SFixed.h index b2aa96d..1d9fab7 100644 --- a/src/FixedPoints/SFixed.h +++ b/src/FixedPoints/SFixed.h @@ -22,6 +22,9 @@ FIXED_POINTS_BEGIN_NAMESPACE // Declaration // +template< unsigned IntegerOut, unsigned FractionOut > +class UFixed; // forward declaration of UFixed for casting between UFixed and SFixed + template< unsigned Integer, unsigned Fraction > class SFixed { @@ -102,6 +105,8 @@ public: template< unsigned IntegerOut, unsigned FractionOut > constexpr explicit operator SFixed() const; + template< unsigned IntegerOut, unsigned FractionOut > + constexpr explicit operator UFixed() const; static constexpr SFixed fromInternal(const InternalType & value); diff --git a/src/FixedPoints/SFixedMemberFunctions.h b/src/FixedPoints/SFixedMemberFunctions.h index e2ab090..43b167f 100644 --- a/src/FixedPoints/SFixedMemberFunctions.h +++ b/src/FixedPoints/SFixedMemberFunctions.h @@ -182,14 +182,33 @@ constexpr SFixed::operator long double() const template< unsigned Integer, unsigned Fraction > template< unsigned IntegerOut, unsigned FractionOut > constexpr SFixed::operator SFixed() const -{ +{ using OutputType = SFixed; using OutputInternalType = typename OutputType::InternalType; using OutputShiftType = typename OutputType::ShiftType; - + + using InputType = SFixed; + 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); +} + +template< unsigned Integer, unsigned Fraction > +template< unsigned IntegerOut, unsigned FractionOut > +constexpr SFixed::operator UFixed() const +{ + using OutputType = UFixed; + using OutputInternalType = typename OutputType::InternalType; + using OutputShiftType = typename OutputType::ShiftType; + using InputType = SFixed; using InputShiftType = typename InputType::ShiftType; - + return (FractionOut > FractionSize) ? OutputType::fromInternal(static_cast(static_cast(this->value) << ((FractionOut > FractionSize) ? (FractionOut - FractionSize) : 0))) : diff --git a/src/FixedPoints/UFixed.h b/src/FixedPoints/UFixed.h index 64079da..7c64a80 100644 --- a/src/FixedPoints/UFixed.h +++ b/src/FixedPoints/UFixed.h @@ -22,6 +22,9 @@ FIXED_POINTS_BEGIN_NAMESPACE // Declaration // +template< unsigned IntegerOut, unsigned FractionOut > +class SFixed; // forward declaration of SFixed for casting between SFixed and UFixed + template< unsigned Integer, unsigned Fraction > class UFixed { @@ -103,6 +106,8 @@ public: template< unsigned IntegerOut, unsigned FractionOut > constexpr explicit operator UFixed() const; + template< unsigned IntegerOut, unsigned FractionOut > + constexpr explicit operator SFixed() const; static constexpr UFixed fromInternal(const InternalType & value); diff --git a/src/FixedPoints/UFixedMemberFunctions.h b/src/FixedPoints/UFixedMemberFunctions.h index 9f7ddd0..c55cde2 100644 --- a/src/FixedPoints/UFixedMemberFunctions.h +++ b/src/FixedPoints/UFixedMemberFunctions.h @@ -189,6 +189,25 @@ constexpr UFixed::operator UFixed() OutputType::fromInternal(this->value); } +template< unsigned Integer, unsigned Fraction > +template< unsigned IntegerOut, unsigned FractionOut > +constexpr UFixed::operator SFixed() const +{ + using OutputType = SFixed; + using OutputInternalType = typename OutputType::InternalType; + using OutputShiftType = typename OutputType::ShiftType; + + using InputType = UFixed; + 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 //