mirror of
https://github.com/esphome/esphome.git
synced 2026-08-31 01:56:01 +00:00
[core] Avoid double promotion in update interval and step formatting (#18825)
This commit is contained in:
@@ -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 {
|
||||
|
||||
+24
-10
@@ -568,7 +568,7 @@ size_t value_accuracy_to_buf(std::span<char, VALUE_ACCURACY_MAX_LEN> 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<double>(value));
|
||||
if (len < 0)
|
||||
return 0;
|
||||
return static_cast<size_t>(len) >= buf.size() ? buf.size() - 1 : static_cast<size_t>(len);
|
||||
@@ -586,16 +586,30 @@ size_t value_accuracy_with_uom_to_buf(std::span<char, VALUE_ACCURACY_MAX_LEN> 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<uint32_t>(scaled);
|
||||
if (scaled - static_cast<float>(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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user