1
1
/*
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.
4
3
5
4
This library is free software; you can redistribute it and/or
6
5
modify it under the terms of the GNU Lesser General Public
9
8
10
9
This library is distributed in the hope that it will be useful,
11
10
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.
14
13
15
14
You should have received a copy of the GNU Lesser General Public
16
15
License along with this library; if not, write to the Free Software
17
16
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
+ */
22
18
23
19
#include < stdlib.h>
24
20
#include < string.h>
@@ -108,6 +104,31 @@ size_t Print::print(unsigned long n, int base)
108
104
}
109
105
}
110
106
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
+
111
132
size_t Print::print (double n, int digits)
112
133
{
113
134
return printFloat (n, digits);
@@ -186,6 +207,20 @@ size_t Print::println(unsigned long num, int base)
186
207
return n;
187
208
}
188
209
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
+
189
224
size_t Print::println (double num, int digits)
190
225
{
191
226
size_t n = print (num, digits);
@@ -262,6 +297,100 @@ size_t Print::printNumber(unsigned long n, uint8_t base)
262
297
return write (str);
263
298
}
264
299
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
+
265
394
size_t Print::printFloat (double number, uint8_t digits)
266
395
{
267
396
size_t n = 0 ;
@@ -300,71 +429,16 @@ size_t Print::printFloat(double number, uint8_t digits)
300
429
301
430
// Print the decimal point, but only if there are digits beyond
302
431
if (digits > 0 ) {
303
- n += print (" . " );
432
+ n += print (' . ' );
304
433
}
305
434
306
435
// Extract digits from the remainder one at a time
307
436
while (digits-- > 0 ) {
308
437
remainder *= 10.0 ;
309
- int toPrint = int ( remainder ) ;
438
+ unsigned int toPrint = ( unsigned int ) remainder ;
310
439
n += print (toPrint);
311
440
remainder -= toPrint;
312
441
}
313
442
314
443
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