Skip to content

Commit 41c0a72

Browse files
authored
Merge pull request arduino#310 from MartinL1/master
Add int64_t and uint64_t data types to Serial.print(ln)
2 parents 8b70e4c + 6f5a596 commit 41c0a72

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

cores/arduino/Print.cpp

+112
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,28 @@ size_t Print::print(unsigned long n, int base)
9494
else return printNumber(n, base);
9595
}
9696

97+
size_t Print::print(long long n, int base)
98+
{
99+
if (base == 0) {
100+
return write(n);
101+
} else if (base == 10) {
102+
if (n < 0) {
103+
int t = print('-');
104+
n = -n;
105+
return printULLNumber(n, 10) + t;
106+
}
107+
return printULLNumber(n, 10);
108+
} else {
109+
return printULLNumber(n, base);
110+
}
111+
}
112+
113+
size_t Print::print(unsigned long long n, int base)
114+
{
115+
if (base == 0) return write(n);
116+
else return printULLNumber(n, base);
117+
}
118+
97119
size_t Print::print(double n, int digits)
98120
{
99121
return printFloat(n, digits);
@@ -172,6 +194,20 @@ size_t Print::println(unsigned long num, int base)
172194
return n;
173195
}
174196

197+
size_t Print::println(long long num, int base)
198+
{
199+
size_t n = print(num, base);
200+
n += println();
201+
return n;
202+
}
203+
204+
size_t Print::println(unsigned long long num, int base)
205+
{
206+
size_t n = print(num, base);
207+
n += println();
208+
return n;
209+
}
210+
175211
size_t Print::println(double num, int digits)
176212
{
177213
size_t n = print(num, digits);
@@ -218,6 +254,81 @@ size_t Print::printNumber(unsigned long n, uint8_t base)
218254
return write(str);
219255
}
220256

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

263374
return n;
264375
}
376+

cores/arduino/Print.h

+5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class Print
3737
private:
3838
int write_error;
3939
size_t printNumber(unsigned long, uint8_t);
40+
size_t printULLNumber(unsigned long long, uint8_t);
4041
size_t printFloat(double, uint8_t);
4142
protected:
4243
void setWriteError(int err = 1) { write_error = err; }
@@ -69,6 +70,8 @@ class Print
6970
size_t print(unsigned int, int = DEC);
7071
size_t print(long, int = DEC);
7172
size_t print(unsigned long, int = DEC);
73+
size_t print(long long, int = DEC);
74+
size_t print(unsigned long long, int = DEC);
7275
size_t print(double, int = 2);
7376
size_t print(const Printable&);
7477

@@ -81,6 +84,8 @@ class Print
8184
size_t println(unsigned int, int = DEC);
8285
size_t println(long, int = DEC);
8386
size_t println(unsigned long, int = DEC);
87+
size_t println(long long, int = DEC);
88+
size_t println(unsigned long long, int = DEC);
8489
size_t println(double, int = 2);
8590
size_t println(const Printable&);
8691
size_t println(void);

0 commit comments

Comments
 (0)