From 41883e6dc34955b847015fa50578a74f98741879 Mon Sep 17 00:00:00 2001 From: Tobias Knauss Date: Thu, 23 Apr 2026 14:13:58 +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. --- cores/arduino/Print.cpp | 16 +++++++++++++++- cores/arduino/Print.h | 14 +++++++++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index 1e4c99a65..82ff2ae6a 100644 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -200,22 +200,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/cores/arduino/Print.h b/cores/arduino/Print.h index 0097cc11d..a46cac32d 100644 --- a/cores/arduino/Print.h +++ b/cores/arduino/Print.h @@ -27,18 +27,26 @@ #include "Printable.h" #define DEC 10 -#define HEX 16 +#define HEX 0x0010 +#define HEX2 0x0210 +#define HEX4 0x0410 +#define HEX8 0x0810 #define OCT 8 #ifdef BIN // Prevent warnings if BIN is previously defined in "iotnx4.h" or similar #undef BIN #endif -#define BIN 2 +#define BIN 0x0002 +#define BIN2 0x0202 +#define BIN4 0x0402 +#define BIN8 0x0802 +#define BIN16 0x1002 +#define BIN32 0x2002 class Print { private: int write_error; - size_t printNumber(unsigned long, uint8_t); + size_t printNumber(unsigned long, uint16_t); size_t printFloat(double, uint8_t); protected: void setWriteError(int err = 1) { write_error = err; } From 0476918ebb11d6a839c268bedc74459cd3cd4f83 Mon Sep 17 00:00:00 2001 From: Tobias Knauss Date: Fri, 29 May 2026 20:07:06 +0200 Subject: [PATCH 2/2] 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. --- cores/arduino/Print.cpp | 89 +++++++++++++++++++++++++++-------------- cores/arduino/Print.h | 18 +++++---- 2 files changed, 70 insertions(+), 37 deletions(-) diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index 82ff2ae6a..6ab741eda 100644 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -69,41 +69,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(double n, int digits) @@ -149,9 +147,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; } @@ -200,8 +212,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]; @@ -209,8 +229,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; } @@ -219,6 +238,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; @@ -226,12 +253,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; } size_t Print::printFloat(double number, uint8_t digits) diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h index a46cac32d..0a2f5f1d4 100644 --- a/cores/arduino/Print.h +++ b/cores/arduino/Print.h @@ -46,7 +46,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 printFloat(double, uint8_t); protected: void setWriteError(int err = 1) { write_error = err; } @@ -74,10 +74,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(double, int = 2); size_t print(const Printable&); @@ -86,10 +88,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(double, int = 2); size_t println(const Printable&);