#pragma once #include "Details.h" #include "UFixed.h" #include "SFixed.h" // // Declaration // FIXED_POINTS_BEGIN_NAMESPACE template< unsigned Integer, unsigned Fraction > constexpr UFixed floorFixed(const UFixed & value); template< unsigned Integer, unsigned Fraction > constexpr SFixed floorFixed(const SFixed & value); template< unsigned Integer, unsigned Fraction > constexpr UFixed ceilFixed(const UFixed & value); template< unsigned Integer, unsigned Fraction > constexpr SFixed ceilFixed(const SFixed & value); template< unsigned Integer, unsigned Fraction > constexpr UFixed roundFixed(const UFixed & value); template< unsigned Integer, unsigned Fraction > constexpr SFixed roundFixed(const SFixed & value); template< unsigned Integer, unsigned Fraction > constexpr bool signbitFixed(const SFixed & value); template< unsigned Integer, unsigned Fraction > constexpr SFixed absFixed(const SFixed & value); template< unsigned Integer, unsigned Fraction > constexpr SFixed copysignFixed(const SFixed & x, const SFixed & y); template< unsigned Integer, unsigned Fraction > constexpr SFixed nextafterFixed(const SFixed & from, const SFixed & to); template< unsigned Integer, unsigned Fraction > constexpr UFixed nextafterFixed(const UFixed & from, const UFixed & to); // // Unsigned Random // template< unsigned Integer, unsigned Fraction > UFixed randomUFixed(void); template< unsigned Integer, unsigned Fraction > UFixed randomUFixed(const UFixed & exclusiveUpperBound); template< unsigned Integer, unsigned Fraction > UFixed randomUFixed(const UFixed & inclusiveLowerBound, const UFixed & exclusiveUpperBound); // // Signed Random // template< unsigned Integer, unsigned Fraction > SFixed randomSFixed(void); template< unsigned Integer, unsigned Fraction > SFixed randomSFixed(const SFixed & exclusiveUpperBound); template< unsigned Integer, unsigned Fraction > SFixed randomSFixed(const SFixed & inclusiveLowerBound, const SFixed & exclusiveUpperBound); FIXED_POINTS_END_NAMESPACE // // Definition // FIXED_POINTS_BEGIN_NAMESPACE template< unsigned Integer, unsigned Fraction > constexpr UFixed floorFixed(const UFixed & value) { using OutputType = UFixed; using InternalType = typename OutputType::InternalType; return OutputType::fromInternal(static_cast(value.getInternal() & ~OutputType::FractionMask)); } template< unsigned Integer, unsigned Fraction > constexpr SFixed floorFixed(const SFixed & value) { using OutputType = SFixed; using InternalType = typename OutputType::InternalType; return OutputType::fromInternal(static_cast(value.getInternal() & ~OutputType::FractionMask)); } template< unsigned Integer, unsigned Fraction > constexpr UFixed ceilFixed(const UFixed & value) { return UFixed((value.getFraction() == 0) ? value.getInteger() : (value.getInteger() + 1), 0); } template< unsigned Integer, unsigned Fraction > constexpr SFixed ceilFixed(const SFixed & value) { return SFixed((value.getFraction() == 0) ? value.getInteger() : (value.getInteger() + 1), 0); } template< unsigned Integer, unsigned Fraction > constexpr UFixed roundFixed(const UFixed & value) { using OutputType = UFixed; return (value.getInternal() & OutputType::MidpointMask) != 0 ? ceilFixed(value) : floorFixed(value); } template< unsigned Integer, unsigned Fraction > constexpr SFixed roundFixed(const SFixed & value) { using OutputType = SFixed; return ( ((value.getInternal() & OutputType::MidpointMask) != 0) && !signbitFixed(value) || ((value.getInternal() & OutputType::LesserMidpointMask) != 0) ) ? ceilFixed(value) : floorFixed(value); } template< unsigned Integer, unsigned Fraction > constexpr UFixed truncFixed(const UFixed & value) { return UFixed(value.getInteger(), 0); } template< unsigned Integer, unsigned Fraction > constexpr SFixed truncFixed(const SFixed & value) { using OutputType = SFixed; return (value.getInternal() < 0) ? OutputType::fromInternal(value.getInternal() & ~OutputType::FractionMask) + OutputType(1, 0) : OutputType::fromInternal(value.getInternal() & ~OutputType::FractionMask); } template< unsigned Integer, unsigned Fraction > constexpr bool signbitFixed(const SFixed & value) { return (value.getInternal() < 0); } template< unsigned Integer, unsigned Fraction > constexpr SFixed absFixed(const SFixed & value) { return (signbitFixed(value)) ? -value : value; } template< unsigned Integer, unsigned Fraction > constexpr SFixed copysignFixed(const SFixed & x, const SFixed & y) { return (signbitFixed(x) != signbitFixed(y)) ? -x : x; } template< unsigned Integer, unsigned Fraction > constexpr SFixed nextafterFixed(const SFixed & from, const SFixed & to) { using ResultType = SFixed; return (from < to) ? ResultType::fromInternal(from.getInternal() + 1) : (from > to) ? ResultType::fromInternal(from.getInternal() - 1): to; } template< unsigned Integer, unsigned Fraction > constexpr UFixed nextafterFixed(const UFixed & from, const UFixed & to) { using ResultType = UFixed; return (from < to) ? ResultType::fromInternal(from.getInternal() + 1) : (from > to) ? ResultType::fromInternal(from.getInternal() - 1): to; } // // Unsigned Random // template< unsigned Integer, unsigned Fraction > UFixed randomUFixed(void) { using InternalType = typename UFixed::InternalType; return UFixed::fromInternal(FIXED_POINTS_DETAILS::RandomHelper::Random()); } template< unsigned Integer, unsigned Fraction > UFixed randomUFixed(const UFixed & exclusiveUpperBound) { using InternalType = typename UFixed::InternalType; return UFixed::fromInternal(FIXED_POINTS_DETAILS::RandomHelper::Random() % exclusiveUpperBound.getInternal()); } template< unsigned Integer, unsigned Fraction > UFixed randomUFixed(const UFixed & inclusiveLowerBound, const UFixed & exclusiveUpperBound) { using InternalType = typename UFixed::InternalType; return UFixed::fromInternal(inclusiveLowerBound.getInternal() + FIXED_POINTS_DETAILS::RandomHelper::Random() % exclusiveUpperBound.getInternal()); } // // Signed Random // template< unsigned Integer, unsigned Fraction > SFixed randomSFixed(void) { using InternalType = typename SFixed::InternalType; return SFixed::fromInternal(FIXED_POINTS_DETAILS::RandomHelper::Random()); } template< unsigned Integer, unsigned Fraction > SFixed randomSFixed(const SFixed & exclusiveUpperBound) { using InternalType = typename SFixed::InternalType; return SFixed::fromInternal(FIXED_POINTS_DETAILS::RandomHelper::Random() % exclusiveUpperBound.getInternal()); } template< unsigned Integer, unsigned Fraction > SFixed randomSFixed(const SFixed & inclusiveLowerBound, const SFixed & exclusiveUpperBound) { using InternalType = typename SFixed::InternalType; return SFixed::fromInternal(inclusiveLowerBound.getInternal() + FIXED_POINTS_DETAILS::RandomHelper::Random() % exclusiveUpperBound.getInternal()); } FIXED_POINTS_END_NAMESPACE