Cleanup of duplicated code.

This commit is contained in:
John Wellbelove 2026-09-23 11:22:58 +01:00
parent 59204cf3a0
commit 9133c3df46
5 changed files with 40 additions and 126 deletions

View File

@ -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)

View File

@ -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
{

View File

@ -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

View File

@ -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)

View File

@ -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)
{