mirror of
https://github.com/esphome/esphome.git
synced 2026-02-24 20:35:30 -07:00
[core] Add pow10_int helper, replace powf in normalize_accuracy and sensor filters (#14114)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include <cmath>
|
||||
#include "esphome/core/application.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "sensor.h"
|
||||
|
||||
@@ -240,7 +241,7 @@ ValueListFilter::ValueListFilter(std::initializer_list<TemplatableValue<float>>
|
||||
|
||||
bool ValueListFilter::value_matches_any_(float sensor_value) {
|
||||
int8_t accuracy = this->parent_->get_accuracy_decimals();
|
||||
float accuracy_mult = powf(10.0f, accuracy);
|
||||
float accuracy_mult = pow10_int(accuracy);
|
||||
float rounded_sensor = roundf(accuracy_mult * sensor_value);
|
||||
|
||||
for (auto &filter_value : this->values_) {
|
||||
@@ -472,7 +473,7 @@ optional<float> ClampFilter::new_value(float value) {
|
||||
RoundFilter::RoundFilter(uint8_t precision) : precision_(precision) {}
|
||||
optional<float> RoundFilter::new_value(float value) {
|
||||
if (std::isfinite(value)) {
|
||||
float accuracy_mult = powf(10.0f, this->precision_);
|
||||
float accuracy_mult = pow10_int(this->precision_);
|
||||
return roundf(accuracy_mult * value) / accuracy_mult;
|
||||
}
|
||||
return value;
|
||||
|
||||
@@ -468,8 +468,15 @@ ParseOnOffState parse_on_off(const char *str, const char *on, const char *off) {
|
||||
|
||||
static inline void normalize_accuracy_decimals(float &value, int8_t &accuracy_decimals) {
|
||||
if (accuracy_decimals < 0) {
|
||||
auto multiplier = powf(10.0f, accuracy_decimals);
|
||||
value = roundf(value * multiplier) / multiplier;
|
||||
float divisor;
|
||||
if (accuracy_decimals == -1) {
|
||||
divisor = 10.0f;
|
||||
} else if (accuracy_decimals == -2) {
|
||||
divisor = 100.0f;
|
||||
} else {
|
||||
divisor = pow10_int(-accuracy_decimals);
|
||||
}
|
||||
value = roundf(value / divisor) * divisor;
|
||||
accuracy_decimals = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,6 +439,21 @@ template<size_t STACK_SIZE, typename T = uint8_t> class SmallBufferWithHeapFallb
|
||||
/// @name Mathematics
|
||||
///@{
|
||||
|
||||
/// Compute 10^exp using iterative multiplication/division.
|
||||
/// Avoids pulling in powf/__ieee754_powf (~2.3KB flash) for small integer exponents.
|
||||
/// Matches powf(10, exp) for the int8_t exponent range used by sensor accuracy_decimals.
|
||||
inline float pow10_int(int8_t exp) {
|
||||
float result = 1.0f;
|
||||
if (exp >= 0) {
|
||||
for (int8_t i = 0; i < exp; i++)
|
||||
result *= 10.0f;
|
||||
} else {
|
||||
for (int8_t i = exp; i < 0; i++)
|
||||
result /= 10.0f;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Remap \p value from the range (\p min, \p max) to (\p min_out, \p max_out).
|
||||
template<typename T, typename U> T remap(U value, U min, U max, T min_out, T max_out) {
|
||||
return (value - min) * (max_out - min_out) / (max - min) + min_out;
|
||||
|
||||
Reference in New Issue
Block a user