9

Say I have a large number (integer or float) like 12345 and I want it to look like 12,345.

How would I accomplish that?

I'm trying to do this for an iPhone app, so something in Objective-C or C would be nice.

Svante
  • 50,694
  • 11
  • 78
  • 122
Kriem
  • 8,666
  • 16
  • 72
  • 120
  • There are also some good answers here: [How to add commas to number every 3 digits in Objective C?](http://stackoverflow.com/questions/2233824/how-to-add-commas-to-number-every-3-digits-in-objective-c). – JohnK May 09 '13 at 23:59

7 Answers7

31

Here is the answer.

  NSNumber* number = [NSNumber numberWithDouble:10000000];
  NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
  [numberFormatter setNumberStyle:kCFNumberFormatterDecimalStyle];
  [numberFormatter setGroupingSeparator:@","];
  NSString* commaString = [numberFormatter stringForObjectValue:number];
  [numberFormatter release];
  NSLog(@"%@ -> %@", number, commaString);
wookay
  • 592
  • 3
  • 3
  • 1
    One small update: it would be better to use NSNumberFormatterDecimalStyle instead of kCFNumberFormatterDecimalStyle (explicit enum comparison on XCode 5 shows a warning) – Guy Chen Feb 18 '14 at 08:25
17

Try using an NSNumberFormatter.

This should allow you to handle this correctly on an iPhone. Make sure you use the 10.4+ style, though. From that page:

"iPhone OS: The v10.0 compatibility mode is not available on iPhone OS—only the 10.4 mode is available."

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
3

At least on Mac OS X, you can just use the "'" string formatter with printf(3).

$ man 3 printf

     `''          Decimal conversions (d, u, or i) or the integral portion
                  of a floating point conversion (f or F) should be
                  grouped and separated by thousands using the non-mone-
                  tary separator returned by localeconv(3).

as in printf("%'6d",1000000);

user102629
  • 31
  • 1
2

Cleaner C code

// write integer value in ASCII into buf of size bufSize, inserting commas at tousands
// character string in buf is terminated by 0.
// return length of character string or bufSize+1 if buf is too small.
size_t int2str( char *buf, size_t bufSize, int val )
{
    char *p;
    size_t len, neg;

    // handle easy case of value 0 first
    if( val == 0 )
    {
         a[0] = '0';
         a[1] = '\0';
         return 1;
    }


    // extract sign of value and set val to absolute value
    if( val < 0 )
    {
        val = -val;
        neg = 1;
    }
    else
        neg = 0;

    // initialize encoding
    p = buf + bufSize;
    *--p = '\0';
    len = 1;

    // while the buffer is not yet full
    while( len < bufSize )
    {
         // put front next digit
         *--p = '0' + val % 10;
         val /= 10;
         ++len;

         // if the value has become 0 we are done
         if( val == 0 )
             break;

         // increment length and if it's a multiple of 3 put front a comma
         if( (len % 3) == 0 )
             *--p = ',';
   }

   // if buffer is too small return bufSize +1 
   if( len == bufSize && (val > 0 || neg == 1) )
       return bufSize + 1;

   // add negative sign if required
   if( neg == 1 )
   {
       *--p = '-';
       ++len;
   }

   // move string to front of buffer if required
   if( p != buf )
       while( *buf++ = *p++ );

   // return encoded string length not including \0
   return len-1;
}
chmike
  • 20,922
  • 21
  • 83
  • 106
1

I did this for an iPhone game recently. I was using the built-in LCD font, which is a monospaced font. I formatted the numbers, ignoring the commas, then stuck the commas in afterward. (The way calculators do it, where the comma is not considered a character.)

Check out the screenshots at RetroJuJu. Sorry--they aren't full-sized screenshots so you'll have to squint!

Nosredna
  • 83,000
  • 15
  • 95
  • 122
0

Hope that helps you (it's in C) :

char* intToFormat(int a)
{
    int nb = 0;
    int i = 1;
    char* res;

    res = (char*)malloc(12*sizeof(char));
    // Should be enough to get you in the billions. Get it higher if you need
    // to use bigger numbers.

    while(a > 0)
    {
        if( nb > 3 && nb%3 == 0)
            res[nb++] = ',';

        // Get the code for the '0' char and add it the position of the
        // number to add (ex: '0' + 5 = '5')
        res[nb] = '0' + a%10;

        nb++;
        a /= 10;
    }

    reverse(&res);
    return res;
}

There might be a few errors I didn't see (I'm blind when it comes to this...) It's like an enhanced iToA so maybe it's not the best solution.

0

Use recursion, Luke:

#include <stdio.h>
#include <stdlib.h>

static int sprint64u( char* buffer, unsigned __int64 x) {
  unsigned __int64 quot = x / 1000;
  int chars_written;
  if ( quot != 0) {
    chars_written = sprint64u( buffer, quot);
    chars_written += sprintf( buffer + chars_written, ".%03u", ( unsigned int)( x % 1000));
  }
  else {
    chars_written = sprintf( buffer, "%u", ( unsigned int)( x % 1000));
  }
  return chars_written;
}
int main( void) {
  char buffer[ 32];
  sprint64u( buffer, 0x100000000ULL);
  puts( buffer);
  return EXIT_SUCCESS;
}
dmityugov
  • 4,390
  • 23
  • 18