Skip to content

Add int64_t and uint64_t data types to Serial.print(ln) #310

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from Oct 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions cores/arduino/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,28 @@ size_t Print::print(unsigned long n, int base)
else return printNumber(n, base);
}

size_t Print::print(long long n, int base)
{
if (base == 0) {
return write(n);
} else if (base == 10) {
if (n < 0) {
int t = print('-');
n = -n;
return printULLNumber(n, 10) + t;
}
return printULLNumber(n, 10);
} else {
return printULLNumber(n, base);
}
}

size_t Print::print(unsigned long long n, int base)
{
if (base == 0) return write(n);
else return printULLNumber(n, base);
}

size_t Print::print(double n, int digits)
{
return printFloat(n, digits);
Expand Down Expand Up @@ -172,6 +194,20 @@ size_t Print::println(unsigned long num, int base)
return n;
}

size_t Print::println(long long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}

size_t Print::println(unsigned long long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}

size_t Print::println(double num, int digits)
{
size_t n = print(num, digits);
Expand Down Expand Up @@ -218,6 +254,81 @@ size_t Print::printNumber(unsigned long n, uint8_t base)
return write(str);
}

// REFERENCE IMPLEMENTATION FOR ULL
// size_t Print::printULLNumber(unsigned long long n, uint8_t base)
// {
// // if limited to base 10 and 16 the bufsize can be smaller
// char buf[65];
// char *str = &buf[64];

// *str = '\0';

// // prevent crash if called with base == 1
// if (base < 2) base = 10;

// do {
// unsigned long long t = n / base;
// char c = n - t * base; // faster than c = n%base;
// n = t;
// *--str = c < 10 ? c + '0' : c + 'A' - 10;
// } while(n);

// return write(str);
// }

// FAST IMPLEMENTATION FOR ULL
size_t Print::printULLNumber(unsigned long long n64, uint8_t base)
{
// if limited to base 10 and 16 the bufsize can be 20
char buf[64];
uint8_t i = 0;
uint8_t innerLoops = 0;

// prevent crash if called with base == 1
if (base < 2) base = 10;

// process chunks that fit in "16 bit math".
uint16_t top = 0xFFFF / base;
uint16_t th16 = 1;
while (th16 < top)
{
th16 *= base;
innerLoops++;
}

while (n64 > th16)
{
// 64 bit math part
uint64_t q = n64 / th16;
uint16_t r = n64 - q*th16;
n64 = q;

// 16 bit math loop to do remainder. (note buffer is filled reverse)
for (uint8_t j=0; j < innerLoops; j++)
{
uint16_t qq = r/base;
buf[i++] = r - qq*base;
r = qq;
}
}

uint16_t n16 = n64;
while (n16 > 0)
{
uint16_t qq = n16/base;
buf[i++] = n16 - qq*base;
n16 = qq;
}

size_t bytes = i;
for (; i > 0; i--)
write((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));

return bytes;
}

size_t Print::printFloat(double number, uint8_t digits)
{
size_t n = 0;
Expand Down Expand Up @@ -262,3 +373,4 @@ size_t Print::printFloat(double number, uint8_t digits)

return n;
}

5 changes: 5 additions & 0 deletions cores/arduino/Print.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Print
private:
int write_error;
size_t printNumber(unsigned long, uint8_t);
size_t printULLNumber(unsigned long long, uint8_t);
size_t printFloat(double, uint8_t);
protected:
void setWriteError(int err = 1) { write_error = err; }
Expand Down Expand Up @@ -69,6 +70,8 @@ class Print
size_t print(unsigned int, int = DEC);
size_t print(long, int = DEC);
size_t print(unsigned long, int = DEC);
size_t print(long long, int = DEC);
size_t print(unsigned long long, int = DEC);
size_t print(double, int = 2);
size_t print(const Printable&);

Expand All @@ -81,6 +84,8 @@ class Print
size_t println(unsigned int, int = DEC);
size_t println(long, int = DEC);
size_t println(unsigned long, int = DEC);
size_t println(long long, int = DEC);
size_t println(unsigned long long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
Expand Down