11/*
2- Print.cpp - Base class that provides print() and println()
3- Copyright (c) 2008 David A. Mellis. All right reserved.
2+ Copyright (c) 2014 Arduino. All right reserved.
43
54 This library is free software; you can redistribute it and/or
65 modify it under the terms of the GNU Lesser General Public
98
109 This library is distributed in the hope that it will be useful,
1110 but WITHOUT ANY WARRANTY; without even the implied warranty of
12- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13- Lesser General Public License for more details.
11+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+ See the GNU Lesser General Public License for more details.
1413
1514 You should have received a copy of the GNU Lesser General Public
1615 License along with this library; if not, write to the Free Software
1716 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18-
19- Modified 23 November 2006 by David A. Mellis
20- Modified 03 August 2015 by Chuck Todd
21- */
17+ */
2218
2319#include < stdlib.h>
2420#include < string.h>
@@ -108,6 +104,31 @@ size_t Print::print(unsigned long n, int base)
108104 }
109105}
110106
107+ size_t Print::print (long long n, int base)
108+ {
109+ if (base == 0 ) {
110+ return write (n);
111+ } else if (base == 10 ) {
112+ if (n < 0 ) {
113+ int t = print (' -' );
114+ n = -n;
115+ return printULLNumber (n, 10 ) + t;
116+ }
117+ return printULLNumber (n, 10 );
118+ } else {
119+ return printULLNumber (n, base);
120+ }
121+ }
122+
123+ size_t Print::print (unsigned long long n, int base)
124+ {
125+ if (base == 0 ) {
126+ return write (n);
127+ } else {
128+ return printULLNumber (n, base);
129+ }
130+ }
131+
111132size_t Print::print (double n, int digits)
112133{
113134 return printFloat (n, digits);
@@ -186,6 +207,20 @@ size_t Print::println(unsigned long num, int base)
186207 return n;
187208}
188209
210+ size_t Print::println (long long num, int base)
211+ {
212+ size_t n = print (num, base);
213+ n += println ();
214+ return n;
215+ }
216+
217+ size_t Print::println (unsigned long long num, int base)
218+ {
219+ size_t n = print (num, base);
220+ n += println ();
221+ return n;
222+ }
223+
189224size_t Print::println (double num, int digits)
190225{
191226 size_t n = print (num, digits);
@@ -262,6 +297,100 @@ size_t Print::printNumber(unsigned long n, uint8_t base)
262297 return write (str);
263298}
264299
300+ /*
301+ void Print::printULLNumber(uint64_t n, uint8_t base)
302+ {
303+ unsigned char buf[16 * sizeof(long)];
304+ unsigned int i = 0;
305+
306+ if (n == 0) {
307+ print((char)'0');
308+ return;
309+ }
310+
311+ while (n > 0) {
312+ buf[i++] = n % base;
313+ n /= base;
314+ }
315+
316+ for (; i > 0; i--) {
317+ print((char)(buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10));
318+ }
319+ }
320+ */
321+ // REFERENCE IMPLEMENTATION FOR ULL
322+ // size_t Print::printULLNumber(unsigned long long n, uint8_t base)
323+ // {
324+ // // if limited to base 10 and 16 the bufsize can be smaller
325+ // char buf[65];
326+ // char *str = &buf[64];
327+
328+ // *str = '\0';
329+
330+ // // prevent crash if called with base == 1
331+ // if (base < 2) base = 10;
332+
333+ // do {
334+ // unsigned long long t = n / base;
335+ // char c = n - t * base; // faster than c = n%base;
336+ // n = t;
337+ // *--str = c < 10 ? c + '0' : c + 'A' - 10;
338+ // } while(n);
339+
340+ // return write(str);
341+ // }
342+
343+ // FAST IMPLEMENTATION FOR ULL
344+ size_t Print::printULLNumber (unsigned long long n64, uint8_t base)
345+ {
346+ // if limited to base 10 and 16 the bufsize can be 20
347+ char buf[64 ];
348+ uint8_t i = 0 ;
349+ uint8_t innerLoops = 0 ;
350+
351+ // prevent crash if called with base == 1
352+ if (base < 2 ) {
353+ base = 10 ;
354+ }
355+
356+ // process chunks that fit in "16 bit math".
357+ uint16_t top = 0xFFFF / base;
358+ uint16_t th16 = 1 ;
359+ while (th16 < top) {
360+ th16 *= base;
361+ innerLoops++;
362+ }
363+
364+ while (n64 > th16) {
365+ // 64 bit math part
366+ uint64_t q = n64 / th16;
367+ uint16_t r = n64 - q * th16;
368+ n64 = q;
369+
370+ // 16 bit math loop to do remainder. (note buffer is filled reverse)
371+ for (uint8_t j = 0 ; j < innerLoops; j++) {
372+ uint16_t qq = r / base;
373+ buf[i++] = r - qq * base;
374+ r = qq;
375+ }
376+ }
377+
378+ uint16_t n16 = n64;
379+ while (n16 > 0 ) {
380+ uint16_t qq = n16 / base;
381+ buf[i++] = n16 - qq * base;
382+ n16 = qq;
383+ }
384+
385+ size_t bytes = i;
386+ for (; i > 0 ; i--) {
387+ write ((char )(buf[i - 1 ] < 10 ?
388+ ' 0' + buf[i - 1 ] :
389+ ' A' + buf[i - 1 ] - 10 ));
390+ }
391+ return bytes;
392+ }
393+
265394size_t Print::printFloat (double number, uint8_t digits)
266395{
267396 size_t n = 0 ;
@@ -300,71 +429,16 @@ size_t Print::printFloat(double number, uint8_t digits)
300429
301430 // Print the decimal point, but only if there are digits beyond
302431 if (digits > 0 ) {
303- n += print (" . " );
432+ n += print (' . ' );
304433 }
305434
306435 // Extract digits from the remainder one at a time
307436 while (digits-- > 0 ) {
308437 remainder *= 10.0 ;
309- int toPrint = int (remainder) ;
438+ unsigned int toPrint = ( unsigned int )remainder ;
310439 n += print (toPrint);
311440 remainder -= toPrint;
312441 }
313442
314443 return n;
315- }
316-
317- #ifdef SUPPORT_LONGLONG
318-
319- void Print::println (int64_t n, uint8_t base)
320- {
321- print (n, base);
322- println ();
323- }
324-
325- void Print::print (int64_t n, uint8_t base)
326- {
327- if (n < 0 ) {
328- print ((char )' -' );
329- n = -n;
330- }
331- if (base < 2 ) {
332- base = 2 ;
333- }
334- print ((uint64_t )n, base);
335- }
336-
337- void Print::println (uint64_t n, uint8_t base)
338- {
339- print (n, base);
340- println ();
341- }
342-
343- void Print::print (uint64_t n, uint8_t base)
344- {
345- if (base < 2 ) {
346- base = 2 ;
347- }
348- printLLNumber (n, base);
349- }
350-
351- void Print::printLLNumber (uint64_t n, uint8_t base)
352- {
353- unsigned char buf[16 * sizeof (long )];
354- unsigned int i = 0 ;
355-
356- if (n == 0 ) {
357- print ((char )' 0' );
358- return ;
359- }
360-
361- while (n > 0 ) {
362- buf[i++] = n % base;
363- n /= base;
364- }
365-
366- for (; i > 0 ; i--) {
367- print ((char )(buf[i - 1 ] < 10 ? ' 0' + buf[i - 1 ] : ' A' + buf[i - 1 ] - 10 ));
368- }
369- }
370- #endif
444+ }
0 commit comments