From 2ec545d7394c46fd7321a1e58708f7b22ddef5a3 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 6 Mar 2019 17:59:18 +0100 Subject: [PATCH] Fix float calculations Fix float calculations in range from 0 to -1 (#5386) --- sonoff/_changelog.ino | 1 + sonoff/support.ino | 43 ++++++++++++++++++++++++------------------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 3690ecf4a..245cc5edb 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -3,6 +3,7 @@ * Add Korean language translations (#5344) * Fix Energy TotalStartTime when commands EnergyReset0 and/or EnergyReset3 used (#5373) * Fix DS18S20 temperature calculation (#5375) + * Fix float calculations in range from 0 to -1 (#5386) * * 6.4.1.18 20190221 * Fix some exceptions and watchdogs due to lack of stack space - part 1 (#5215) diff --git a/sonoff/support.ino b/sonoff/support.ino index 8bb9d1dea..c5e5dcc42 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -154,34 +154,39 @@ char* subStr(char* dest, char* str, const char *delim, int index) return sub; } -double CharToDouble(const char *str) +double CharToDouble(char *str) { // simple ascii to double, because atof or strtod are too large char strbuf[24]; strlcpy(strbuf, str, sizeof(strbuf)); - char *pt; - double left = atoi(strbuf); + char *pt = strbuf; + while ((*pt != '\0') && isblank(*pt)) { pt++; } // Trim leading spaces + + signed char sign = 1; + if (*pt == '-') { sign = -1; } + if (*pt == '-' || *pt=='+') { pt++; } // Skip any sign + + double left = 0; + if (*pt != '.') { + left = atoi(pt); // Get left part + while (isdigit(*pt)) { pt++; } // Skip number + } + double right = 0; - short len = 0; - pt = strtok (strbuf, "."); - if (pt) { - pt = strtok (NULL, "."); - if (pt) { - right = atoi(pt); - len = strlen(pt); - double fac = 1; - while (len) { - fac /= 10.0; - len--; - } - // pow is also very large - //double fac=pow(10,-len); - right *= fac; + if (*pt == '.') { + pt++; + right = atoi(pt); // Decimal part + while (isdigit(*pt)) { + pt++; + right /= 10.0; } } + double result = left + right; - if (left < 0) { result = left - right; } + if (sign < 0) { + return -result; // Add negative sign + } return result; }