From 80ccbaef0dd744dcad1ce7805292be60cb50c143 Mon Sep 17 00:00:00 2001 From: Martin Ayotte Date: Thu, 6 Aug 2015 13:32:02 -0400 Subject: [PATCH] fix dtostrf() issue using trackerj/odometer fixes along with my own fix for string null character ending --- cores/esp8266/core_esp8266_noniso.c | 37 ++++++++++++++--------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/cores/esp8266/core_esp8266_noniso.c b/cores/esp8266/core_esp8266_noniso.c index 40fe5e6dd..fecdd3362 100644 --- a/cores/esp8266/core_esp8266_noniso.c +++ b/cores/esp8266/core_esp8266_noniso.c @@ -162,46 +162,45 @@ char * dtostrf(double number, signed char width, unsigned char prec, char *s) { strcpy(s, "ovf"); return s; } - char* out = s; - int signInt_Part = 1; - // Handle negative numbers if (number < 0.0) { - signInt_Part = -1; + *out = '-'; + ++out; number = -number; } - // calc left over digits - if (prec > 0) - { - width -= (prec + 1); - } - // Round correctly so that print(1.999, 2) prints as "2.00" - double rounding = 0.5; + // I optimized out most of the divisions + double rounding = 2.0; for (uint8_t i = 0; i < prec; ++i) - rounding /= 10.0; + rounding *= 10.0; + rounding = 1.0 / rounding; number += rounding; // Extract the integer part of the number and print it unsigned long int_part = (unsigned long)number; double remainder = number - (double)int_part; - out += sprintf(out, "%*ld", width, int_part * signInt_Part); + out += sprintf(out, "%d", int_part); // Print the decimal point, but only if there are digits beyond if (prec > 0) { *out = '.'; ++out; - - - for (unsigned char decShift = prec; decShift > 0; decShift--) { - remainder *= 10.0; - } - sprintf(out, "%0*d", prec, (int)remainder); } + // Print the digits after the decimal point + int8_t digit = 0; + while (prec-- > 0) { + remainder *= 10.0; + digit = (int8_t)remainder; + if (digit > 9) digit = 9; // insurance + *out = (char)('0' | digit); + ++out; + remainder -= digit; + } + *out = 0; return s; }