mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Merge remote-tracking branch 'origin/feature/cumulative_moving_average' into development
This commit is contained in:
parent
01bae83542
commit
f8c6830807
60
include/etl/absolute.h
Normal file
60
include/etl/absolute.h
Normal file
@ -0,0 +1,60 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2018 jwellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_ABSOLUTE_INCLUDED
|
||||
#define ETL_ABSOLUTE_INCLUDED
|
||||
|
||||
#include "type_traits.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
// For signed types.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
typename etl::enable_if<etl::is_signed<T>::value, T>::type
|
||||
absolute(T value)
|
||||
{
|
||||
return (value < T(0)) ? -value : value;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
// For unsigned types.
|
||||
//***************************************************************************
|
||||
template <typename T>
|
||||
typename etl::enable_if<etl::is_unsigned<T>::value, T>::type
|
||||
absolute(T value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
176
include/etl/cumulative_moving_average.h
Normal file
176
include/etl/cumulative_moving_average.h
Normal file
@ -0,0 +1,176 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2018 jwellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_CUMULATIVE_MOVING_AVERAGE_INCLUDED
|
||||
#define ETL_CUMULATIVE_MOVING_AVERAGE_INCLUDED
|
||||
|
||||
#include "type_traits.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// Cumulative Moving Average
|
||||
/// \tparam T The sample value type.
|
||||
/// \tparam SAMPLE_SIZE The number of samples to average over.
|
||||
/// \tparam SCALING The scaling factor applied to samples. Default = 1.
|
||||
//***************************************************************************
|
||||
template <typename T,
|
||||
const size_t SAMPLE_SIZE,
|
||||
const size_t SCALING = 1U,
|
||||
const bool IsIntegral = std::is_integral<T>::value,
|
||||
const bool IsFloat = std::is_floating_point<T>::value>
|
||||
class cumulative_moving_average;
|
||||
|
||||
//***************************************************************************
|
||||
/// Cumulative Moving Average
|
||||
/// For integral types.
|
||||
/// \tparam T The sample value type.
|
||||
/// \tparam SAMPLE_SIZE The number of samples to average over.
|
||||
/// \tparam SCALING The scaling factor applied to samples. Default = 1.
|
||||
//***************************************************************************
|
||||
template <typename T, const size_t SAMPLE_SIZE_, const size_t SCALING_>
|
||||
class cumulative_moving_average<T, SAMPLE_SIZE_, SCALING_, true, false>
|
||||
{
|
||||
typedef typename etl::conditional<etl::is_signed<T>::value, int32_t, uint32_t>::type scale_t;
|
||||
typedef typename etl::conditional<etl::is_signed<T>::value, int32_t, uint32_t>::type sample_t;
|
||||
|
||||
static const sample_t SAMPLES = static_cast<sample_t>(SAMPLE_SIZE_);
|
||||
static const scale_t SCALE = static_cast<scale_t>(SCALING_);
|
||||
|
||||
public:
|
||||
|
||||
static const size_t SAMPLE_SIZE = SAMPLE_SIZE_; ///< The number of samples averaged over.
|
||||
static const size_t SCALING = SCALING_; ///< The sample scaling factor.
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
/// \param initial_value The initial value for the average.
|
||||
//*************************************************************************
|
||||
cumulative_moving_average(const T initial_value)
|
||||
: average(initial_value * SCALE)
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Clears the average.
|
||||
/// \param initial_value The initial value for the average.
|
||||
//*************************************************************************
|
||||
void clear(const T initial_value)
|
||||
{
|
||||
average = (initial_value * SCALE);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Adds a new sample to the average.
|
||||
/// \param new_value The value to add.
|
||||
//*************************************************************************
|
||||
void add(T new_value)
|
||||
{
|
||||
average *= SAMPLES;
|
||||
average += SCALE * new_value;
|
||||
average /= SAMPLES + sample_t(1);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the current cumulative average.
|
||||
/// \return The current average.
|
||||
//*************************************************************************
|
||||
T value() const
|
||||
{
|
||||
return average;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T average; ///< The current cumulative average.
|
||||
};
|
||||
|
||||
//***************************************************************************
|
||||
/// Cumulative Moving Average
|
||||
/// For floating point types.
|
||||
/// \tparam T The sample value type.
|
||||
/// \tparam SAMPLE_SIZE The number of samples to average over.
|
||||
//***************************************************************************
|
||||
template <typename T, const size_t SAMPLE_SIZE_>
|
||||
class cumulative_moving_average<T, SAMPLE_SIZE_, 1U, false, true>
|
||||
{
|
||||
public:
|
||||
|
||||
static const size_t SAMPLE_SIZE = SAMPLE_SIZE_;
|
||||
|
||||
//*************************************************************************
|
||||
/// Constructor
|
||||
/// \param initial_value The initial value for the average.
|
||||
//*************************************************************************
|
||||
cumulative_moving_average(const T initial_value)
|
||||
: sample_size(T(SAMPLE_SIZE_)),
|
||||
sample_size_plus_1(T(SAMPLE_SIZE_ + 1)),
|
||||
average(initial_value)
|
||||
{
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Clears the average.
|
||||
/// \param initial_value The initial value for the average.
|
||||
//*************************************************************************
|
||||
void clear(const T initial_value)
|
||||
{
|
||||
average = initial_value;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Adds a new sample to the average.
|
||||
/// \param new_value The value to add.
|
||||
//*************************************************************************
|
||||
void add(const T new_value)
|
||||
{
|
||||
average *= sample_size;
|
||||
average += new_value;
|
||||
average /= sample_size_plus_1;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Gets the current cumulative average.
|
||||
/// \return The current average.
|
||||
//*************************************************************************
|
||||
T value() const
|
||||
{
|
||||
return average;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const T sample_size; ///< The sample size to average over.
|
||||
const T sample_size_plus_1; ///< One greater than the sample size.
|
||||
T average; ///< The current cumulative average.
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
356
include/etl/scaled_rounding.h
Normal file
356
include/etl/scaled_rounding.h
Normal file
@ -0,0 +1,356 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2018 jwellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_SCALED_ROUNDING_INCLUDED
|
||||
#define ETL_SCALED_ROUNDING_INCLUDED
|
||||
|
||||
#include "static_assert.h"
|
||||
#include "type_traits.h"
|
||||
#include "absolute.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
struct scaled_rounding_t
|
||||
{
|
||||
typedef typename etl::conditional<etl::is_signed<T>::value, int32_t, uint32_t>::type type;
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
/// A set of rounding algorithms for scaled integrals.
|
||||
/// \tparam T The integral type.
|
||||
/// \tparam SCALING The scaling factor.
|
||||
///
|
||||
/// \example For emulating fixed point of two decimal places we could use a
|
||||
/// scaling factor of '100'. To round the result of scaled int calculations
|
||||
/// using 'Banker's Rounding' we would define this.
|
||||
/// \code
|
||||
/// typedef etl::scaled_rounding<int, 100> Rounding;
|
||||
/// int final_result = Rounding::round_half_even_unscaled(accumulated_result);
|
||||
/// \endcode
|
||||
/// \link http://www.clivemaxfield.com/diycalculator/sp-round.shtml
|
||||
//*****************************************************************************
|
||||
|
||||
//***************************************************************************
|
||||
/// Round to more positive integer.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_ceiling_unscaled(T value)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
if (value >= 0)
|
||||
{
|
||||
return T((value + scale_t(SCALING)) / scale_t(SCALING));
|
||||
}
|
||||
else
|
||||
{
|
||||
return T(value / scale_t(SCALING));
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round to more positive integer.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Scaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_ceiling_scaled(T value)
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return round_ceiling_unscaled<SCALING>(value) * scale_t(SCALING);
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round to more negative integer.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_floor_unscaled(T value)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
if (value >= 0)
|
||||
{
|
||||
return T(value / scale_t(SCALING));
|
||||
}
|
||||
else
|
||||
{
|
||||
return T((value - scale_t(SCALING)) / scale_t(SCALING));
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round to more negative integer.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Scaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_floor_scaled(T value)
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(round_floor_unscaled<SCALING>(value) * scale_t(SCALING));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round to nearest integer. 'Half' value is rounded up (to infinity).
|
||||
/// Uses 'symmetric up' rounding.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_half_up_unscaled(T value)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
ETL_STATIC_ASSERT((((SCALING / 2U) * 2U) == SCALING), "Scaling must be divisible by 2");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
if (value >= 0)
|
||||
{
|
||||
return T((value + scale_t(SCALING / 2U)) / scale_t(SCALING));
|
||||
}
|
||||
else
|
||||
{
|
||||
return T((value - scale_t(SCALING / 2U)) / scale_t(SCALING));
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round to nearest integer. 'Half' value is rounded up (to infinity).
|
||||
/// Uses 'symmetric up' rounding.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Scaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_half_up_scaled(T value)
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(round_half_up_unscaled<SCALING>(value) * scale_t(SCALING));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round to nearest integer. 'Half' value is rounded down (to zero).
|
||||
/// Uses 'symmetric down' rounding.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_half_down_unscaled(T value)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
ETL_STATIC_ASSERT((((SCALING / 2U) * 2U) == SCALING), "Scaling must be divisible by 2");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
if (value >= 0)
|
||||
{
|
||||
return T((value + scale_t((SCALING / 2U) - 1U)) / scale_t(SCALING));
|
||||
}
|
||||
else
|
||||
{
|
||||
return T((value - scale_t((SCALING / 2U) - 1U)) / scale_t(SCALING));
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round to nearest integer. 'Half' value is rounded down (to zero).
|
||||
/// Uses 'symmetric down' rounding.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Scaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_half_down_scaled(T value)
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(round_half_down_unscaled<SCALING>(value) * scale_t(SCALING));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round toward zero.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_zero_unscaled(T value)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(value / scale_t(SCALING));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round toward zero.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Scaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_zero_scaled(T value)
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(round_zero_unscaled<SCALING>(value) * scale_t(SCALING));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round toward infinity.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_infinity_unscaled(T value)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
if (value >= 0)
|
||||
{
|
||||
return T((value + scale_t(SCALING)) / scale_t(SCALING));
|
||||
}
|
||||
else
|
||||
{
|
||||
return T((value - scale_t(SCALING)) / scale_t(SCALING));
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round toward infinity.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Ccaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_infinity_scaled(T value)
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(round_infinity_unscaled<SCALING>(value) * scale_t(SCALING));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round to nearest integer. 'Half' value is rounded to even integral.
|
||||
/// Also known as 'Banker's Rounding'.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_half_even_unscaled(T value)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
// Half?
|
||||
if ((etl::absolute(value) % scale_t(SCALING)) == scale_t(SCALING / 2U))
|
||||
{
|
||||
// Odd?
|
||||
if ((value / scale_t(SCALING)) & 1U)
|
||||
{
|
||||
return T(round_half_up_unscaled<SCALING>(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
return T(round_half_down_unscaled<SCALING>(value));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return T(round_half_up_unscaled<SCALING>(value));
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round to nearest integer. 'Half' value is rounded to even integral.
|
||||
/// Also known as 'Banker's Rounding'.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Scaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_half_even_scaled(T value)
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(round_half_even_unscaled<SCALING>(value) * scale_t(SCALING));
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round to nearest integer. 'Half' value is rounded to odd integral.
|
||||
/// Also known as 'Banker's Rounding'.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Unscaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_half_odd_unscaled(T value)
|
||||
{
|
||||
ETL_STATIC_ASSERT(etl::is_integral<T>::value, "Type must be an integral");
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
// Half?
|
||||
if ((etl::absolute(value) % scale_t(SCALING)) == scale_t(SCALING / 2U))
|
||||
{
|
||||
// Odd?
|
||||
if ((value / scale_t(SCALING)) & 1U)
|
||||
{
|
||||
return T(round_half_down_unscaled<SCALING>(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
return T(round_half_up_unscaled<SCALING>(value));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return T(round_half_up_unscaled<SCALING>(value));
|
||||
}
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// Round to nearest integer. 'Half' value is rounded to odd integral.
|
||||
/// Also known as 'Banker's Rounding'.
|
||||
/// \param value Scaled integral.
|
||||
/// \return Scaled, rounded integral.
|
||||
//***************************************************************************
|
||||
template <const size_t SCALING, typename T>
|
||||
T round_half_odd_scaled(T value)
|
||||
{
|
||||
typedef typename scaled_rounding_t<T>::type scale_t;
|
||||
|
||||
return T(round_half_odd_unscaled<SCALING>(value) * scale_t(SCALING));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -38,8 +38,8 @@ SOFTWARE.
|
||||
///\ingroup utilities
|
||||
|
||||
#define ETL_VERSION_MAJOR 14
|
||||
#define ETL_VERSION_MINOR 5
|
||||
#define ETL_VERSION_PATCH 1
|
||||
#define ETL_VERSION_MINOR 6
|
||||
#define ETL_VERSION_PATCH 0
|
||||
|
||||
#define ETL_VERSION ETL_STRINGIFY(ETL_VERSION_MAJOR) ETL_STRINGIFY(ETL_VERSION_MINOR) ETL_STRINGIFY(ETL_VERSION_PATCH)
|
||||
#define ETL_VERSION_W ETL_WIDE_STRING(ETL_CONCAT(ETL_CONCAT(ETL_VERSION_MAJOR, ETL_VERSION_MINOR), ETL_VERSION_PATCH))
|
||||
|
||||
@ -1,3 +1,14 @@
|
||||
===============================================================================
|
||||
14.6.0
|
||||
Added etl::scaled_rounding to allow selection of rounding algorithms when
|
||||
emulating fixed point arithmetic with scaled integral values.
|
||||
|
||||
Added etl::cumulating_moving_average, implementing an algorithm for
|
||||
calculating an average for a stream of samples. There are specialisations
|
||||
for floating point and scaled integral sample types.
|
||||
|
||||
Added C++11 rvalue reference 'push' functions for etl::deque.
|
||||
|
||||
===============================================================================
|
||||
14.5.1
|
||||
Fixed deque pushes for literals.
|
||||
|
||||
@ -413,6 +413,7 @@
|
||||
<Unit filename="../test_reference_flat_multimap.cpp" />
|
||||
<Unit filename="../test_reference_flat_multiset.cpp" />
|
||||
<Unit filename="../test_reference_flat_set.cpp" />
|
||||
<Unit filename="../test_scaled_rounding.cpp" />
|
||||
<Unit filename="../test_set.cpp" />
|
||||
<Unit filename="../test_smallest.cpp" />
|
||||
<Unit filename="../test_stack.cpp" />
|
||||
|
||||
125
test/test_cumulative_moving_average.cpp
Normal file
125
test/test_cumulative_moving_average.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2018 jwellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "UnitTest++.h"
|
||||
|
||||
#include "etl/cumulative_moving_average.h"
|
||||
#include "etl/scaled_rounding.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
const size_t SAMPLE_SIZE = 10U;
|
||||
const size_t SCALING = 100U;
|
||||
|
||||
SUITE(test_cumulative_moving_average)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST(integral_signed_average_positive)
|
||||
{
|
||||
typedef etl::cumulative_moving_average<int, SAMPLE_SIZE, SCALING> CMA;
|
||||
CMA cma(0);
|
||||
|
||||
CHECK_EQUAL(0, cma.value());
|
||||
|
||||
cma.add(9);
|
||||
cma.add(1);
|
||||
cma.add(8);
|
||||
cma.add(2);
|
||||
cma.add(7);
|
||||
cma.add(3);
|
||||
cma.add(6);
|
||||
cma.add(4);
|
||||
cma.add(5);
|
||||
|
||||
CHECK_EQUAL(280, cma.value());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(integral_signed_average_negative)
|
||||
{
|
||||
typedef etl::cumulative_moving_average<int, SAMPLE_SIZE, SCALING> CMA;
|
||||
CMA cma(0);
|
||||
|
||||
CHECK_EQUAL(0, cma.value());
|
||||
|
||||
cma.add(-9);
|
||||
cma.add(-1);
|
||||
cma.add(-8);
|
||||
cma.add(-2);
|
||||
cma.add(-7);
|
||||
cma.add(-3);
|
||||
cma.add(-6);
|
||||
cma.add(-4);
|
||||
cma.add(-5);
|
||||
|
||||
CHECK_EQUAL(-280, cma.value());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(integral_unsigned_average_positive)
|
||||
{
|
||||
typedef etl::cumulative_moving_average<unsigned int, SAMPLE_SIZE, SCALING> CMA;
|
||||
CMA cma(0U);
|
||||
|
||||
CHECK_EQUAL(0U, cma.value());
|
||||
|
||||
cma.add(9U);
|
||||
cma.add(1U);
|
||||
cma.add(8U);
|
||||
cma.add(2U);
|
||||
cma.add(7U);
|
||||
cma.add(3U);
|
||||
cma.add(6U);
|
||||
cma.add(4U);
|
||||
cma.add(5U);
|
||||
|
||||
CHECK_EQUAL(280U, cma.value());
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(floating_point_average)
|
||||
{
|
||||
typedef etl::cumulative_moving_average<double, SAMPLE_SIZE> CMA;
|
||||
CMA cma(0);
|
||||
|
||||
CHECK_EQUAL(0.0, cma.value());
|
||||
|
||||
cma.add(9.0);
|
||||
cma.add(1.0);
|
||||
cma.add(8.0);
|
||||
cma.add(2.0);
|
||||
cma.add(7.0);
|
||||
cma.add(3.0);
|
||||
cma.add(6.0);
|
||||
cma.add(4.0);
|
||||
cma.add(5.0);
|
||||
|
||||
CHECK_CLOSE(2.82, cma.value(), 0.01);
|
||||
}
|
||||
};
|
||||
}
|
||||
345
test/test_scaled_rounding.cpp
Normal file
345
test/test_scaled_rounding.cpp
Normal file
@ -0,0 +1,345 @@
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2018 jwellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "UnitTest++.h"
|
||||
|
||||
#include "etl/scaled_rounding.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace
|
||||
{
|
||||
std::array<int, 12> source = { 54, 55, 56, 64, 65, 66, -54, -55, -56, -64, -65, -66 };
|
||||
|
||||
SUITE(test_scaled_rounding)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST(round_ceiling_scaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 60, 60, 60, 70, 70, 70, -50, -50, -50, -60, -60, -60 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_ceiling_scaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_ceiling_scaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_ceiling_scaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_ceiling_scaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_ceiling_scaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_ceiling_scaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_ceiling_scaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_ceiling_scaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_ceiling_scaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_ceiling_scaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_ceiling_scaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_ceiling_scaled<10>(source[11]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(round_ceiling_unscaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 6, 6, 6, 7, 7, 7, -5, -5, -5, -6, -6, -6 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_ceiling_unscaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_ceiling_unscaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_ceiling_unscaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_ceiling_unscaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_ceiling_unscaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_ceiling_unscaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_ceiling_unscaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_ceiling_unscaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_ceiling_unscaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_ceiling_unscaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_ceiling_unscaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_ceiling_unscaled<10>(source[11]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(round_floor_scaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 50, 50, 50, 60, 60, 60, -60, -60, -60, -70, -70, -70 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_floor_scaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_floor_scaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_floor_scaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_floor_scaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_floor_scaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_floor_scaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_floor_scaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_floor_scaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_floor_scaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_floor_scaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_floor_scaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_floor_scaled<10>(source[11]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(round_floor_unscaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 5, 5, 5, 6, 6, 6, -6, -6, -6, -7, -7, -7 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_floor_unscaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_floor_unscaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_floor_unscaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_floor_unscaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_floor_unscaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_floor_unscaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_floor_unscaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_floor_unscaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_floor_unscaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_floor_unscaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_floor_unscaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_floor_unscaled<10>(source[11]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(round_half_up_scaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 50, 60, 60, 60, 70, 70, -50, -60, -60, -60, -70, -70 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_half_up_scaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_half_up_scaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_half_up_scaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_half_up_scaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_half_up_scaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_half_up_scaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_half_up_scaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_half_up_scaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_half_up_scaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_half_up_scaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_half_up_scaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_half_up_scaled<10>(source[11]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(round_half_up_unscaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 5, 6, 6, 6, 7, 7, -5, -6, -6, -6, -7, -7 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_half_up_unscaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_half_up_unscaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_half_up_unscaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_half_up_unscaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_half_up_unscaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_half_up_unscaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_half_up_unscaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_half_up_unscaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_half_up_unscaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_half_up_unscaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_half_up_unscaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_half_up_unscaled<10>(source[11]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(round_half_down_scaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 50, 50, 60, 60, 60, 70, -50, -50, -60, -60, -60, -70 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_half_down_scaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_half_down_scaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_half_down_scaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_half_down_scaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_half_down_scaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_half_down_scaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_half_down_scaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_half_down_scaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_half_down_scaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_half_down_scaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_half_down_scaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_half_down_scaled<10>(source[11]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(round_half_down_unscaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 5, 5, 6, 6, 6, 7, -5, -5, -6, -6, -6, -7 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_half_down_unscaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_half_down_unscaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_half_down_unscaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_half_down_unscaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_half_down_unscaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_half_down_unscaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_half_down_unscaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_half_down_unscaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_half_down_unscaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_half_down_unscaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_half_down_unscaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_half_down_unscaled<10>(source[11]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(round_zero_scaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 50, 50, 50, 60, 60, 60, -50, -50, -50, -60, -60, -60 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_zero_scaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_zero_scaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_zero_scaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_zero_scaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_zero_scaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_zero_scaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_zero_scaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_zero_scaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_zero_scaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_zero_scaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_zero_scaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_zero_scaled<10>(source[11]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(round_zero_unscaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 5, 5, 5, 6, 6, 6, -5, -5, -5, -6, -6, -6 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_zero_unscaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_zero_unscaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_zero_unscaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_zero_unscaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_zero_unscaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_zero_unscaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_zero_unscaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_zero_unscaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_zero_unscaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_zero_unscaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_zero_unscaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_zero_unscaled<10>(source[11]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(round_infinity_scaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 60, 60, 60, 70, 70, 70, -60, -60, -60, -70, -70, -70 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_infinity_scaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_infinity_scaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_infinity_scaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_infinity_scaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_infinity_scaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_infinity_scaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_infinity_scaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_infinity_scaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_infinity_scaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_infinity_scaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_infinity_scaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_infinity_scaled<10>(source[11]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(round_infinity_unscaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 6, 6, 6, 7, 7, 7, -6, -6, -6, -7, -7, -7 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_infinity_unscaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_infinity_unscaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_infinity_unscaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_infinity_unscaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_infinity_unscaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_infinity_unscaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_infinity_unscaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_infinity_unscaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_infinity_unscaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_infinity_unscaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_infinity_unscaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_infinity_unscaled<10>(source[11]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(round_half_even_scaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 50, 60, 60, 60, 60, 70, -50, -60, -60, -60, -60, -70 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_half_even_scaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_half_even_scaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_half_even_scaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_half_even_scaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_half_even_scaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_half_even_scaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_half_even_scaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_half_even_scaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_half_even_scaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_half_even_scaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_half_even_scaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_half_even_scaled<10>(source[11]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(round_half_even_unscaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 5, 6, 6, 6, 6, 7, -5, -6, -6, -6, -6, -7 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_half_even_unscaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_half_even_unscaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_half_even_unscaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_half_even_unscaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_half_even_unscaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_half_even_unscaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_half_even_unscaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_half_even_unscaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_half_even_unscaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_half_even_unscaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_half_even_unscaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_half_even_unscaled<10>(source[11]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(round_half_odd_scaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 50, 50, 60, 60, 70, 70, -50, -50, -60, -60, -70, -70 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_half_odd_scaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_half_odd_scaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_half_odd_scaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_half_odd_scaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_half_odd_scaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_half_odd_scaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_half_odd_scaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_half_odd_scaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_half_odd_scaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_half_odd_scaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_half_odd_scaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_half_odd_scaled<10>(source[11]));
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(round_half_odd_unscaled)
|
||||
{
|
||||
std::array<int, 12> expected = { 5, 5, 6, 6, 7, 7, -5, -5, -6, -6, -7, -7 };
|
||||
|
||||
CHECK_EQUAL(expected[0], etl::round_half_odd_unscaled<10>(source[0]));
|
||||
CHECK_EQUAL(expected[1], etl::round_half_odd_unscaled<10>(source[1]));
|
||||
CHECK_EQUAL(expected[2], etl::round_half_odd_unscaled<10>(source[2]));
|
||||
CHECK_EQUAL(expected[3], etl::round_half_odd_unscaled<10>(source[3]));
|
||||
CHECK_EQUAL(expected[4], etl::round_half_odd_unscaled<10>(source[4]));
|
||||
CHECK_EQUAL(expected[5], etl::round_half_odd_unscaled<10>(source[5]));
|
||||
CHECK_EQUAL(expected[6], etl::round_half_odd_unscaled<10>(source[6]));
|
||||
CHECK_EQUAL(expected[7], etl::round_half_odd_unscaled<10>(source[7]));
|
||||
CHECK_EQUAL(expected[8], etl::round_half_odd_unscaled<10>(source[8]));
|
||||
CHECK_EQUAL(expected[9], etl::round_half_odd_unscaled<10>(source[9]));
|
||||
CHECK_EQUAL(expected[10], etl::round_half_odd_unscaled<10>(source[10]));
|
||||
CHECK_EQUAL(expected[11], etl::round_half_odd_unscaled<10>(source[11]));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -369,10 +369,13 @@
|
||||
<ClInclude Include="..\..\include\etl\constant.h" />
|
||||
<ClInclude Include="..\..\include\etl\crc16_modbus.h" />
|
||||
<ClInclude Include="..\..\include\etl\crc32_c.h" />
|
||||
<ClInclude Include="..\..\include\etl\cumulative_moving_average.h" />
|
||||
<ClInclude Include="..\..\include\etl\c\ecl_timer.h" />
|
||||
<ClInclude Include="..\..\include\etl\fsm.h" />
|
||||
<ClInclude Include="..\..\include\etl\fsm_generator.h" />
|
||||
<ClInclude Include="..\..\include\etl\largest_generator.h" />
|
||||
<ClInclude Include="..\..\include\etl\absolute.h" />
|
||||
<ClInclude Include="..\..\include\etl\scaled_rounding.h" />
|
||||
<ClInclude Include="..\..\include\etl\state_chart.h" />
|
||||
<ClInclude Include="..\..\include\etl\math_constants.h" />
|
||||
<ClInclude Include="..\..\include\etl\memory_model.h" />
|
||||
@ -561,6 +564,7 @@
|
||||
<ClCompile Include="..\murmurhash3.cpp" />
|
||||
<ClCompile Include="..\test_algorithm.cpp" />
|
||||
<ClCompile Include="..\test_alignment.cpp" />
|
||||
<ClCompile Include="..\test_cumulative_moving_average.cpp" />
|
||||
<ClCompile Include="..\test_forward_list_shared_pool.cpp" />
|
||||
<ClCompile Include="..\test_bit_stream.cpp" />
|
||||
<ClCompile Include="..\test_list_shared_pool.cpp" />
|
||||
@ -720,6 +724,7 @@
|
||||
<ClCompile Include="..\test_reference_flat_multimap.cpp" />
|
||||
<ClCompile Include="..\test_reference_flat_multiset.cpp" />
|
||||
<ClCompile Include="..\test_reference_flat_set.cpp" />
|
||||
<ClCompile Include="..\test_scaled_rounding.cpp" />
|
||||
<ClCompile Include="..\test_set.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
|
||||
@ -711,6 +711,15 @@
|
||||
<ClInclude Include="..\..\include\etl\crc16_modbus.h">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\etl\cumulative_moving_average.h">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\etl\scaled_rounding.h">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\etl\absolute.h">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\main.cpp">
|
||||
@ -1127,8 +1136,11 @@
|
||||
<ClCompile Include="..\test_state_chart.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\crc16_modbus.cpp">
|
||||
<Filter>ETL\Maths</Filter>
|
||||
<ClCompile Include="..\test_scaled_rounding.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\test_cumulative_moving_average.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user