From a4f6875eea595b8b945e6ac5cf83dcdaf2874df5 Mon Sep 17 00:00:00 2001 From: Tobias Knauss Date: Mon, 27 Apr 2026 20:00:36 +0200 Subject: [PATCH 1/2] more print format constants defined; function printNumber(..) adapted. - HEX2, HEX4, HEX8 - BIN2, BIN4, BIN8, BIN16, BIN32 The number represents the minimum digit count for printing, i.e. adding leading zeros. --- api/Print.cpp | 16 +++++++++++++++- api/Print.h | 14 +++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/api/Print.cpp b/api/Print.cpp index 4a6e942a..ee6d3b83 100644 --- a/api/Print.cpp +++ b/api/Print.cpp @@ -238,22 +238,36 @@ size_t Print::println(const Printable& x) // Private Methods ///////////////////////////////////////////////////////////// -size_t Print::printNumber(unsigned long n, uint8_t base) +size_t Print::printNumber(unsigned long n, uint16_t base) { char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. char *str = &buf[sizeof(buf) - 1]; *str = '\0'; + uint8_t minDigits = 1; + uint8_t maxDigits = sizeof(buf) - 1; + if (base > 0xFF) + { + minDigits = base >> 8; + base = base & 0xFF; + } + if (minDigits > maxDigits) minDigits = maxDigits; + // prevent crash if called with base == 1 if (base < 2) base = 10; + uint8_t usedDigits = 0; do { char c = n % base; n /= base; *--str = c < 10 ? c + '0' : c + 'A' - 10; + usedDigits++; } while(n); + while (usedDigits++ < minDigits) { + *--str = '0'; + } return write(str); } diff --git a/api/Print.h b/api/Print.h index 2016d7d5..38fdd9c9 100644 --- a/api/Print.h +++ b/api/Print.h @@ -26,9 +26,17 @@ #include "Printable.h" #define DEC 10 -#define HEX 16 +#define HEX 0x0010 +#define HEX2 0x0210 +#define HEX4 0x0410 +#define HEX8 0x0810 #define OCT 8 -#define BIN 2 +#define BIN 0x0002 +#define BIN2 0x0202 +#define BIN4 0x0402 +#define BIN8 0x0802 +#define BIN16 0x1002 +#define BIN32 0x2002 namespace arduino { @@ -36,7 +44,7 @@ class Print { private: int write_error; - size_t printNumber(unsigned long, uint8_t); + size_t printNumber(unsigned long, uint16_t); size_t printULLNumber(unsigned long long, uint8_t); size_t printFloat(double, int); protected: From 542695cdf363ae2a4fd112c5d953bc84514fe589 Mon Sep 17 00:00:00 2001 From: Tobias Knauss Date: Fri, 29 May 2026 19:32:04 +0200 Subject: [PATCH 2/2] Unified handling of print(num) via printNumber(..). Added support for printing negative numbers in base-2, -4, -8, and -16 with length of original type and not always with length of uint32. --- api/Print.cpp | 89 ++++++++++++++++++++++++++++++++++----------------- api/Print.h | 18 +++++++---- 2 files changed, 70 insertions(+), 37 deletions(-) diff --git a/api/Print.cpp b/api/Print.cpp index ee6d3b83..cb83d94c 100644 --- a/api/Print.cpp +++ b/api/Print.cpp @@ -71,41 +71,39 @@ size_t Print::print(char c) return write(c); } -size_t Print::print(unsigned char b, int base) +size_t Print::print(char num, int base) { - return print((unsigned long) b, base); + return printNumber ((long) num, num < 0, sizeof(char), base); } -size_t Print::print(int n, int base) +size_t Print::print(signed char num, int base) { - return print((long) n, base); + return printNumber ((long) num, num < 0, sizeof(char), base); } -size_t Print::print(unsigned int n, int base) +size_t Print::print(unsigned char num, int base) { - return print((unsigned long) n, base); + return printNumber ((unsigned long) num, false, sizeof(char), base); } -size_t Print::print(long n, int base) +size_t Print::print(int num, 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); - } + return printNumber ((long) num, num < 0, sizeof(int), base); } -size_t Print::print(unsigned long n, int base) +size_t Print::print(unsigned int num, int base) { - if (base == 0) return write(n); - else return printNumber(n, base); + return printNumber ((unsigned long) num, false, sizeof(int), base); +} + +size_t Print::print(long num, int base) +{ + return printNumber (num, num < 0, sizeof(long), base); +} + +size_t Print::print(unsigned long num, int base) +{ + return printNumber (num, false, sizeof(long), base); } size_t Print::print(long long n, int base) @@ -173,9 +171,23 @@ size_t Print::println(char c) return n; } -size_t Print::println(unsigned char b, int base) +size_t Print::println(char num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(signed char num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t Print::println(unsigned char num, int base) { - size_t n = print(b, base); + size_t n = print(num, base); n += println(); return n; } @@ -238,8 +250,16 @@ size_t Print::println(const Printable& x) // Private Methods ///////////////////////////////////////////////////////////// -size_t Print::printNumber(unsigned long n, uint16_t base) +size_t Print::printNumber(unsigned long n, bool negative, size_t bytes, uint16_t base) { + if (base == 0) return write(n); + + int t = 0; + if (base == 10 && negative) { + t = print('-'); + n = -n; + } + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. char *str = &buf[sizeof(buf) - 1]; @@ -247,8 +267,7 @@ size_t Print::printNumber(unsigned long n, uint16_t base) uint8_t minDigits = 1; uint8_t maxDigits = sizeof(buf) - 1; - if (base > 0xFF) - { + if (base > 0xFF) { minDigits = base >> 8; base = base & 0xFF; } @@ -257,6 +276,14 @@ size_t Print::printNumber(unsigned long n, uint16_t base) // prevent crash if called with base == 1 if (base < 2) base = 10; + uint8_t nominalDigits = 255; + switch (base) { + case 2: nominalDigits = bytes * 8; break; + case 4: nominalDigits = bytes * 4; break; + case 8: nominalDigits = (bytes * 8 + 2) / 3; break; // +2 is for round up + case 16: nominalDigits = bytes * 2; break; + } + uint8_t usedDigits = 0; do { char c = n % base; @@ -264,12 +291,14 @@ size_t Print::printNumber(unsigned long n, uint16_t base) *--str = c < 10 ? c + '0' : c + 'A' - 10; usedDigits++; - } while(n); + } while(n && usedDigits < nominalDigits); + + char fillChar = negative ? (base <= 10 ? base + '0' - 1 : base + 'A' - 11) : '0'; while (usedDigits++ < minDigits) { - *--str = '0'; + *--str = fillChar; } - return write(str); + return write(str) + t; } // REFERENCE IMPLEMENTATION FOR ULL diff --git a/api/Print.h b/api/Print.h index 38fdd9c9..5c06b2f4 100644 --- a/api/Print.h +++ b/api/Print.h @@ -44,7 +44,7 @@ class Print { private: int write_error; - size_t printNumber(unsigned long, uint16_t); + size_t printNumber(unsigned long, bool, size_t, uint16_t); size_t printULLNumber(unsigned long long, uint8_t); size_t printFloat(double, int); protected: @@ -73,10 +73,12 @@ class Print size_t print(const String &); size_t print(const char[]); size_t print(char); + size_t print( char, int); + size_t print( signed char, int = DEC); 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( 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); @@ -87,10 +89,12 @@ class Print size_t println(const String &s); size_t println(const char[]); size_t println(char); + size_t println( char, int); + size_t println( signed char, int = DEC); 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( 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);