From 7c064f6fc80932201eb3e0c3c88e60e22961aa9f Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Thu, 23 Dec 2021 12:48:12 +0100 Subject: [PATCH] Fix changeUIntScale to be stable --- tasmota/support_float.ino | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tasmota/support_float.ino b/tasmota/support_float.ino index 330daa480..7d77659f3 100644 --- a/tasmota/support_float.ino +++ b/tasmota/support_float.ino @@ -407,8 +407,19 @@ uint16_t changeUIntScale(uint16_t inum, uint16_t ifrom_min, uint16_t ifrom_max, to_max = ito_min; } - uint32_t numerator = (num - from_min) * (to_max - to_min + 1); - uint32_t result = numerator / (from_max - from_min) + to_min; + // short-cut if limits to avoid rounding errors + if (num == from_min) return to_min; + if (num == from_max) return to_max; + + uint32_t result; + if ((num - from_min) < 0x8000L) { // no overflow possible + uint32_t numerator = ((num - from_min) * 2 + 1) * (to_max - to_min + 1); + result = numerator / ((from_max - from_min + 1) * 2) + to_min; + } else { // no pre-rounding since it might create an overflow + uint32_t numerator = (num - from_min) * (to_max - to_min + 1); + result = numerator / (from_max - from_min) + to_min; + } + return (uint32_t) (result > to_max ? to_max : (result < to_min ? to_min : result)); }