Serial.print() of a 64-bit DOUBLE

I've read in the Reference section that the DOUBLE data type on the Due is a 64-bit variable. Unfortunately, the Serial.print won't handle a 64-bit variable. I haven't been able to print out a uint64_t either.

Any ideas of how to print this?

I've looked into bit shifting the top 32-bits into an unsigned int, and then printing the high 32-bits followed by the low 32-bits, but apparently the bit shift operator defaults to a 32-bit operation as well.

The reason I'm trying to do this is because I stuck a 16 GB SD card into my wifi shield and can read it using the SD library, but it won't show the correct size of the SD card because it's so large. The unsigned int will only show up to ~4 GB. (0xFFFFFFFF = 4294967295 decimal).

Time to program the BigInt class?

Made this code for printing int64_t and uint64_t some time ago on an UNO - IDE 0.22;

Should work for DUE too I guess, but is not tested other than on my UNO (so all disclaimers apply ;).
Just received my first DUE yesterday not downloaded the IDE for that to play with it.

Add this snippet to print.cpp to print the 64 bit integers, mind you! a simple sketch adds about 8KB!

Snippet for print.cpp

#ifdef SUPPORT_LONGLONG

void Print::println(int64_t n, uint8_t base)
{
  print(n, base);
  println();
}

void Print::print(int64_t n, uint8_t base)
{
  if (n < 0)
  {
    print((char)'-');
    n = -n;
  }
  if (base < 2) base = 2;
  print((uint64_t)n, base);
}

void Print::println(uint64_t n, uint8_t base)
{
  print(n, base);
  println();
}

void Print::print(uint64_t n, uint8_t base)
{
  if (base < 2) base = 2;
  printLLNumber(n, base);
}

void Print::printLLNumber(uint64_t n, uint8_t base)
{
  unsigned char buf[16 * sizeof(long)]; 
  unsigned int i = 0;

  if (n == 0) 
  {
    print((char)'0');
    return;
  }

  while (n > 0) 
  {
    buf[i++] = n % base;
    n /= base;
  }

  for (; i > 0; i--)
    print((char) (buf[i - 1] < 10 ?
      '0' + buf[i - 1] :
      'A' + buf[i - 1] - 10));
}
#endif

patched version of print.h

