Printing Large Numbers on Arduinos

2^32 (4,294,967,296) sounds like a big number. It’s over four billion, after all.

Large as it is, four billion (or more) is increasingly a perfectly reasonable number to be working with. For instance, it represents access to four gigabytes of memory, which isn’t much, these days. 32-bit math has become limiting, which is why computers switched to 64-bit hardware about ten years ago. (It was the memory addressing that made it happen.)

There’s good support for 64-bit numbers on desktop software, too. C provides the “unsigned long long int” (or uint64_t) type, which can hold numbers up to 2^64-1, and this covers nearly all of the cases that don’t fit in 32 bits.

Unfortunately, these large numbers, being newer than their 16-bit and 32-bit counterparts, aren’t always supported as well on smaller devices like microcontrollers. (After all, an 8-bit microcontroller has to do a lot of shuffling and carrying to do math with them.) Arduino C’s usual, super easy to use Serial.Print() function doesn’t understand how to handle anything larger than 32 bits. Trying an end run using tricks like sprintf(myString,”%llu”,bigValue) doesn’t work, either.

The proper solution would be to find a way to include 64-bit capable printf() code in the Arduino C compiler — but I suspect that if this were easy, someone would have done it by now. So I came up with a hack: use long division.

Integers, in any base, can be constructed digit by digit, and Arduinos can still do math with 64-bit numbers. So, to print out large numbers, take the number modulo ten, add that to the left end of your string, take it away from the original number, and divide it by ten. It’s not super efficient, needing an integer division operation for each digit — but it will still run in O(log(n)) time, and shouldn’t take very long at all, even for large numbers. It can be done in C readily enough, but the BASIC-like string concatenation capabilities of Arduino C make it easy.

Here’s the code, which should work for all Arduino-compatible devices:

void bigPrint(uint64_t n){
  //Print unsigned long long integers (uint_64t)
  //CC (BY-NC) 2020
  //M. Eric Carr / paleotechnologist.net
  unsigned char temp;
  String result=""; //Start with a blank string
  if(n==0){Serial.println(0);return;} //Catch the zero case
  while(n){
    temp = n % 10;
    result=String(temp)+result; //Add this digit to the left of the string
    n=(n-temp)/10;      
    }//while
  Serial.println(result);
  }

Now, 18,446,744,073,709,551,615 is the limit. Happy large-number computing!

This entry was posted in Arduino, C, Coding, HOW-TO, Math and tagged , , , , , , , , , . Bookmark the permalink.

Leave a Reply