From 9133c3df4640423203eee8e1f9f269904c0cb69a Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Wed, 23 Sep 2026 11:22:58 +0100 Subject: [PATCH] Cleanup of duplicated code. --- include/etl/format.h | 87 ++++---------------------- include/etl/math.h | 55 ++++++++-------- include/etl/platform.h | 2 +- include/etl/private/to_string_helper.h | 4 +- test/test_math.cpp | 18 ------ 5 files changed, 40 insertions(+), 126 deletions(-) diff --git a/include/etl/format.h b/include/etl/format.h index 288454fd..05d05896 100644 --- a/include/etl/format.h +++ b/include/etl/format.h @@ -47,10 +47,6 @@ SOFTWARE. #include "variant.h" #include "visitor.h" -#if ETL_USING_FORMAT_FLOATING_POINT - #include -#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(::log10(static_cast(value))); - } - inline long double format_floor(long double value) - { - return static_cast(::floor(static_cast(value))); - } - inline long double format_pow(long double base, long double exp) - { - return static_cast(::pow(static_cast(base), static_cast(exp))); - } - inline long double format_round(long double value) - { - return static_cast(::round(static_cast(value))); - } - inline long double format_modf(long double value, long double* iptr) - { - double d_iptr; - double result = ::modf(static_cast(value), &d_iptr); - *iptr = static_cast(d_iptr); - return static_cast(result); - } - #endif - - template - T format_log10(T value) - { - return ::log10(value); - } - template - T format_floor(T value) - { - return ::floor(value); - } - template - T format_pow(T base, T exp) - { - return ::pow(base, exp); - } - template - T format_round(T value) - { - return ::round(value); - } - template - T format_modf(T value, T* iptr) - { - return ::modf(value, iptr); - } - template 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(10, fractional_decimals); - unsigned long long int fractional_int = static_cast(format_round(fractional * scale)); + unsigned long long int fractional_int = static_cast(etl::clib::round(fractional * scale)); unsigned long long int integral_int = static_cast(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(0x10, fractional_decimals); - unsigned long long int fractional_int = static_cast(format_round(fractional * scale)); + unsigned long long int fractional_int = static_cast(etl::clib::round(fractional * scale)); unsigned long long int integral_int = static_cast(integral); if (fractional_int == scale) @@ -1924,8 +1861,8 @@ namespace etl if (abs_value > static_cast(0)) { - exponent_int = static_cast(format_floor(format_log10(abs_value))); - value = abs_value / format_pow(static_cast(10), static_cast(exponent_int)); + exponent_int = static_cast(etl::clib::floor(etl::clib::log10(abs_value))); + value = abs_value / etl::clib::pow(static_cast(10), static_cast(exponent_int)); // Correct for floating-point rounding in log10/pow if (value >= static_cast(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(10, fractional_decimals); - unsigned long long int fractional_int = static_cast(format_round(fractional * scale)); + unsigned long long int fractional_int = static_cast(etl::clib::round(fractional * scale)); unsigned long long int integral_int = static_cast(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(10, fractional_decimals); - unsigned long long int fractional_int = static_cast(format_round(fractional * scale)); + unsigned long long int fractional_int = static_cast(etl::clib::round(fractional * scale)); unsigned long long int integral_int = static_cast(integral); if (fractional_int == scale) diff --git a/include/etl/math.h b/include/etl/math.h index 1856ef1b..575afbfc 100644 --- a/include/etl/math.h +++ b/include/etl/math.h @@ -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 and 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(::fabs(static_cast(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 { diff --git a/include/etl/platform.h b/include/etl/platform.h index 3e936a82..9305461d 100644 --- a/include/etl/platform.h +++ b/include/etl/platform.h @@ -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 diff --git a/include/etl/private/to_string_helper.h b/include/etl/private/to_string_helper.h index 254116b4..56bc0eae 100644 --- a/include/etl/private/to_string_helper.h +++ b/include/etl/private/to_string_helper.h @@ -44,8 +44,6 @@ SOFTWARE. #include "../negative.h" #include "../type_traits.h" -#include - #if ETL_USING_STL && ETL_USING_CPP11 #include // For std::begin, std::end and std::size #endif @@ -351,7 +349,7 @@ namespace etl uworkspace_t integral = static_cast(f_integral); // Find the fractional part of the floating point. - uworkspace_t fractional = static_cast(::round((scaled - f_integral) * multiplier)); + uworkspace_t fractional = static_cast(etl::clib::round((scaled - f_integral) * multiplier)); // Check for a rounding carry to the integral. if (fractional == multiplier) diff --git a/test/test_math.cpp b/test/test_math.cpp index 302e487f..258590ee 100644 --- a/test/test_math.cpp +++ b/test/test_math.cpp @@ -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) {