/*
  Print.h - Base class that provides print() and println()
  Copyright (c) 2008 David A. Mellis.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#ifndef Print_h
#define Print_h

#include <inttypes.h>
#include <stdio.h> // for size_t

#include "WString.h"

#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
#define BYTE 0

// uncomment next line to support printing of 64 bit ints.
#define SUPPORT_LONGLONG

class Print
{
  private:
    void printNumber(unsigned long, uint8_t);
#ifdef SUPPORT_LONGLONG
	void printLLNumber(uint64_t, uint8_t );
#endif
    void printFloat(double, uint8_t);
  public:
    virtual void write(uint8_t) = 0;
    virtual void write(const char *str);
    virtual void write(const uint8_t *buffer, size_t size);
    
    void print(const String &);
    void print(const char[]);
    void print(char, uint8_t = BYTE);
    void print(unsigned char, uint8_t = BYTE);
    void print(int, uint8_t = DEC);
    void print(unsigned int, uint8_t = DEC);
    void print(long, uint8_t = DEC);
    void print(unsigned long, uint8_t = DEC);
    void print(double, uint8_t = 2);

    void println(const String &s);
    void println(const char[]);
    void println(char, uint8_t = BYTE);
    void println(unsigned char, uint8_t = BYTE);
    void println(int, uint8_t = DEC);
    void println(unsigned int, uint8_t = DEC);
    void println(long, uint8_t = DEC);
    void println(unsigned long, uint8_t = DEC);
    void println(double, uint8_t = 2);
    void println(void);
	
#ifdef SUPPORT_LONGLONG
	void println(int64_t, uint8_t = DEC);
	void print(int64_t, uint8_t = DEC);
	void println(uint64_t, uint8_t = DEC);
	void print(uint64_t, uint8_t = DEC);
#endif
	
};

#endif

Can you confirm this works on DUE?

void setup()
{
  Serial.begin(9600);
  Serial.print(1000000000000LL, 10);
  Serial.println();
  Serial.print(-1000000000000LL, 10);
  Serial.println();
  Serial.println(1000000000000LL, 10);
  Serial.println(-1000000000000LL, 10);
}

void loop(){}

printing doubles I did not investigate yet but can be tackled in the same way as printing floats are handled using the printing of longs (on UNO)

Just had a look at the 1.0 IDE version, (still not downloaded DUE IDE )

The code should be extended with size_t return values, and some math to calc the right value ...

I made those modifications to print.cpp and print.h, and it worked just great on my DUE. I am now able to display the true size of my 16 GB SD Card:

Volume size (bytes): 15923150848

I didn't change the methods to size_t though, it worked fine without that change. (I did try it, and it threw a bunch of errors, so I left them as void).

As you noted, the change does add about 8KB, but heck, I've got a DUE with 512K program memory, so I can spare the extra 8K. Woot.

good to hear it works!

Is the performance fast enough?
can you test printing 100 int64's @115200 and time it with micros?
and do the same with 100 int32's?

The size_t thing should be solved someday but apparently not now :wink:

You also stated that you were not able to print a double ? but floats works?
(there is definitely no x.yyyE-nnn engineering format yet)

Did some rework on the printing of int64's.
Most important, I replaced the % math with less expensive code => test app size went from 9766 => 6966

  • added constrain for base
  • merged the printLLnumber into print(uint64_t, int); as that was the only one that called.

still todo
- need to support base = BYTE. not supported in 1.0 so will not be implemented. (patched below)

  • include size_t for 1.0 version
#ifdef SUPPORT_LONGLONG

void Print::println(int64_t number, uint8_t base)
{
  print(number, base);
  println();
}

void Print::print(int64_t number, uint8_t base)
{
  if (number < 0)
  {
    write('-');
    number = -number;
  }
  print((uint64_t)number, base);
}

void Print::println(uint64_t number, uint8_t base)
{
  print(number, base);
  println();
}

void Print::print(uint64_t number, uint8_t base)
{
  unsigned char buf[64];
  uint8_t i = 0;

  if (number == 0) 
  {
    print((char)'0');
    return;
  }
  
  if (base < 2) base = 2;
  else if (base > 16) base = 16;

  while (number > 0) 
  {
    uint64_t q = number/base;
    buf[i++] = number - q*base;
    number = q;
  }
  for (; i > 0; i--) 
    write((char) (buf[i - 1] < 10 ?
      '0' + buf[i - 1] :
      'A' + buf[i - 1] - 10));
}
#endif

update ==> remove printLLnumber() from print.h too

update ==> I had already patched print.cpp to use uint8_t for param base in all functions. [change to int will solve this]

extra code to append to for 1.0x print.cpp

#ifdef SUPPORT_LONGLONG

size_t Print::println(int64_t number, int base)
{
  size_t n = 0;
  n += print(number, base);
  n += println();
  return n;
}

size_t Print::print(int64_t number, int base)
{
  size_t n = 0;
  if (number < 0)
  {
    write('-');
	number = -number;
	n++;
  }
  n += print((uint64_t)number, base);
  return n;
}

size_t Print::println(uint64_t number, int base)
{
  size_t n = 0;
  n += print((uint64_t)number, base);
  n += println();
  return n;
}

size_t Print::print(uint64_t number, int base)
{
  size_t n = 0;
  unsigned char buf[64];
  uint8_t i = 0;

  if (number == 0) 
  {
    n += print((char)'0');
    return n;
  }
  
  if (base < 2) base = 2;
  else if (base > 16) base = 16;

  while (number > 0) 
  {
    uint64_t q = number/base;
    buf[i++] = number - q*base;
    number = q;
  } 
  
  for (; i > 0; i--) 
    n += write((char) (buf[i - 1] < 10 ?
      '0' + buf[i - 1] :
      'A' + buf[i - 1] - 10));
	  
   return n;
}
#endif

additional code for 1.0x print.h

// uncomment next line for int64 support
#define SUPPORT_LONGLONG

.... 
		
#ifdef SUPPORT_LONGLONG
	size_t println(int64_t, int = DEC);
	size_t print(int64_t, int = DEC);
	size_t println(uint64_t, int = DEC);
	size_t print(uint64_t, int = DEC);
#endif

robtillaart, thanks for your great code

i test with uint64_t a = 4294329243;

it's can display in DEC, BIN, OCT, HEX all correct.

thank you very much. :slight_smile:

robtillaart:
extra code to append to for 1.0x print.cpp

#ifdef SUPPORT_LONGLONG

size_t Print::println(int64_t number, int base)
{
 size_t n = 0;
 n += print(number, base);
 n += println();
 return n;
}

size_t Print::print(int64_t number, int base)
{
 size_t n = 0;
 if (number < 0)
 {
   write('-');
number = -number;
n++;
 }
 n += print((uint64_t)number, base);
 return n;
}

size_t Print::println(uint64_t number, int base)
{
 size_t n = 0;
 n += print((uint64_t)number, base);
 n += println();
 return n;
}

size_t Print::print(uint64_t number, int base)
{
 size_t n = 0;
 unsigned char buf[64];
 uint8_t i = 0;

if (number == 0)
 {
   n += print((char)'0');
   return n;
 }
 
 if (base < 2) base = 2;
 else if (base > 16) base = 16;

while (number > 0)
 {
   uint64_t q = number/base;
   buf[i++] = number - q*base;
   number = q;
 }
 
 for (; i > 0; i--)
   n += write((char) (buf[i - 1] < 10 ?
     '0' + buf[i - 1] :
     'A' + buf[i - 1] - 10));
 
  return n;
}
#endif




additional code for 1.0x print.h


// uncomment next line for int64 support
#define SUPPORT_LONGLONG

....

#ifdef SUPPORT_LONGLONG
size_t println(int64_t, int = DEC);
size_t print(int64_t, int = DEC);
size_t println(uint64_t, int = DEC);
size_t print(uint64_t, int = DEC);
#endif

you're welcome !

After following this thread I tried to implement it using Arduino IDE 1.0.x with the arduino mega and I receive these compiling errors

C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp: In member function 'size_t Print::print(const __FlashStringHelper*)':
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:45: warning: '__progmem__' attribute ignored
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp: At global scope:
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:274: error: prototype for 'size_t Print::println(int64_t, int)' does not match any in class 'Print'
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\/Print.h:89: error: candidates are: size_t Print::println(uint64_t, uint8_t)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\/Print.h:87: error:                 size_t Print::println(int64_t, uint8_t)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:128: error:                 size_t Print::println()
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:198: error:                 size_t Print::println(const Printable&)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:191: error:                 size_t Print::println(double, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:184: error:                 size_t Print::println(long unsigned int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:177: error:                 size_t Print::println(long int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:170: error:                 size_t Print::println(unsigned int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:163: error:                 size_t Print::println(int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:156: error:                 size_t Print::println(unsigned char, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:149: error:                 size_t Print::println(char)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:142: error:                 size_t Print::println(const char*)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:135: error:                 size_t Print::println(const String&)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:116: error:                 size_t Print::println(const __FlashStringHelper*)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:282: error: prototype for 'size_t Print::print(int64_t, int)' does not match any in class 'Print'
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\/Print.h:90: error: candidates are: size_t Print::print(uint64_t, uint8_t)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\/Print.h:88: error:                 size_t Print::print(int64_t, uint8_t)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:123: error:                 size_t Print::print(const Printable&)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:111: error:                 size_t Print::print(double, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:105: error:                 size_t Print::print(long unsigned int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:89: error:                 size_t Print::print(long int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:84: error:                 size_t Print::print(unsigned int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:79: error:                 size_t Print::print(int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:74: error:                 size_t Print::print(unsigned char, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:69: error:                 size_t Print::print(char)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:64: error:                 size_t Print::print(const char*)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:55: error:                 size_t Print::print(const String&)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:43: error:                 size_t Print::print(const __FlashStringHelper*)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:295: error: prototype for 'size_t Print::println(uint64_t, int)' does not match any in class 'Print'
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\/Print.h:89: error: candidates are: size_t Print::println(uint64_t, uint8_t)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\/Print.h:87: error:                 size_t Print::println(int64_t, uint8_t)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:128: error:                 size_t Print::println()
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:198: error:                 size_t Print::println(const Printable&)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:191: error:                 size_t Print::println(double, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:184: error:                 size_t Print::println(long unsigned int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:177: error:                 size_t Print::println(long int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:170: error:                 size_t Print::println(unsigned int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:163: error:                 size_t Print::println(int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:156: error:                 size_t Print::println(unsigned char, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:149: error:                 size_t Print::println(char)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:142: error:                 size_t Print::println(const char*)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:135: error:                 size_t Print::println(const String&)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:116: error:                 size_t Print::println(const __FlashStringHelper*)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:303: error: prototype for 'size_t Print::print(uint64_t, int)' does not match any in class 'Print'
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\/Print.h:90: error: candidates are: size_t Print::print(uint64_t, uint8_t)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\/Print.h:88: error:                 size_t Print::print(int64_t, uint8_t)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:123: error:                 size_t Print::print(const Printable&)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:111: error:                 size_t Print::print(double, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:105: error:                 size_t Print::print(long unsigned int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:89: error:                 size_t Print::print(long int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:84: error:                 size_t Print::print(unsigned int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:79: error:                 size_t Print::print(int, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:74: error:                 size_t Print::print(unsigned char, int)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:69: error:                 size_t Print::print(char)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:64: error:                 size_t Print::print(const char*)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:55: error:                 size_t Print::print(const String&)
C:\arduino\arduino-1.0.5\hardware\arduino\cores\arduino\Print.cpp:43: error:                 size_t Print::print(const __FlashStringHelper*)

Does anyone have any suggestions? Thanks.

It worked on 1.0.4 (I do not run 1.0.5)

Can you post your edited print.h and print.cpp file (please use code tags)

I just had a look at this code and have a few questions:

  • Why is the implementation of printLLNumber so different from the one in printNumber? If there is no particular reason to make it different, perhaps it should be more similar?
  • Did you try just modifying printNumber to accepted 64-bits numbers? Does that increase sketch sizes too much?
  • Your code includes an #ifdef, but AFAIU the compiler will automatically exclude functions that are not referenced (due to -Wl,--gc-sections and -ffunction-sections).

in #7 printLLnumber is replaced by a print that is more similar to existing code.

What I still am thinking about with this one is that the 64 bit division is REALLY expensive..

First strategy is to scale down asap

size_t Print::print(uint64_t number64, uint8_t base)  // base to uint8_t 
{
  size_t n = 0;
  unsigned char buf[64];
  uint8_t i = 0;

  if (number64 == 0) 
  {
    write('0');  // write is faster than print.
    return  1;
  }
  
  // keep base in "reasonable limits
  if (base < 2) base = 2;
  else if (base > 16) base = 16;

  // use 64 bit math asl long as needed
  while (number64 >  4294967295)  // > 32 bit
  {
    uint64_t q = number64/base;
    buf[i++] = number64 - q*base;
    number64 = q;
  } 

uint32_t number32 = number64;
 while (number32  >  65535)  // > 16 bit but fit in 32 bit 
  {
    uint32_T q = number32/base;
    buf[i++] = number32 - q*base;
    number32 = q;
  } 

// maybe this step is too much?
uint16_t number16 = number32;  // last digits fit in 16 bit
 while (number16 >  0) 
  {
    uint16_T q = number16/base;
    buf[i++] = number16 - q*base;
    number16 = q;
  } 
  
  n += i;
  for (; i > 0; i--) 
    write((char) (buf[i - 1] < 10 ?
      '0' + buf[i - 1] :
      'A' + buf[i - 1] - 10));
	  
   return n;
}

Another strategy is to split of 4 digits at a time and use a print (16 bit)
has smaller footprint but also a "problem"...

size_t Print::print(uint64_t number64, uint8_t base)  // base to uint8_t 
{
  if (number64 == 0) 
  {
    write('0');  // write is faster than print.
    return  1;
  }
  
  // keep base in "reasonable limits
  if (base < 2) base = 2;
  else if (base > 16) base = 16;

  size_t n = 0;
  while (number64 >  0)
  {
    uint64_t  q = number64 / 1000;  // 7 divisions max, 
    uint16_t r =  number64 - q * 1000;

    n += print(r, base);  //  <<<<<<<<  problem here is leading zeroos.

    number64 = q;
  }
   return n;
}

The two strategies can be "mixed" to maximize performance,
split the 64 bit in

  • one 16 bit 4 digits max: 9,999
  • two 32 bits numbers of 9 digits max: 999,999,999
    and split the 32 bit numbers in three (max) 4 digit 16 bit numbers
    The 16 bit math that remains is faster that a 64 bit %/ 10 loop.

Not tested well what best strategy is, but there is def. room for further improvements.

The internal buffer [64] is way too large if base = 10; ,
264-1 = 18,446,744,073,709,551,615 => 20 digits
so buffer[24] should be enough, if only base 10 and base 16 are used.

(in fact in base 10 an N bit number will fit always in a string of length N/3 + 3 )

Some variations of printing uint64_t tested this morning.

Measurements:

  • NOT embedded in the print Class => sort of simulation more.
  • one call only with MAX U LONG LONG
  • measurement in micros (stepsize 4), but the results are not that close.
  • nothing done to prevent interrupt, so indicative at best.
In attachment at the bottom of this post

results for base 10; (times inuSec) - sketch runs base 2..16

10

18446744073709551615	printLLNumber	13012	first version for reference only
18446744073709551615	print0	7620
18446744073709551615	print1	7632
18446744073709551615	print2	5004
6155517097374444618	print3	4064	<<< FAIL, but was interesting wrt thinking how to
18446744073709551615	print4	5136
18446744073709551615	print5	5128
18446744073709551615	print6	2052	<<< base 10 only
18446744073709551615	print7	1812	<<< base 10 only
18446744073709551615	print8	1888
18446744073709551615	print9	2160
18446744073709551615	print10	1836

in general, again a trade of size versus speed.

printLong64Test.zip (2.13 KB)

From the test above some preliminary conclusions:

printing 64 bits integers is not a daily job on an Arduino. 64 bit math is slow, but as these implementations show there is quite some performance to be gained at the cost of some footprint.

print6() is dedicated for base10 only, it has very good performance footprint ratio.

print9() is my favorite for all bases. The implementation is still reasonably straightforward while performance is very good. The footprint is substantially larger than print6() (estimate factor 2+)

printing 64 bits integers is not a daily job on an Arduino. 64 bit math is slow, but as these implementations show there is quite some performance to be gained at the cost of some footprint.

Well on the Due there is 512kB of program memory and its 32 bit throughout. The
only performance "gotcha" is the lack of divide hardware. Any method of printing that
avoids / and % will likely win. The fastest base 10 printing algorithm is test-subtraction
using a table of powers of ten - with that much flash available its not prohibitive to
store the table.

You need to avoid Serial library calls to get a true benchmark figure, in other
words time sprintf style conervsion, not printf style.

Has this code ever been added to mainstream? I am on IDE 1.6.9 and Serial.println with "long long" is not going to compile.

@sadr0b0t

Created a pull request - Add support for 64 bit integer printing by RobTillaart · Pull Request #6608 · arduino/Arduino · GitHub - with the code for long long ...

You can print uin64_t, int64_t and double this way:

uint64_t bignum0 = 0xFFFFFFFFFFFFFFllu;
uint64_t bignum1 = pow(2, 64) - 1;
int64_t bignum2 = - pow(2, 62);
double bignum3 = -1.123456789876543;

void setup() {
  Serial.begin(250000);
}

void loop() {
  printf(" bignum0 = 0x%llx\n", bignum0);
  printf(" bignum1 = %llu\n", bignum1);
  printf(" bignum2 = %lld\n", bignum2);
  Serial.print(" bignum3 = ");
  Serial.println(bignum3,15);
  delay(1000);
}