diff --git a/cores/arduino/Print.cpp b/cores/arduino/Print.cpp index 1e4c99a65..efca8c2be 100644 --- a/cores/arduino/Print.cpp +++ b/cores/arduino/Print.cpp @@ -202,22 +202,101 @@ 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 *str = &buf[sizeof(buf) - 1]; - - *str = '\0'; + // shortcut printing just 0 and prevent later overhead + if (n == 0) { + return write('0'); + } // prevent crash if called with base == 1 - if (base < 2) base = 10; - - do { - char c = n % base; - n /= base; - - *--str = c < 10 ? c + '0' : c + 'A' - 10; - } while(n); - - return write(str); + if (base < 2) return printNumber(n, 10); + +// use -D ARDUINO_PRINT_NUMBER_GENERIC_ONLY when compiling to get only the generic version +#ifndef ARDUINO_PRINT_NUMBER_GENERIC_ONLY + switch (base) { + case 16: + // optimized version for hex prints + { + uint8_t *access = (uint8_t*) &n; + uint8_t written = 0; + for (int8_t i=sizeof(unsigned long)-1; i>=0; i--) { + char c; + c = (access[i] & 0xf0) >> 4; + if (c != 0 || written != 0) { + c = (c < 10 ? c + '0' : c + 'A' - 10); + written += write(c); + } // else: skip leading zeros + c = access[i] & 0x0f; + if (c != 0 || written != 0) { + c = (c < 10 ? c + '0' : c + 'A' - 10); + written += write(c); + } // else: skip leading zeros + } + return written; + } + case 2: + // optimized version for binary prints + { + uint8_t *access = (uint8_t*) &n; + uint8_t written = 0; + for (int8_t i=sizeof(unsigned long)-1; i>=0; i--) { + if (access[i] == 0 && written == 0) { + // skip leading zeros + continue; + } + for (int8_t j=7; j>=0; j--) { + char c; + if (j == 0) { + // avoid shift by 0 - undefined + c = (access[i] & 0x01); + } else { + c = (access[i] & 1<> j; + } + if (c == 0 && written == 0) { + // skip leading zeros + continue; + } + c = (c < 10 ? c + '0' : c + 'A' - 10); + written += write(c); + } + } + return written; + } + default: + // the generic implementation +#endif + { + unsigned long reverse = 0; + uint8_t digits = 0; + char avoid_overflow = n % base; + + // this step and 'avoid_overflow' will make sure it stays in unsigned long range being able to print all 10 digits no matter what + n /= base; + + // reverse the number and count digits + while (n != 0) { + uint8_t remainder = n % base; + reverse = reverse * base + remainder; + n /= base; + digits++; + } + + // from here onwards reuse of variable 'n' to count written chars + while (digits--) { + char c = reverse % base; + reverse /= base; + + c = (c < 10 ? c + '0' : c + 'A' - 10); + n += write(c); + } + + avoid_overflow = (avoid_overflow < 10 ? avoid_overflow + '0' : avoid_overflow + 'A' - 10); + n += write(avoid_overflow); + + return n; + } +#ifndef ARDUINO_PRINT_NUMBER_GENERIC_ONLY + } +#endif } size_t Print::printFloat(double number, uint8_t digits) 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