Skip to content

Commit 3c3b27e

Browse files
RobTillaartfacchinm
authored andcommitted
Add support for 64 bit integer printing
1 parent 1ebf4cd commit 3c3b27e

File tree

2 files changed

+116
-0
lines changed

2 files changed

+116
-0
lines changed

api/Print.cpp

+111
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,28 @@ size_t Print::print(unsigned long n, int base)
105105
else return printNumber(n, base);
106106
}
107107

108+
size_t Print::print(long long n, int base)
109+
{
110+
if (base == 0) {
111+
return write(n);
112+
} else if (base == 10) {
113+
if (n < 0) {
114+
int t = print('-');
115+
n = -n;
116+
return printULLNumber(n, 10) + t;
117+
}
118+
return printULLNumber(n, 10);
119+
} else {
120+
return printULLNumber(n, base);
121+
}
122+
}
123+
124+
size_t Print::print(unsigned long long n, int base)
125+
{
126+
if (base == 0) return write(n);
127+
else return printULLNumber(n, base);
128+
}
129+
108130
size_t Print::print(double n, int digits)
109131
{
110132
return printFloat(n, digits);
@@ -183,6 +205,20 @@ size_t Print::println(unsigned long num, int base)
183205
return n;
184206
}
185207

208+
size_t Print::println(long long num, int base)
209+
{
210+
size_t n = print(num, base);
211+
n += println();
212+
return n;
213+
}
214+
215+
size_t Print::println(unsigned long long num, int base)
216+
{
217+
size_t n = print(num, base);
218+
n += println();
219+
return n;
220+
}
221+
186222
size_t Print::println(double num, int digits)
187223
{
188224
size_t n = print(num, digits);
@@ -219,6 +255,81 @@ size_t Print::printNumber(unsigned long n, uint8_t base)
219255
return write(str);
220256
}
221257

258+
// REFERENCE IMPLEMENTATION FOR ULL
259+
// size_t Print::printULLNumber(unsigned long long n, uint8_t base)
260+
// {
261+
// // if limited to base 10 and 16 the bufsize can be smaller
262+
// char buf[65];
263+
// char *str = &buf[64];
264+
265+
// *str = '\0';
266+
267+
// // prevent crash if called with base == 1
268+
// if (base < 2) base = 10;
269+
270+
// do {
271+
// unsigned long long t = n / base;
272+
// char c = n - t * base; // faster than c = n%base;
273+
// n = t;
274+
// *--str = c < 10 ? c + '0' : c + 'A' - 10;
275+
// } while(n);
276+
277+
// return write(str);
278+
// }
279+
280+
// FAST IMPLEMENTATION FOR ULL
281+
size_t Print::printULLNumber(unsigned long long n64, uint8_t base)
282+
{
283+
// if limited to base 10 and 16 the bufsize can be 20
284+
char buf[64];
285+
uint8_t i = 0;
286+
uint8_t innerLoops = 0;
287+
288+
// prevent crash if called with base == 1
289+
if (base < 2) base = 10;
290+
291+
// process chunks that fit in "16 bit math".
292+
uint16_t top = 0xFFFF / base;
293+
uint16_t th16 = 1;
294+
while (th16 < top)
295+
{
296+
th16 *= base;
297+
innerLoops++;
298+
}
299+
300+
while (n64 > th16)
301+
{
302+
// 64 bit math part
303+
uint64_t q = n64 / th16;
304+
uint16_t r = n64 - q*th16;
305+
n64 = q;
306+
307+
// 16 bit math loop to do remainder. (note buffer is filled reverse)
308+
for (uint8_t j=0; j < innerLoops; j++)
309+
{
310+
uint16_t qq = r/base;
311+
buf[i++] = r - qq*base;
312+
r = qq;
313+
}
314+
}
315+
316+
uint16_t n16 = n64;
317+
while (n16 > 0)
318+
{
319+
uint16_t qq = n16/base;
320+
buf[i++] = n16 - qq*base;
321+
n16 = qq;
322+
}
323+
324+
size_t bytes = i;
325+
for (; i > 0; i--)
326+
write((char) (buf[i - 1] < 10 ?
327+
'0' + buf[i - 1] :
328+
'A' + buf[i - 1] - 10));
329+
330+
return bytes;
331+
}
332+
222333
size_t Print::printFloat(double number, uint8_t digits)
223334
{
224335
size_t n = 0;

api/Print.h

+5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class Print
3434
private:
3535
int write_error;
3636
size_t printNumber(unsigned long, uint8_t);
37+
size_t printULLNumber(unsigned long long, uint8_t);
3738
size_t printFloat(double, uint8_t);
3839
protected:
3940
void setWriteError(int err = 1) { write_error = err; }
@@ -62,6 +63,8 @@ class Print
6263
size_t print(unsigned int, int = DEC);
6364
size_t print(long, int = DEC);
6465
size_t print(unsigned long, int = DEC);
66+
size_t print(long long, int = DEC);
67+
size_t print(unsigned long long, int = DEC);
6568
size_t print(double, int = 2);
6669
size_t print(const Printable&);
6770

@@ -74,6 +77,8 @@ class Print
7477
size_t println(unsigned int, int = DEC);
7578
size_t println(long, int = DEC);
7679
size_t println(unsigned long, int = DEC);
80+
size_t println(long long, int = DEC);
81+
size_t println(unsigned long long, int = DEC);
7782
size_t println(double, int = 2);
7883
size_t println(const Printable&);
7984
size_t println(void);

0 commit comments

Comments
 (0)