From 6c76c942beba4a9eb759ab40b52d8c1c931b3a06 Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Wed, 29 Jan 2020 15:13:55 +0100 Subject: [PATCH 1/2] Extend Print class for 64bit integers. --- cores/arduino/Print.cpp | 67 +++++++++++++++++++++++++++------ cores/arduino/Print.h | 83 ++++++++++++++++++++++------------------- 2 files changed, 100 insertions(+), 50 deletions(-) diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index 1e4c99a65..fde3206c1 100644 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -86,18 +86,12 @@ size_t Print::print(unsigned int n, int base) size_t Print::print(long n, int base) { - if (base == 0) { - return write(n); - } else if (base == 10) { - if (n < 0) { - int t = print('-'); - n = -n; - return printNumber(n, 10) + t; - } - return printNumber(n, 10); - } else { - return printNumber(n, base); + int t = 0; + if (base == 10 && n < 0) { + t = print('-'); + n = -n; } + return printNumber(static_cast(n), base) + t; } size_t Print::print(unsigned long n, int base) @@ -106,6 +100,22 @@ size_t Print::print(unsigned long n, int base) else return printNumber(n, base); } +size_t Print::print(long long n, int base) +{ + int t = 0; + if (base == 10 && n < 0) { + t = print('-'); + n = -n; + } + return printNumber(static_cast(n), base) + t; +} + +size_t Print::print(unsigned long long n, int base) +{ + if (base == 0) return write(n); + return printNumber(n, base); +} + size_t Print::print(double n, int digits) { return printFloat(n, digits); @@ -184,6 +194,20 @@ size_t Print::println(unsigned long num, int base) return n; } +size_t Print::println(long long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned long long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + size_t Print::println(double num, int digits) { size_t n = print(num, digits); @@ -220,6 +244,27 @@ size_t Print::printNumber(unsigned long n, uint8_t base) return write(str); } +size_t Print::printNumber(unsigned long long n, uint8_t base) +{ + char buf[8 * sizeof(long long) + 1]; // Assumes 8-bit chars plus zero byte. + char* str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + + do { + unsigned long m = n; + n /= base; + char c = m - base * n; + + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while(n); + + return write(str); +} + size_t Print::printFloat(double number, uint8_t digits) { size_t n = 0; diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h index 058a2abbd..6d7bb1583 100644 --- a/cores/arduino/Print.h +++ b/cores/arduino/Print.h @@ -36,58 +36,63 @@ class Print { - private: - int write_error; - size_t printNumber(unsigned long, uint8_t); - size_t printFloat(double, uint8_t); - protected: + private: + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printNumber(unsigned long long, uint8_t); + size_t printFloat(double, uint8_t); + protected: void setWriteError(int err = 1) { write_error = err; } - public: + public: Print() : write_error(0) {} - + int getWriteError() { return write_error; } void clearWriteError() { setWriteError(0); } - - virtual size_t write(uint8_t) = 0; - size_t write(const char *str) { + + virtual size_t write(uint8_t) = 0; + size_t write(const char *str) { if (str == NULL) return 0; return write((const uint8_t *)str, strlen(str)); - } - virtual size_t write(const uint8_t *buffer, size_t size); - size_t write(const char *buffer, size_t size) { - return write((const uint8_t *)buffer, size); - } + } + virtual size_t write(const uint8_t *buffer, size_t size); + size_t write(const char *buffer, size_t size) { + return write((const uint8_t *) buffer, size); + } // default to zero, meaning "a single write may block" // should be overriden by subclasses with buffering virtual int availableForWrite() { return 0; } - size_t print(const __FlashStringHelper *); - size_t print(const String &); - size_t print(const char[]); - size_t print(char); - size_t print(unsigned char, int = DEC); - size_t print(int, int = DEC); - size_t print(unsigned int, int = DEC); - size_t print(long, int = DEC); - size_t print(unsigned long, int = DEC); - size_t print(double, int = 2); - size_t print(const Printable&); + size_t print(const __FlashStringHelper *); + size_t print(const String &); + size_t print(const char[]); + size_t print(char); + size_t print(unsigned char, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(long long, int = DEC); + size_t print(unsigned long long, int = DEC); + size_t print(double, int = 2); + size_t print(const Printable&); - size_t println(const __FlashStringHelper *); - size_t println(const String &s); - size_t println(const char[]); - size_t println(char); - size_t println(unsigned char, int = DEC); - size_t println(int, int = DEC); - size_t println(unsigned int, int = DEC); - size_t println(long, int = DEC); - size_t println(unsigned long, int = DEC); - size_t println(double, int = 2); - size_t println(const Printable&); - size_t println(void); + size_t println(const __FlashStringHelper *); + size_t println(const String &s); + size_t println(const char[]); + size_t println(char); + size_t println(unsigned char, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(long long, int = DEC); + size_t println(unsigned long long, int = DEC); + size_t println(double, int = 2); + size_t println(const Printable&); + size_t println(void); - virtual void flush() { /* Empty implementation for backward compatibility */ } + virtual void flush() { /* Empty implementation for backward compatibility */ } }; #endif From 9da1069bee7a0bcf4a84805bbeef85d8a2daeb0a Mon Sep 17 00:00:00 2001 From: "Dirk O. Kaar" Date: Sun, 2 Feb 2020 09:49:42 +0100 Subject: [PATCH 2/2] Fix 32bit long used in long long printNumber. --- cores/arduino/Print.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index fde3206c1..db76ff76f 100644 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -226,7 +226,7 @@ size_t Print::println(const Printable& x) size_t Print::printNumber(unsigned long n, uint8_t base) { - char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char buf[8 * sizeof(n) + 1]; // Assumes 8-bit chars plus zero byte. char *str = &buf[sizeof(buf) - 1]; *str = '\0'; @@ -246,7 +246,7 @@ size_t Print::printNumber(unsigned long n, uint8_t base) size_t Print::printNumber(unsigned long long n, uint8_t base) { - char buf[8 * sizeof(long long) + 1]; // Assumes 8-bit chars plus zero byte. + char buf[8 * sizeof(n) + 1]; // Assumes 8-bit chars plus zero byte. char* str = &buf[sizeof(buf) - 1]; *str = '\0'; @@ -255,7 +255,7 @@ size_t Print::printNumber(unsigned long long n, uint8_t base) if (base < 2) base = 10; do { - unsigned long m = n; + auto m = n; n /= base; char c = m - base * n;