72

If I have a number int aNum = 2000000 how do I format this so that I can display it as the NSString 2,000,000?

Sebastian
  • 7,670
  • 5
  • 38
  • 50
RexOnRoids
  • 14,002
  • 33
  • 96
  • 136

9 Answers9

149

Use NSNumberFormatter.

Specifically:

NSNumberFormatter *formatter = [NSNumberFormatter new];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle]; // this line is important!

NSString *formatted = [formatter stringFromNumber:[NSNumber numberWithInteger:2000000]];

[formatter release];

By default NSNumberFormatter uses the current locale so the grouping separators are set to their correct values by default. The key thing is to remember to set a number style.

Girish
  • 4,692
  • 4
  • 35
  • 55
Nik
  • 5,801
  • 2
  • 31
  • 23
  • yes I had similar problem it wouldnt parse "200,000", even if I had set the locale to English UK, until I had set the style to NSNumberFormatterDecimalStyle. Think it would only understand the string "200000" – brian.clear Dec 04 '12 at 09:20
  • 2
    @MCKapur why do you say new is old school? It does not make sense typing more to do the same, isn't it? – Julio Bailon Aug 20 '14 at 13:27
  • 1
    @JulioBailon WOW this was like 2 years ago. Honestly don't remember why I said +new was old school. It isn't. I do however prefer +alloc-init for consistency, +new always felt like an unnecessary shortcut, and +alloc-init helped me keep good code practice. – MCKapur Aug 20 '14 at 14:44
  • What if I want both commas and the decimal places? – GeneCode Aug 26 '16 at 11:17
80

Don't do your own number formatting. You will almost certainly not get all the edge cases right or correctly handle all possible locales. Use the NSNumberFormatter for formatting numeric data to a localized string representation.

You would use the NSNumberFormatter instance method -setGroupingSeparator: to set the grouping separator to @"," (or better yet [[NSLocale currentLocale] objectForKey:NSLocaleGroupingSeparator]; thanks @ntesler) and -setGroupingSize: to put a grouping separator every 3 digits.

Barry Wark
  • 107,306
  • 24
  • 181
  • 206
34

There's a static method on NSNumberFormatter that does just what you need:

int aNum = 2000000;
NSString *display = [NSNumberFormatter localizedStringFromNumber:@(aNum)
                                                     numberStyle:NSNumberFormatterDecimalStyle];

This way is a little more succinct than creating a new NSNumberFormatter if you don't need to do any additional configuration of the formatter.

Phil Calvin
  • 5,077
  • 2
  • 41
  • 35
18

Even easier:

NSNumber *someNumber = @(1234567890);
NSString *modelNumberString = [NSString localizedStringWithFormat:@"%@", someNumber];
NSLog(@"Number with commas: %@", modelNumberString);

coworker just taught me this today. #amazing

yujean
  • 795
  • 8
  • 14
16

Think some as i will get this post looking for sample. So if you are working with number make attention on next params:

setNumberStyle:NSNumberFormatterCurrencyStyle // if you are working with currency

It could be also

setNumberStyle:NSNumberFormatterDecimalStyle

All code is For ARC.

If you are working with Integer and need to get result such as 200,000

int value = 200000;
NSNumberFormatter * formatter = [NSNumberFormatter new];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSString * newString =  [formatter stringFromNumber:[NSNumber numberWithInteger:value]];

If you are working with Float and need to get result such as 200,000.00

float value = 200000;
NSNumberFormatter * formatter = [NSNumberFormatter new];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
[formatter setMaximumFractionDigits:2]; // Set this if you need 2 digits
NSString * newString =  [formatter stringFromNumber:[NSNumber numberWithFloat:value]];

EDIT

To have ability to use different digital separators use NSLocale. Add to code where NSLocale is specified on Locale Identifier:

[formatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"de_DE"]];

or use current local:

[formatter setLocale:[NSLocale currentLocale]];
Nazir
  • 1,945
  • 24
  • 27
1

Swift version

let formatter = NSNumberFormatter()
formatter.numberStyle = .DecimalStyle
formatter.maximumFractionDigits = decimalPlaces
let result = formatter.stringFromNumber(NSNumber(double: 8.0))

By http://ios.eezytutorials.com

Raj iOS
  • 1,047
  • 1
  • 9
  • 20
0

An easy solution could be this. My answer is almost same like @Nazir's answer but with a small trick.

double current_balance = 2000000.00;

NSNumberFormatter * formatter = [NSNumberFormatter new];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
//[formatter setNumberStyle:NSNumberFormatterCurrencyStyle];  //if you want for currency with $ sign
[formatter setMinimumFractionDigits:2]; // Set this if you need 2 digits
[formatter setMaximumFractionDigits:2]; // Set this if you need 2 digits
NSString * currency_format =  [NSString stringWithFormat:@"%@", [formatter stringFromNumber:[NSNumber numberWithDouble:current_balance]]];
Julfikar
  • 1,353
  • 2
  • 18
  • 35
0

For Swift 4.0

let formatter = NumberFormatter()

formatter.numberStyle = .decimal

formatter.minimumFractionDigits = 2

formatter.maximumFractionDigits = 2

let result = formatter.string(from: NSNumber(value: 123456))
Sandip Patel - SM
  • 3,346
  • 29
  • 27
0

For those who need to do it with strings of numbers and not just integers (I.e. Big Numbers) I made the following macro:

#define addCommas(__string) (\
(^NSString *(void){\
NSString *__numberString = __string;\
NSString *__integerPortion = __numberString;\
NSString *__decimalPortion = @"";\
if ([__string containsString:@"."]) {\
__integerPortion = [__numberString componentsSeparatedByString:@"."][0];\
__decimalPortion = st(@".%@", [__numberString componentsSeparatedByString:@"."][1]);\
}\
int __i = (int)__integerPortion.length-3;\
while (__i > 0) {\
__integerPortion = st(@"%@,%@", substringInRange(__integerPortion, 0, __i), substringInRange(__integerPortion, __i, (int)__integerPortion.length));\
__i -= 3;\
}\
__numberString = st(@"%@%@", __integerPortion, __decimalPortion);\
return __numberString;\
})()\
)
Albert Renshaw
  • 17,282
  • 18
  • 107
  • 195