mirror of
https://github.com/ETLCPP/etl.git
synced 2026-10-28 18:07:10 +08:00
Cleanup of duplicated code.
This commit is contained in:
parent
59204cf3a0
commit
9133c3df46
@ -47,10 +47,6 @@ SOFTWARE.
|
||||
#include "variant.h"
|
||||
#include "visitor.h"
|
||||
|
||||
#if ETL_USING_FORMAT_FLOATING_POINT
|
||||
#include <cmath>
|
||||
#endif
|
||||
|
||||
#if ETL_USING_CPP11
|
||||
|
||||
namespace etl
|
||||
@ -1740,65 +1736,6 @@ namespace etl
|
||||
double, long double>
|
||||
long_double_format_type;
|
||||
|
||||
#if ETL_NOT_USING_FORMAT_LONG_DOUBLE_MATH
|
||||
//***********************************
|
||||
// Math function wrappers to handle toolchains that don't provide
|
||||
// long double math functions (log10l, floorl, powl, modfl, roundl).
|
||||
// When ETL_FORMAT_NO_LONG_DOUBLE_MATH is defined, long double overloads
|
||||
// cast through double. For float and double, the standard functions are
|
||||
// called directly via the template versions.
|
||||
//***********************************
|
||||
inline long double format_log10(long double value)
|
||||
{
|
||||
return static_cast<long double>(::log10(static_cast<double>(value)));
|
||||
}
|
||||
inline long double format_floor(long double value)
|
||||
{
|
||||
return static_cast<long double>(::floor(static_cast<double>(value)));
|
||||
}
|
||||
inline long double format_pow(long double base, long double exp)
|
||||
{
|
||||
return static_cast<long double>(::pow(static_cast<double>(base), static_cast<double>(exp)));
|
||||
}
|
||||
inline long double format_round(long double value)
|
||||
{
|
||||
return static_cast<long double>(::round(static_cast<double>(value)));
|
||||
}
|
||||
inline long double format_modf(long double value, long double* iptr)
|
||||
{
|
||||
double d_iptr;
|
||||
double result = ::modf(static_cast<double>(value), &d_iptr);
|
||||
*iptr = static_cast<long double>(d_iptr);
|
||||
return static_cast<long double>(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
T format_log10(T value)
|
||||
{
|
||||
return ::log10(value);
|
||||
}
|
||||
template <typename T>
|
||||
T format_floor(T value)
|
||||
{
|
||||
return ::floor(value);
|
||||
}
|
||||
template <typename T>
|
||||
T format_pow(T base, T exp)
|
||||
{
|
||||
return ::pow(base, exp);
|
||||
}
|
||||
template <typename T>
|
||||
T format_round(T value)
|
||||
{
|
||||
return ::round(value);
|
||||
}
|
||||
template <typename T>
|
||||
T format_modf(T value, T* iptr)
|
||||
{
|
||||
return ::modf(value, iptr);
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename T>
|
||||
void format_floating_default(OutputIt& it, T value, const format_spec_t& spec)
|
||||
{
|
||||
@ -1819,7 +1756,7 @@ namespace etl
|
||||
}
|
||||
|
||||
T integral;
|
||||
T fractional = format_modf(value, &integral);
|
||||
T fractional = etl::clib::modf(value, &integral);
|
||||
|
||||
// Take absolute values to avoid casting negative values to unsigned
|
||||
if (sign)
|
||||
@ -1829,7 +1766,7 @@ namespace etl
|
||||
}
|
||||
|
||||
unsigned long long int scale = int_pow<unsigned long long int>(10, fractional_decimals);
|
||||
unsigned long long int fractional_int = static_cast<unsigned long long int>(format_round(fractional * scale));
|
||||
unsigned long long int fractional_int = static_cast<unsigned long long int>(etl::clib::round(fractional * scale));
|
||||
unsigned long long int integral_int = static_cast<unsigned long long int>(integral);
|
||||
|
||||
if (fractional_int == scale)
|
||||
@ -1856,20 +1793,20 @@ namespace etl
|
||||
bool sign = signbit(value);
|
||||
|
||||
T integral;
|
||||
T fractional = format_modf(value, &integral);
|
||||
T fractional = etl::clib::modf(value, &integral);
|
||||
|
||||
while (value >= 0x10 || value <= -0x10)
|
||||
{
|
||||
++exponent_int;
|
||||
value /= 0x10;
|
||||
fractional = format_modf(value, &integral);
|
||||
fractional = etl::clib::modf(value, &integral);
|
||||
}
|
||||
|
||||
while ((value > 0.0000000000001 && value < 1) || (value < -0.0000000000001 && value > -1))
|
||||
{
|
||||
--exponent_int;
|
||||
value *= 0x10;
|
||||
fractional = format_modf(value, &integral);
|
||||
fractional = etl::clib::modf(value, &integral);
|
||||
}
|
||||
|
||||
// Take absolute values to avoid casting negative values to unsigned
|
||||
@ -1880,7 +1817,7 @@ namespace etl
|
||||
}
|
||||
|
||||
unsigned long long int scale = int_pow<unsigned long long int>(0x10, fractional_decimals);
|
||||
unsigned long long int fractional_int = static_cast<unsigned long long int>(format_round(fractional * scale));
|
||||
unsigned long long int fractional_int = static_cast<unsigned long long int>(etl::clib::round(fractional * scale));
|
||||
unsigned long long int integral_int = static_cast<unsigned long long int>(integral);
|
||||
|
||||
if (fractional_int == scale)
|
||||
@ -1924,8 +1861,8 @@ namespace etl
|
||||
|
||||
if (abs_value > static_cast<T>(0))
|
||||
{
|
||||
exponent_int = static_cast<long long int>(format_floor(format_log10(abs_value)));
|
||||
value = abs_value / format_pow(static_cast<T>(10), static_cast<T>(exponent_int));
|
||||
exponent_int = static_cast<long long int>(etl::clib::floor(etl::clib::log10(abs_value)));
|
||||
value = abs_value / etl::clib::pow(static_cast<T>(10), static_cast<T>(exponent_int));
|
||||
// Correct for floating-point rounding in log10/pow
|
||||
if (value >= static_cast<T>(10))
|
||||
{
|
||||
@ -1944,10 +1881,10 @@ namespace etl
|
||||
}
|
||||
|
||||
T integral;
|
||||
T fractional = format_modf(value, &integral);
|
||||
T fractional = etl::clib::modf(value, &integral);
|
||||
|
||||
unsigned long long int scale = int_pow<unsigned long long int>(10, fractional_decimals);
|
||||
unsigned long long int fractional_int = static_cast<unsigned long long int>(format_round(fractional * scale));
|
||||
unsigned long long int fractional_int = static_cast<unsigned long long int>(etl::clib::round(fractional * scale));
|
||||
unsigned long long int integral_int = static_cast<unsigned long long int>(integral);
|
||||
|
||||
if (fractional_int == scale)
|
||||
@ -1985,7 +1922,7 @@ namespace etl
|
||||
bool sign = signbit(value);
|
||||
|
||||
T integral;
|
||||
T fractional = format_modf(value, &integral);
|
||||
T fractional = etl::clib::modf(value, &integral);
|
||||
|
||||
// Take absolute values to avoid casting negative values to unsigned
|
||||
if (sign)
|
||||
@ -1995,7 +1932,7 @@ namespace etl
|
||||
}
|
||||
|
||||
unsigned long long int scale = int_pow<unsigned long long int>(10, fractional_decimals);
|
||||
unsigned long long int fractional_int = static_cast<unsigned long long int>(format_round(fractional * scale));
|
||||
unsigned long long int fractional_int = static_cast<unsigned long long int>(etl::clib::round(fractional * scale));
|
||||
unsigned long long int integral_int = static_cast<unsigned long long int>(integral);
|
||||
|
||||
if (fractional_int == scale)
|
||||
|
||||
@ -132,6 +132,14 @@ namespace etl
|
||||
}
|
||||
#include "private/diagnostic_pop.h"
|
||||
|
||||
//***************************************************************************
|
||||
// These functions wrap the C library math functions.
|
||||
// The functions are overloaded for the different floating point types.
|
||||
// They provide a consistent interface for float, double and long double.
|
||||
// They are in the clib namespace to avoid conflicts with the C library and ETL functions.
|
||||
// These take the place of std::floor, std::ceil etc which may not be available `No STL` environments.
|
||||
// Avoids unpredictable behaviour for global calls of ::floor, ::ceil etc when both <math.h> and <cmath> are included.
|
||||
//***************************************************************************
|
||||
namespace clib
|
||||
{
|
||||
//***************************************************************************
|
||||
@ -143,6 +151,7 @@ namespace etl
|
||||
return ::floorf(value);
|
||||
}
|
||||
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline double floor(double value) ETL_NOEXCEPT
|
||||
{
|
||||
@ -150,12 +159,14 @@ namespace etl
|
||||
}
|
||||
|
||||
#if ETL_USING_LONG_DOUBLE_MATH
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline long double floor(long double value) ETL_NOEXCEPT
|
||||
{
|
||||
return ::floorl(value);
|
||||
}
|
||||
#else
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline long double floor(long double value) ETL_NOEXCEPT
|
||||
{
|
||||
@ -172,6 +183,7 @@ namespace etl
|
||||
return ::ceilf(value);
|
||||
}
|
||||
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline double ceil(double value) ETL_NOEXCEPT
|
||||
{
|
||||
@ -179,12 +191,14 @@ namespace etl
|
||||
}
|
||||
|
||||
#if ETL_USING_LONG_DOUBLE_MATH
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline long double ceil(long double value) ETL_NOEXCEPT
|
||||
{
|
||||
return ::ceill(value);
|
||||
}
|
||||
#else
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline long double ceil(long double value) ETL_NOEXCEPT
|
||||
{
|
||||
@ -201,6 +215,7 @@ namespace etl
|
||||
return ::log10f(value);
|
||||
}
|
||||
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline double log10(double value) ETL_NOEXCEPT
|
||||
{
|
||||
@ -208,12 +223,14 @@ namespace etl
|
||||
}
|
||||
|
||||
#if ETL_USING_LONG_DOUBLE_MATH
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline long double log10(long double value) ETL_NOEXCEPT
|
||||
{
|
||||
return ::log10l(value);
|
||||
}
|
||||
#else
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline long double log10(long double value) ETL_NOEXCEPT
|
||||
{
|
||||
@ -230,6 +247,7 @@ namespace etl
|
||||
return ::roundf(value);
|
||||
}
|
||||
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline double round(double value) ETL_NOEXCEPT
|
||||
{
|
||||
@ -237,12 +255,14 @@ namespace etl
|
||||
}
|
||||
|
||||
#if ETL_USING_LONG_DOUBLE_MATH
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline long double round(long double value) ETL_NOEXCEPT
|
||||
{
|
||||
return ::roundl(value);
|
||||
}
|
||||
#else
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline long double round(long double value) ETL_NOEXCEPT
|
||||
{
|
||||
@ -250,35 +270,6 @@ namespace etl
|
||||
}
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
// fabs
|
||||
//***************************************************************************
|
||||
ETL_NODISCARD
|
||||
inline float fabs(float value) ETL_NOEXCEPT
|
||||
{
|
||||
return ::fabsf(value);
|
||||
}
|
||||
|
||||
ETL_NODISCARD
|
||||
inline double fabs(double value) ETL_NOEXCEPT
|
||||
{
|
||||
return ::fabs(value);
|
||||
}
|
||||
|
||||
#if ETL_USING_LONG_DOUBLE_MATH
|
||||
ETL_NODISCARD
|
||||
inline long double fabs(long double value) ETL_NOEXCEPT
|
||||
{
|
||||
return ::fabsl(value);
|
||||
}
|
||||
#else
|
||||
ETL_NODISCARD
|
||||
inline long double fabs(long double value) ETL_NOEXCEPT
|
||||
{
|
||||
return static_cast<long double>(::fabs(static_cast<double>(value)));
|
||||
}
|
||||
#endif
|
||||
|
||||
//***************************************************************************
|
||||
// power
|
||||
//***************************************************************************
|
||||
@ -288,6 +279,7 @@ namespace etl
|
||||
return ::powf(base, exponent);
|
||||
}
|
||||
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline double pow(double base, double exponent) ETL_NOEXCEPT
|
||||
{
|
||||
@ -295,12 +287,14 @@ namespace etl
|
||||
}
|
||||
|
||||
#if ETL_USING_LONG_DOUBLE_MATH
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline long double pow(long double base, long double exponent) ETL_NOEXCEPT
|
||||
{
|
||||
return ::powl(base, exponent);
|
||||
}
|
||||
#else
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline long double power(long double base, long double exponent) ETL_NOEXCEPT
|
||||
{
|
||||
@ -317,6 +311,7 @@ namespace etl
|
||||
return ::modff(value, intpart);
|
||||
}
|
||||
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline double modf(double value, double* intpart) ETL_NOEXCEPT
|
||||
{
|
||||
@ -324,12 +319,14 @@ namespace etl
|
||||
}
|
||||
|
||||
#if ETL_USING_LONG_DOUBLE_MATH
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline long double modf(long double value, long double* intpart) ETL_NOEXCEPT
|
||||
{
|
||||
return ::modfl(value, intpart);
|
||||
}
|
||||
#else
|
||||
//*********************************
|
||||
ETL_NODISCARD
|
||||
inline long double modf(long double value, long double* intpart) ETL_NOEXCEPT
|
||||
{
|
||||
|
||||
@ -192,7 +192,7 @@ SOFTWARE.
|
||||
// Define ETL_NO_LONG_DOUBLE_MATH if the toolchain does not provide
|
||||
// long double math functions (log10l, floorl, powl, modfl, roundl).
|
||||
// When defined, long double arguments are cast to double for math operations.
|
||||
#if defined(ETL_NO_LONG_DOUBLE_MATH)
|
||||
#if defined(ETL_NO_LONG_DOUBLE_MATH) || defined(ETL_FORMAT_NO_LONG_DOUBLE_MATH)
|
||||
#define ETL_USING_LONG_DOUBLE_MATH 0
|
||||
#define ETL_NOT_USING_LONG_DOUBLE_MATH 1
|
||||
#else
|
||||
|
||||
@ -44,8 +44,6 @@ SOFTWARE.
|
||||
#include "../negative.h"
|
||||
#include "../type_traits.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#if ETL_USING_STL && ETL_USING_CPP11
|
||||
#include <iterator> // For std::begin, std::end and std::size
|
||||
#endif
|
||||
@ -351,7 +349,7 @@ namespace etl
|
||||
uworkspace_t integral = static_cast<uworkspace_t>(f_integral);
|
||||
|
||||
// Find the fractional part of the floating point.
|
||||
uworkspace_t fractional = static_cast<uworkspace_t>(::round((scaled - f_integral) * multiplier));
|
||||
uworkspace_t fractional = static_cast<uworkspace_t>(etl::clib::round((scaled - f_integral) * multiplier));
|
||||
|
||||
// Check for a rounding carry to the integral.
|
||||
if (fractional == multiplier)
|
||||
|
||||
@ -179,24 +179,6 @@ namespace
|
||||
CHECK_CLOSE(4.0L, etl::clib::log10(ld1), 0.0001L);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_fabs)
|
||||
{
|
||||
float f1 = -1.5f;
|
||||
float f2 = 1.5f;
|
||||
double d1 = -2.5;
|
||||
double d2 = 2.5;
|
||||
long double ld1 = -3.5L;
|
||||
long double ld2 = 3.5L;
|
||||
|
||||
CHECK_CLOSE(1.5f, etl::clib::fabs(f1), 0.0001f);
|
||||
CHECK_CLOSE(1.5f, etl::clib::fabs(f2), 0.0001f);
|
||||
CHECK_CLOSE(2.5, etl::clib::fabs(d1), 0.0001);
|
||||
CHECK_CLOSE(2.5, etl::clib::fabs(d2), 0.0001);
|
||||
CHECK_CLOSE(3.5L, etl::clib::fabs(ld1), 0.0001L);
|
||||
CHECK_CLOSE(3.5L, etl::clib::fabs(ld2), 0.0001L);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST(test_pow)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user