From fa09a5079d67931c9f23a22b9caa1a78fbef19d1 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 7 Feb 2021 01:28:13 +0100 Subject: [PATCH 1/7] String: compatibility with 64 bits scalars time_t is now 64 bits. Strig(time_t) was ambiguous tests added --- cores/esp8266/WString.cpp | 36 +++++++++++++++++++++++++++++++ cores/esp8266/WString.h | 22 +++++++++++++++++++ cores/esp8266/debug.cpp | 2 +- cores/esp8266/stdlib_noniso.cpp | 38 +++++++++++++++++++++++++++++++++ cores/esp8266/stdlib_noniso.h | 8 ++++++- tests/host/Makefile | 1 + tests/host/core/test_string.cpp | 10 +++++++++ 7 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 cores/esp8266/stdlib_noniso.cpp diff --git a/cores/esp8266/WString.cpp b/cores/esp8266/WString.cpp index 07ab99b2cf..2cad607117 100644 --- a/cores/esp8266/WString.cpp +++ b/cores/esp8266/WString.cpp @@ -98,6 +98,32 @@ String::String(unsigned long value, unsigned char base) { *this = buf; } +String::String(long long value) { + init(); + char buf[2 + 8 * sizeof(long long)]; + sprintf(buf, "%lld", value); + *this = buf; +} + +String::String(long long value, unsigned char base) { + init(); + char buf[2 + 8 * sizeof(long long)]; + *this = lltoa(value, buf, sizeof(buf), base); +} + +String::String(unsigned long long value) { + init(); + char buf[1 + 8 * sizeof(unsigned long long)]; + sprintf(buf, "%llu", value); + *this = buf; +} + +String::String(unsigned long long value, unsigned char base) { + init(); + char buf[1 + 8 * sizeof(unsigned long long)]; + *this = ulltoa(value, buf, sizeof(buf), base); +} + String::String(float value, unsigned char decimalPlaces) { init(); char buf[33]; @@ -313,6 +339,16 @@ unsigned char String::concat(unsigned long num) { return concat(buf, strlen(buf)); } +unsigned char String::concat(long long num) { + char buf[2 + 3 * sizeof(long long)]; + return concat(buf, sprintf(buf, "%lld", num)); +} + +unsigned char String::concat(unsigned long long num) { + char buf[1 + 3 * sizeof(unsigned long long)]; + return concat(buf, sprintf(buf, "%llu", num)); +} + unsigned char String::concat(float num) { char buf[20]; char *string = dtostrf(num, 4, 2, buf); diff --git a/cores/esp8266/WString.h b/cores/esp8266/WString.h index dcb0982387..beae31a9ab 100644 --- a/cores/esp8266/WString.h +++ b/cores/esp8266/WString.h @@ -72,6 +72,10 @@ class String { explicit String(unsigned int, unsigned char base = 10); explicit String(long, unsigned char base = 10); explicit String(unsigned long, unsigned char base = 10); + explicit String(long long /* base 10 */); + explicit String(long long, unsigned char base); + explicit String(unsigned long long /* base 10 */); + explicit String(unsigned long long, unsigned char base); explicit String(float, unsigned char decimalPlaces = 2); explicit String(double, unsigned char decimalPlaces = 2); ~String() { @@ -117,6 +121,8 @@ class String { unsigned char concat(unsigned int num); unsigned char concat(long num); unsigned char concat(unsigned long num); + unsigned char concat(long long num); + unsigned char concat(unsigned long long num); unsigned char concat(float num); unsigned char concat(double num); unsigned char concat(const __FlashStringHelper *str); @@ -156,6 +162,14 @@ class String { concat(num); return *this; } + String &operator +=(long long num) { + concat(num); + return *this; + } + String &operator +=(unsigned long long num) { + concat(num); + return *this; + } String &operator +=(float num) { concat(num); return *this; @@ -177,6 +191,8 @@ class String { friend StringSumHelper &operator +(const StringSumHelper &lhs, unsigned int num); friend StringSumHelper &operator +(const StringSumHelper &lhs, long num); friend StringSumHelper &operator +(const StringSumHelper &lhs, unsigned long num); + friend StringSumHelper &operator +(const StringSumHelper &lhs, long long num); + friend StringSumHelper &operator +(const StringSumHelper &lhs, unsigned long long num); friend StringSumHelper &operator +(const StringSumHelper &lhs, float num); friend StringSumHelper &operator +(const StringSumHelper &lhs, double num); friend StringSumHelper &operator +(const StringSumHelper &lhs, const __FlashStringHelper *rhs); @@ -375,6 +391,12 @@ class StringSumHelper: public String { StringSumHelper(unsigned long num) : String(num) { } + StringSumHelper(long long num) : + String(num) { + } + StringSumHelper(unsigned long long num) : + String(num) { + } StringSumHelper(float num) : String(num) { } diff --git a/cores/esp8266/debug.cpp b/cores/esp8266/debug.cpp index eddc7b06fe..858f5e1118 100644 --- a/cores/esp8266/debug.cpp +++ b/cores/esp8266/debug.cpp @@ -30,7 +30,7 @@ void hexdump(const void *mem, uint32_t len, uint8_t cols) while (len > 0) { uint32_t linesize = cols > len ? len : cols; - os_printf("\n[%p] 0x%04x: ", src, src - (const char*)mem); + os_printf("\n[%p] 0x%04x: ", src, (int)(src - (const char*)mem)); for (uint32_t i = 0; i < linesize; i++) { os_printf("%02x ", *(src + i)); diff --git a/cores/esp8266/stdlib_noniso.cpp b/cores/esp8266/stdlib_noniso.cpp new file mode 100644 index 0000000000..160c2e35df --- /dev/null +++ b/cores/esp8266/stdlib_noniso.cpp @@ -0,0 +1,38 @@ + +#include "stdlib_noniso.h" + +// fill backwards +char* ulltoa(unsigned long long val, char* str, size_t slen, uint_fast8_t radix) +{ + str += --slen; + *str = 0; + do + { + auto n = val % radix; + val /= radix; + *--str = n + ((n > 9) ? ('a' - 10) : '0'); + } while (--slen && val); + return val? nullptr: str; +} + +char* lltoa (long long val, char* str, size_t slen, uint_fast8_t radix) +{ + bool neg; + if (val < 0) + { + val = -val; + neg = true; + } + else + { + neg = false; + } + char* ret = ulltoa(val, str, slen, radix); + if (neg) + { + if (ret == str) + return nullptr; + *--ret = '-'; + } + return ret; +} diff --git a/cores/esp8266/stdlib_noniso.h b/cores/esp8266/stdlib_noniso.h index 053ea47948..8c2a3485fc 100644 --- a/cores/esp8266/stdlib_noniso.h +++ b/cores/esp8266/stdlib_noniso.h @@ -22,6 +22,8 @@ #ifndef STDLIB_NONISO_H #define STDLIB_NONISO_H +#include + #ifdef __cplusplus extern "C"{ #endif @@ -36,10 +38,14 @@ char* itoa (int val, char *s, int radix); char* ltoa (long val, char *s, int radix); +char* lltoa (long long val, char* str, size_t slen, uint_fast8_t radix); + char* utoa (unsigned int val, char *s, int radix); char* ultoa (unsigned long val, char *s, int radix); - + +char* ulltoa (unsigned long long val, char* str, size_t slen, uint_fast8_t radix); + char* dtostrf (double val, signed char width, unsigned char prec, char *s); void reverse(char* begin, char* end); diff --git a/tests/host/Makefile b/tests/host/Makefile index 4bb6e83b32..cc10061858 100644 --- a/tests/host/Makefile +++ b/tests/host/Makefile @@ -80,6 +80,7 @@ CORE_CPP_FILES := \ Stream.cpp \ WString.cpp \ Print.cpp \ + stdlib_noniso.cpp \ FS.cpp \ spiffs_api.cpp \ MD5Builder.cpp \ diff --git a/tests/host/core/test_string.cpp b/tests/host/core/test_string.cpp index 1150ba5913..e080be9507 100644 --- a/tests/host/core/test_string.cpp +++ b/tests/host/core/test_string.cpp @@ -132,6 +132,16 @@ TEST_CASE("String concantenation", "[core][String]") REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.01"); str += (double)1.01; REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01"); + str += LLONG_MIN; + REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808"); + str += String(LLONG_MIN, 10); + REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-9223372036854775808"); + str += LLONG_MAX; + REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-92233720368547758089223372036854775807"); + str += ULLONG_MAX; + REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-9223372036854775808922337203685477580718446744073709551615"); + str += String(ULLONG_MAX, 16); + REQUIRE(str == "abcdeabcde9872147483647-2147483648691969-123321-1.011.01-9223372036854775808-9223372036854775808922337203685477580718446744073709551615ffffffffffffffff"); str = "clean"; REQUIRE(str.concat(str) == true); REQUIRE(str == "cleanclean"); From 8c4c363491d1703a903d4815c56ffed63fb1adad Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 7 Feb 2021 16:34:50 +0100 Subject: [PATCH 2/7] use a single div+mod facility --- cores/esp8266/stdlib_noniso.cpp | 16 +++++++++---- cores/esp8266/stdlib_noniso.h | 40 +++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/cores/esp8266/stdlib_noniso.cpp b/cores/esp8266/stdlib_noniso.cpp index 160c2e35df..0eed3a35b7 100644 --- a/cores/esp8266/stdlib_noniso.cpp +++ b/cores/esp8266/stdlib_noniso.cpp @@ -2,20 +2,28 @@ #include "stdlib_noniso.h" // fill backwards -char* ulltoa(unsigned long long val, char* str, size_t slen, uint_fast8_t radix) +char* ulltoa(unsigned long long val, char* str, int slen, unsigned long long radix) { str += --slen; *str = 0; do { - auto n = val % radix; +#if 1 + // using div and mod in a single call + // String(ULLMAX_LONG, 10) => 354us + unsigned long long mod; + val = udivmod(val, radix, mod); +#else + // String(ULLMAX_LONG, 10) => 374us + auto mod = val % radix; val /= radix; - *--str = n + ((n > 9) ? ('a' - 10) : '0'); +#endif + *--str = mod + ((mod > 9) ? ('a' - 10) : '0'); } while (--slen && val); return val? nullptr: str; } -char* lltoa (long long val, char* str, size_t slen, uint_fast8_t radix) +char* lltoa (long long val, char* str, int slen, long long radix) { bool neg; if (val < 0) diff --git a/cores/esp8266/stdlib_noniso.h b/cores/esp8266/stdlib_noniso.h index 8c2a3485fc..6d2bcaa28e 100644 --- a/cores/esp8266/stdlib_noniso.h +++ b/cores/esp8266/stdlib_noniso.h @@ -22,8 +22,6 @@ #ifndef STDLIB_NONISO_H #define STDLIB_NONISO_H -#include - #ifdef __cplusplus extern "C"{ #endif @@ -38,13 +36,13 @@ char* itoa (int val, char *s, int radix); char* ltoa (long val, char *s, int radix); -char* lltoa (long long val, char* str, size_t slen, uint_fast8_t radix); +char* lltoa (long long val, char* str, int slen, unsigned long long radix); char* utoa (unsigned int val, char *s, int radix); char* ultoa (unsigned long val, char *s, int radix); -char* ulltoa (unsigned long long val, char* str, size_t slen, uint_fast8_t radix); +char* ulltoa (unsigned long long val, char* str, int slen, unsigned long long radix); char* dtostrf (double val, signed char width, unsigned char prec, char *s); @@ -54,8 +52,36 @@ const char* strrstr(const char*__restrict p_pcString, const char*__restrict p_pcPattern); #ifdef __cplusplus -} // extern "C" -#endif +} // extern "C" -#endif +// https://gcc.gnu.org/legacy-ml/gcc/2016-02/msg00001.html +extern "C++" { +template +T udivmod(T num, T den, T& mod) +{ + T bit = 1; + T res = 0; + + while (den < num && bit && !(den & (((T)1) << (sizeof(T)*8 - 1)))) + { + den <<= 1; + bit <<= 1; + } + while (bit) + { + if (num >= den) + { + num -= den; + res |= bit; + } + bit >>= 1; + den >>= 1; + } + mod = num; + return res; +} // udivmod +} // "C++" + +#endif // __cplusplus +#endif // STDLIB_NONISO_H From 598491f46cf192ea434811676b2dd1e37349f6c6 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 7 Feb 2021 17:29:06 +0100 Subject: [PATCH 3/7] fix host tests --- cores/esp8266/stdlib_noniso.cpp | 26 ++++++++++++++++++++++++++ cores/esp8266/stdlib_noniso.h | 17 ++++++++++++----- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/cores/esp8266/stdlib_noniso.cpp b/cores/esp8266/stdlib_noniso.cpp index 0eed3a35b7..851b05d79e 100644 --- a/cores/esp8266/stdlib_noniso.cpp +++ b/cores/esp8266/stdlib_noniso.cpp @@ -1,3 +1,24 @@ +/* + stdlib_noniso.h - nonstandard (but usefull) conversion functions + + Copyright (c) 2021 David Gauchard. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include "stdlib_noniso.h" @@ -26,6 +47,11 @@ char* ulltoa(unsigned long long val, char* str, int slen, unsigned long long rad char* lltoa (long long val, char* str, int slen, long long radix) { bool neg; + if (radix < 0) + { + radix = -radix; + val = -val; + } if (val < 0) { val = -val; diff --git a/cores/esp8266/stdlib_noniso.h b/cores/esp8266/stdlib_noniso.h index 6d2bcaa28e..4b66dcb558 100644 --- a/cores/esp8266/stdlib_noniso.h +++ b/cores/esp8266/stdlib_noniso.h @@ -1,9 +1,9 @@ -/* +/* stdlib_noniso.h - nonstandard (but usefull) conversion functions Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. This file is part of the esp8266 core for Arduino environment. - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -36,7 +36,7 @@ char* itoa (int val, char *s, int radix); char* ltoa (long val, char *s, int radix); -char* lltoa (long long val, char* str, int slen, unsigned long long radix); +char* lltoa (long long val, char* str, int slen, long long radix); char* utoa (unsigned int val, char *s, int radix); @@ -55,15 +55,20 @@ const char* strrstr(const char*__restrict p_pcString, } // extern "C" -// https://gcc.gnu.org/legacy-ml/gcc/2016-02/msg00001.html extern "C++" { + +#pragma GCC push_options +#pragma GCC optimize("Os") // Os better than O3 or Ofast + +// RFC PR43721 https://gcc.gnu.org/legacy-ml/gcc/2016-02/msg00001.html +// templatized gcc's https://github.com/gcc-mirror/gcc/blob/master/libgcc/udivmodhi4.c template T udivmod(T num, T den, T& mod) { T bit = 1; T res = 0; - while (den < num && bit && !(den & (((T)1) << (sizeof(T)*8 - 1)))) + while (den < num && bit && !(den & (((T)1) << ((sizeof(T) * 8) - 1)))) { den <<= 1; bit <<= 1; @@ -83,5 +88,7 @@ T udivmod(T num, T den, T& mod) } // udivmod } // "C++" +#pragma GCC pop_options + #endif // __cplusplus #endif // STDLIB_NONISO_H From fe0b14c8419f446a801edc30b70fdd9148a3cc3a Mon Sep 17 00:00:00 2001 From: david gauchard Date: Sun, 7 Feb 2021 22:27:34 +0100 Subject: [PATCH 4/7] remove generic udivmod --- cores/esp8266/stdlib_noniso.cpp | 8 ------- cores/esp8266/stdlib_noniso.h | 41 +++------------------------------ 2 files changed, 3 insertions(+), 46 deletions(-) diff --git a/cores/esp8266/stdlib_noniso.cpp b/cores/esp8266/stdlib_noniso.cpp index 851b05d79e..cc61b54044 100644 --- a/cores/esp8266/stdlib_noniso.cpp +++ b/cores/esp8266/stdlib_noniso.cpp @@ -29,16 +29,8 @@ char* ulltoa(unsigned long long val, char* str, int slen, unsigned long long rad *str = 0; do { -#if 1 - // using div and mod in a single call - // String(ULLMAX_LONG, 10) => 354us - unsigned long long mod; - val = udivmod(val, radix, mod); -#else - // String(ULLMAX_LONG, 10) => 374us auto mod = val % radix; val /= radix; -#endif *--str = mod + ((mod > 9) ? ('a' - 10) : '0'); } while (--slen && val); return val? nullptr: str; diff --git a/cores/esp8266/stdlib_noniso.h b/cores/esp8266/stdlib_noniso.h index 4b66dcb558..faebd0f4d4 100644 --- a/cores/esp8266/stdlib_noniso.h +++ b/cores/esp8266/stdlib_noniso.h @@ -52,43 +52,8 @@ const char* strrstr(const char*__restrict p_pcString, const char*__restrict p_pcPattern); #ifdef __cplusplus - } // extern "C" +#endif -extern "C++" { - -#pragma GCC push_options -#pragma GCC optimize("Os") // Os better than O3 or Ofast - -// RFC PR43721 https://gcc.gnu.org/legacy-ml/gcc/2016-02/msg00001.html -// templatized gcc's https://github.com/gcc-mirror/gcc/blob/master/libgcc/udivmodhi4.c -template -T udivmod(T num, T den, T& mod) -{ - T bit = 1; - T res = 0; - - while (den < num && bit && !(den & (((T)1) << ((sizeof(T) * 8) - 1)))) - { - den <<= 1; - bit <<= 1; - } - while (bit) - { - if (num >= den) - { - num -= den; - res |= bit; - } - bit >>= 1; - den >>= 1; - } - mod = num; - return res; -} // udivmod -} // "C++" - -#pragma GCC pop_options - -#endif // __cplusplus -#endif // STDLIB_NONISO_H + +#endif From 54bbe235cc24e9bfe12dd933b062af497c6b8309 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Wed, 10 Feb 2021 22:54:27 +0100 Subject: [PATCH 5/7] radix type, test with charconv --- cores/esp8266/WString.cpp | 33 ++++++++++++++++++++++++++++++--- cores/esp8266/stdlib_noniso.cpp | 10 ++-------- cores/esp8266/stdlib_noniso.h | 4 ++-- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/cores/esp8266/WString.cpp b/cores/esp8266/WString.cpp index 2cad607117..2d7b9c9650 100644 --- a/cores/esp8266/WString.cpp +++ b/cores/esp8266/WString.cpp @@ -105,25 +105,52 @@ String::String(long long value) { *this = buf; } +String::String(unsigned long long value) { + init(); + char buf[1 + 8 * sizeof(unsigned long long)]; + sprintf(buf, "%llu", value); + *this = buf; +} + +#if 1 +// slower version (374us vs charconv:230us) +// -880 flash bytes (vs charconv) +// -256 rodata bytes (vs charconv) + String::String(long long value, unsigned char base) { init(); char buf[2 + 8 * sizeof(long long)]; *this = lltoa(value, buf, sizeof(buf), base); } -String::String(unsigned long long value) { +String::String(unsigned long long value, unsigned char base) { init(); char buf[1 + 8 * sizeof(unsigned long long)]; - sprintf(buf, "%llu", value); + *this = ulltoa(value, buf, sizeof(buf), base); +} + +#else +// faster version (230us vs lltoa:374us) +// +880 flash bytes (vs lltoa) +// +256 rodata bytes (vs lltoa) + +#include +String::String(long long value, unsigned char base) { + init(); + char buf[2 + 8 * sizeof(long long)]; + std::to_chars(buf, buf + sizeof(buf) - 1, value, base); *this = buf; } String::String(unsigned long long value, unsigned char base) { init(); char buf[1 + 8 * sizeof(unsigned long long)]; - *this = ulltoa(value, buf, sizeof(buf), base); + std::to_chars(buf, buf + sizeof(buf) - 1, value, base); + *this = buf; } +#endif + String::String(float value, unsigned char decimalPlaces) { init(); char buf[33]; diff --git a/cores/esp8266/stdlib_noniso.cpp b/cores/esp8266/stdlib_noniso.cpp index cc61b54044..6f90306caa 100644 --- a/cores/esp8266/stdlib_noniso.cpp +++ b/cores/esp8266/stdlib_noniso.cpp @@ -19,11 +19,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #include "stdlib_noniso.h" // fill backwards -char* ulltoa(unsigned long long val, char* str, int slen, unsigned long long radix) +char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix) { str += --slen; *str = 0; @@ -36,14 +35,9 @@ char* ulltoa(unsigned long long val, char* str, int slen, unsigned long long rad return val? nullptr: str; } -char* lltoa (long long val, char* str, int slen, long long radix) +char* lltoa (long long val, char* str, int slen, unsigned int radix) { bool neg; - if (radix < 0) - { - radix = -radix; - val = -val; - } if (val < 0) { val = -val; diff --git a/cores/esp8266/stdlib_noniso.h b/cores/esp8266/stdlib_noniso.h index faebd0f4d4..2bacc2cb2c 100644 --- a/cores/esp8266/stdlib_noniso.h +++ b/cores/esp8266/stdlib_noniso.h @@ -36,13 +36,13 @@ char* itoa (int val, char *s, int radix); char* ltoa (long val, char *s, int radix); -char* lltoa (long long val, char* str, int slen, long long radix); +char* lltoa (long long val, char* str, int slen, unsigned int radix); char* utoa (unsigned int val, char *s, int radix); char* ultoa (unsigned long val, char *s, int radix); -char* ulltoa (unsigned long long val, char* str, int slen, unsigned long long radix); +char* ulltoa (unsigned long long val, char* str, int slen, unsigned int radix); char* dtostrf (double val, signed char width, unsigned char prec, char *s); From 5c573cc004a395b8b491ecdd7dc0ba6be1a1e18b Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 12 Feb 2021 01:33:20 +0100 Subject: [PATCH 6/7] remove charconv, add comment --- cores/esp8266/WString.cpp | 27 --------------------------- cores/esp8266/stdlib_noniso.cpp | 6 +++++- 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/cores/esp8266/WString.cpp b/cores/esp8266/WString.cpp index 2d7b9c9650..8cff99a217 100644 --- a/cores/esp8266/WString.cpp +++ b/cores/esp8266/WString.cpp @@ -112,11 +112,6 @@ String::String(unsigned long long value) { *this = buf; } -#if 1 -// slower version (374us vs charconv:230us) -// -880 flash bytes (vs charconv) -// -256 rodata bytes (vs charconv) - String::String(long long value, unsigned char base) { init(); char buf[2 + 8 * sizeof(long long)]; @@ -129,28 +124,6 @@ String::String(unsigned long long value, unsigned char base) { *this = ulltoa(value, buf, sizeof(buf), base); } -#else -// faster version (230us vs lltoa:374us) -// +880 flash bytes (vs lltoa) -// +256 rodata bytes (vs lltoa) - -#include -String::String(long long value, unsigned char base) { - init(); - char buf[2 + 8 * sizeof(long long)]; - std::to_chars(buf, buf + sizeof(buf) - 1, value, base); - *this = buf; -} - -String::String(unsigned long long value, unsigned char base) { - init(); - char buf[1 + 8 * sizeof(unsigned long long)]; - std::to_chars(buf, buf + sizeof(buf) - 1, value, base); - *this = buf; -} - -#endif - String::String(float value, unsigned char decimalPlaces) { init(); char buf[33]; diff --git a/cores/esp8266/stdlib_noniso.cpp b/cores/esp8266/stdlib_noniso.cpp index 6f90306caa..6427547514 100644 --- a/cores/esp8266/stdlib_noniso.cpp +++ b/cores/esp8266/stdlib_noniso.cpp @@ -21,7 +21,10 @@ #include "stdlib_noniso.h" -// fill backwards +// ulltoa() is slower than std::to_char() (1.6 times) +// but is smaller by ~800B/flash and ~250B/rodata + +// ulltoa fills str backwards and can return a pointer different from str char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix) { str += --slen; @@ -35,6 +38,7 @@ char* ulltoa(unsigned long long val, char* str, int slen, unsigned int radix) return val? nullptr: str; } +// lltoa fills str backwards and can return a pointer different from str char* lltoa (long long val, char* str, int slen, unsigned int radix) { bool neg; From 644ae09789eeebbfc539548834491319818e2e69 Mon Sep 17 00:00:00 2001 From: david gauchard Date: Fri, 12 Feb 2021 01:38:30 +0100 Subject: [PATCH 7/7] fix corner case --- cores/esp8266/stdlib_noniso.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cores/esp8266/stdlib_noniso.cpp b/cores/esp8266/stdlib_noniso.cpp index 6427547514..2b24681d3d 100644 --- a/cores/esp8266/stdlib_noniso.cpp +++ b/cores/esp8266/stdlib_noniso.cpp @@ -54,7 +54,7 @@ char* lltoa (long long val, char* str, int slen, unsigned int radix) char* ret = ulltoa(val, str, slen, radix); if (neg) { - if (ret == str) + if (ret == str || ret == nullptr) return nullptr; *--ret = '-'; } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy