64 bit integer types and printing

Hey all.

I’m trying to print the amount of free memory available on my SD card using the SDFat library.

Here a code snippet:

uint64_t JazaSD::freeSpace(){

   unsigned int clusterSize = 512L*sd.vol()->blocksPerCluster();
   Serial.printlnf("Cluster Size: %u bytes", clusterSize);

   int freeClusters = sd.vol()->freeClusterCount();
   if(freeClusters < 0) return 0;
   Serial.printlnf("FreeClusters: %d", freeClusters);

   uint64_t freeClusters64 = (uint64_t)(freeClusters);
   uint64_t freeSpace = (uint64_t)(clusterSize) * freeClusters64;
   Serial.printlnf("Free space: %u", freeSpace);
   Serial.printlnf("Free space: %lu", freeSpace);
   Serial.printlnf("Free space: %llu", freeSpace);
   Serial.printlnf("Free space (MB): %lu", freeSpace / 1024);
   Serial.printlnf("Free space (GB): %lu", freeSpace / 1048576L);
   Serial.printlnf("Free space: %f", freeSpace/1073741824L);
   return freeSpace ;
}

and here is what the output is when I run that code:

Cluster Size: 32768 bytes
FreeClusters: 491247
Free space: 3
Free space: 3
Free space: lu
Free space (MB): 0
Free space (GB): 0
Free space: 0.000000

What am I missing? Is there some special trick to printing 64-bit numbers?

If printing 64-bit numbers is not possible, how can I confirm that I have the correct number stored in my freeSpace variable?

I don’t think the Arduino print code knows about 64-bit integers at all. I would try switching to snprintf() instead.

2 Likes

Thanks for the response @bko here is my modified code.

It still doesn’t work.

   char tempBuf[100];

   unsigned int clusterSize = 512L*sd.vol()->blocksPerCluster();
   Serial.printlnf("Cluster Size: %u bytes", clusterSize);

   int freeClusters = sd.vol()->freeClusterCount();
   if(freeClusters < 0) return 0;
   Serial.printlnf("FreeClusters: %d", freeClusters);

   uint64_t freeSpace64 = (uint64_t)(clusterSize) * (uint64_t)(freeClusters);

   Serial.println("freeSpace64 using \"llu\" specifier:");
   snprintf(tempBuf, 100, "%llu", freeSpace64);
   Serial.println(tempBuf);
   Serial.println("freeSpace64 using \"lu\" specifier:");
   snprintf(tempBuf, 100, "%lu", freeSpace64);
   Serial.println(tempBuf);
   Serial.println("freeSpace64 using \"u\" specifier:");
   snprintf(tempBuf, 100, "%u", freeSpace64);
   Serial.println(tempBuf);

   Serial.println("freeSpace64 using printing tricks with \"lu\" specifier: ");
   snprintf(tempBuf, 100, "%0lu", freeSpace64/1000000UL);
   Serial.print(tempBuf);
   snprintf(tempBuf, 100, "%0lu", freeSpace64%1000000UL);
   Serial.println(tempBuf);
   Serial.println("freeSpace64 using printing tricks with \"llu\" specifier: ");
   snprintf(tempBuf, 100, "%0llu", freeSpace64/1000000UL);
   Serial.print(tempBuf);
   snprintf(tempBuf, 100, "%0llu", freeSpace64%1000000UL);
   Serial.println(tempBuf);

_
_
produces this output:
_

Cluster Size: 32768 bytes
FreeClusters: 491317
freeSpace64 using "llu" specifier:
lu
freeSpace64 using "lu" specifier:
129
freeSpace64 using "u" specifier:
129
freeSpace64 using printing tricks with "lu" specifier:
00
freeSpace64 using printing tricks with "llu" specifier:
lulu

There was a discussion about long long a long time ago and I guess things haven't changed since

1 Like

I’ve decided I don’t need too much precision here in the end.

So instead of counting the free bytes on the SD card, I’m comfortable just counting the free KBs, which can be stored in a 32-bit data type.

Thanks for the responses.

This will continue to haunt my dreams I’m sure but for now its not mission critical for me.

The Arduino print() and println() functions only support up to 32-bit types, so I created a modified version of the Arduino Print.h & Print.cpp files with overloads that accept 64-bit integer (signed long long int, unsigned long long int, int64_t, uint64_t) and long double types. They’re available here: Arduino/hardware/avr at master · Michael-Brodsky/Arduino · GitHub. You’ll need to copy them to your Arduino install folder (mine’s at C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino - or just search for the files under your Arduino folder) and replace the old files there (make a backup first!!). Cheers!