I made a big search about how to Format Numbers with the Arduino. I want to format unsigned Longs into a String in this format: "23,854,972".

The most of the snippets I found work only with the standard C / C++ Libraries. They dont work on the Arduino until I should put some STL libraries on the Arduino, which I want to prevent. It would be too bit of a overhead to import these only for this task. Also these Libraries will of course use some additional Flash and SRAM.

For my Application it is very important that the solution uses the minimum Flash, SRAM and is fast.

Even if a solution does not use STL or works only with the native Arduino Libraries, I would need help to decide which one is more effective in the sense of speed.

Incoming Number: 23854972 Arduino Program Output: 23,854,972

  • Have you tried writing a function that does what you're asking?
    – Avamander
    Aug 22, 2016 at 21:19

2 Answers 2


Here is my try at it: The usual way to write a number in decimal is to get the digits from right to left with a loop that looks something like

digit = '0' + val % 10;
val /= 10;

The following function does exactly this, with the addition of adding commas at the correct positions:

 * Format an unsigned long (32 bits) into a string in the format
 * "23,854,972".
 * The provided buffer must be at least 14 bytes long. The number will
 * be right-adjusted in the buffer. Returns a pointer to the first
 * digit.
char *ultoa(unsigned long val, char *s)
    char *p = s + 13;
    *p = '\0';
    do {
        if ((p - s) % 4 == 2)
            *--p = ',';
        *--p = '0' + val % 10;
        val /= 10;
    } while (val);
    return p;

Note that the string is right adjusted in the buffer, and the unused characters are not touched. This means you can get a right adjusted string by:

  • pre-filling the string with spaces (for padding)
  • calling the function above
  • using the original buffer as the right adjusted string

Otherwise you would use the returned pointer to have a string with no padding.

Here is a simple test program:

unsigned long vals[] = {0, 1, 2, 9, 10, 999, 1000, 0xffffffff};
const int COUNT = sizeof vals / sizeof vals[0];

void setup()
    char buffer[14];
    for (int i = 0; i < COUNT; i++) {
        unsigned long val = vals[i];
        Serial.println(ultoa(val, buffer));

void loop() {}

The most effective way to format numbers on Arduino

If "effective way" is minimum effort you could hack the avr-libc source code for ltoa and do something like below:

char *ultos_recursive(unsigned long val, char *s, unsigned radix, int pos)
  int c;

  if (val >= radix)
    s = ultos_recursive(val / radix, s, radix, pos+1);
  c = val % radix;
  c += (c < 10 ? '0' : 'a' - 10);
  *s++ = c;
  if (pos % 3 == 0) *s++ = ',';
  return s;

char *ltos(long val, char *s, int radix)
  if (radix < 2 || radix > 36) {
    s[0] = 0;
  } else {
    char *p = s;
    if (radix == 10 && val < 0) {
      val = -val;
      *p++ = '-';
    p = ultos_recursive(val, p, radix, 0) - 1;
    *p = 0;
  return s;

void setup()
  while (!Serial);

  char buf[32];
  Serial.println(ltos(12345678, buf, 10));
  Serial.println(ltos(-12345678, buf, 10));

void loop()

Gives the output:



PS: Please see the table driven, non-recursive, number conversion in Cosa (source and benchmark) for a lean and faster implementation.

  • How would I check which answer/solution gives the faster result? I always print delta-micros() but is there a better way? Aug 23, 2016 at 10:28
  • The above solution is slow. This is a fast hack to show that you do not need all the libraries mentioned in your original question. See @EdgarBonet's answer for a solution that runs much faster. It can be improved with table lookup to avoid division/modulo. That is what the Cosa version does. Aug 23, 2016 at 10:46
  • Thank you very much. But how you know if this one or the other one is faster? How to determine it? Aug 23, 2016 at 11:01
  • Estimate the algorithms complexity and behavior. Read the generated assembly code and calculate the number of clock cycles. Write a test program and verify. Aug 23, 2016 at 12:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.