diff --git a/esphome/core/component.cpp b/esphome/core/component.cpp index e5fbb8ba07..41dd32ea66 100644 --- a/esphome/core/component.cpp +++ b/esphome/core/component.cpp @@ -336,10 +336,8 @@ void log_update_interval(const char *tag, PollingComponent *component) { uint32_t update_interval = component->get_update_interval(); if (update_interval == SCHEDULER_DONT_RUN) { ESP_LOGCONFIG(tag, " Update Interval: never"); - } else if (update_interval < 100) { - ESP_LOGCONFIG(tag, " Update Interval: %.3fs", update_interval / 1000.0f); } else { - ESP_LOGCONFIG(tag, " Update Interval: %.1fs", update_interval / 1000.0f); + ESP_LOGCONFIG(tag, " Update Interval: %" PRIu32 ".%03" PRIu32 "s", update_interval / 1000, update_interval % 1000); } } float Component::get_actual_setup_priority() const { diff --git a/esphome/core/helpers.cpp b/esphome/core/helpers.cpp index 6bfe5c9e3c..433d2547b0 100644 --- a/esphome/core/helpers.cpp +++ b/esphome/core/helpers.cpp @@ -568,7 +568,7 @@ size_t value_accuracy_to_buf(std::span buf, float } // Fallback for NaN/Inf/high accuracy/out-of-range - int len = snprintf(buf.data(), buf.size(), "%.*f", accuracy_decimals, value); + int len = snprintf(buf.data(), buf.size(), "%.*f", accuracy_decimals, static_cast(value)); if (len < 0) return 0; return static_cast(len) >= buf.size() ? buf.size() - 1 : static_cast(len); @@ -586,16 +586,30 @@ size_t value_accuracy_with_uom_to_buf(std::span bu } int8_t step_to_accuracy_decimals(float step) { - // use printf %g to find number of digits based on temperature step - char buf[32]; - snprintf(buf, sizeof buf, "%.5g", step); - - std::string str{buf}; - size_t dot_pos = str.find('.'); - if (dot_pos == std::string::npos) + // Decimals needed to show the step at five significant digits, trailing zeros dropped. + if (!std::isfinite(step) || step == 0.0f) return 0; - - return str.length() - dot_pos - 1; + float mantissa = std::fabs(step); + int8_t decimals = 4; // decimals needed for five significant digits when mantissa is in [1, 10) + while (mantissa >= 10.0f) { + mantissa /= 10.0f; + decimals--; + } + while (mantissa < 1.0f) { + mantissa *= 10.0f; + decimals++; + } + if (decimals <= 0) + return 0; + float scaled = mantissa * 10000.0f; + auto digits = static_cast(scaled); + if (scaled - static_cast(digits) >= 0.5f) + digits++; + while (decimals > 0 && digits % 10 == 0) { + digits /= 10; + decimals--; + } + return decimals; } // Map a base64/base64url character to its 6-bit value (0-63) arithmetically. diff --git a/tests/components/core/test_helpers.cpp b/tests/components/core/test_helpers.cpp index a031dcb36f..baf688fc8a 100644 --- a/tests/components/core/test_helpers.cpp +++ b/tests/components/core/test_helpers.cpp @@ -328,10 +328,10 @@ TEST(StepToAccuracyDecimals, RoundsUpToWholeNumber) { } TEST(StepToAccuracyDecimals, OutsideFixedNotationRange) { - // %.5g prints these in exponent form, so the count comes from parsing "1e-05" or "1.2346e+05". - EXPECT_EQ(step_to_accuracy_decimals(0.00001f), 0); + // %.5g would print these in exponent form; the count is now the real one rather than a parse of "1e-05". + EXPECT_EQ(step_to_accuracy_decimals(0.00001f), 5); EXPECT_EQ(step_to_accuracy_decimals(0.000125f), 6); - EXPECT_EQ(step_to_accuracy_decimals(123456.0f), 8); + EXPECT_EQ(step_to_accuracy_decimals(123456.0f), 0); EXPECT_EQ(step_to_accuracy_decimals(1000000.0f), 0); }