Add support for casting UFixed to SFixed and vice versa

pull/67/head
Dirk Petrautzki 4 years ago
parent 8d0ef25aec
commit 95dba437d7
  1. 4
      README.md
  2. 5
      src/FixedPoints/SFixed.h
  3. 25
      src/FixedPoints/SFixedMemberFunctions.h
  4. 5
      src/FixedPoints/UFixed.h
  5. 19
      src/FixedPoints/UFixedMemberFunctions.h

@ -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<I, F>` 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.

@ -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<IntegerOut, FractionOut>() const;
template< unsigned IntegerOut, unsigned FractionOut >
constexpr explicit operator UFixed<IntegerOut, FractionOut>() const;
static constexpr SFixed fromInternal(const InternalType & value);

@ -182,14 +182,33 @@ constexpr SFixed<Integer, Fraction>::operator long double() const
template< unsigned Integer, unsigned Fraction >
template< unsigned IntegerOut, unsigned FractionOut >
constexpr SFixed<Integer, Fraction>::operator SFixed<IntegerOut, FractionOut>() const
{
{
using OutputType = SFixed<IntegerOut, FractionOut>;
using OutputInternalType = typename OutputType::InternalType;
using OutputShiftType = typename OutputType::ShiftType;
using InputType = SFixed<Integer, 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);
}
template< unsigned Integer, unsigned Fraction >
template< unsigned IntegerOut, unsigned FractionOut >
constexpr SFixed<Integer, Fraction>::operator UFixed<IntegerOut, FractionOut>() const
{
using OutputType = UFixed<IntegerOut, FractionOut>;
using OutputInternalType = typename OutputType::InternalType;
using OutputShiftType = typename OutputType::ShiftType;
using InputType = SFixed<Integer, Fraction>;
using InputShiftType = typename InputType::ShiftType;
return
(FractionOut > FractionSize) ?
OutputType::fromInternal(static_cast<OutputInternalType>(static_cast<OutputShiftType>(this->value) << ((FractionOut > FractionSize) ? (FractionOut - FractionSize) : 0))) :

@ -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<IntegerOut, FractionOut>() const;
template< unsigned IntegerOut, unsigned FractionOut >
constexpr explicit operator SFixed<IntegerOut, FractionOut>() const;
static constexpr UFixed fromInternal(const InternalType & value);

@ -189,6 +189,25 @@ constexpr UFixed<Integer, Fraction>::operator UFixed<IntegerOut, FractionOut>()
OutputType::fromInternal(this->value);
}
template< unsigned Integer, unsigned Fraction >
template< unsigned IntegerOut, unsigned FractionOut >
constexpr UFixed<Integer, Fraction>::operator SFixed<IntegerOut, FractionOut>() const
{
using OutputType = SFixed<IntegerOut, FractionOut>;
using OutputInternalType = typename OutputType::InternalType;
using OutputShiftType = typename OutputType::ShiftType;
using InputType = UFixed<Integer, 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
//

Loading…
Cancel
Save