Skip to content

Commit

Permalink
Merge pull request #310 from MartinL1/master
Browse files Browse the repository at this point in the history
Add int64_t and uint64_t data types to Serial.print(ln)
  • Loading branch information
hathach authored Oct 1, 2021
2 parents 8b70e4c + 6f5a596 commit 41c0a72
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
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

0 comments on commit 41c0a72

Please sign in to comment.