Got a big NSDecimal with high precision. Like this:

NSString *decStr = @"999999999999.999999999999";
NSDecimal dec;
NSScanner *scanner = [[NSScanner alloc] initWithString:decStr];
[scanner scanDecimal:&dec];

NSDecimalNumber *decNum = [[NSDecimalNumber alloc] initWithDecimal:*dec];

I can easily get a string representation of my NSDecimal with this:

NSString *output = [decNum stringValue];

Or

NSString *output = [decNum descriptionWithLocale:nil];

But it's never formatted correctly for output on screen:

output = 999999999999.999999999999

I want it to have group separation like 999,999,999,999.999999999999

So I tried a NSNumberFormatter:

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setAllowsFloats:YES];
[formatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[formatter setNumberStyle:kCFNumberFormatterDecimalStyle];

NSString *output = [formatter stringFromNumber:resultDecNum];

It ends up with this:

output = 1,000,000,000,000

Is there a way to get a big high precision NSDecimal formatted correctly based on users locale without losing precision?

有帮助吗?

解决方案

As you already noticed, NSNumberFormatter converts to float. Sadly there's only descriptionWithLocale as an alternative, which doesn't provide a way change the behaviour you want. The best way should be to write you own formatter, Apple even provides a guide for that:

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/DataFormatting/DataFormatting.html

I would take the descriptionWithLocale as a starting point and look for the separator. Then add comas every 3 digits before it.

Edit:

Another idea would be to split the string in the integer part and the stuff behind the separator, then format the integer part using the formatter and combine it with the rest after that.

// Get the number from the substring before the seperator 
NSString *output = [number descriptionWithLocale:nil];
NSNumber *integerPartOnly = [NSNumber numberWithInt:[output intValue]];

// Format with decimal separators
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[formatter setNumberStyle:kCFNumberFormatterDecimalStyle];

NSString *result = [formatter stringFromNumber:integerPartOnly]

// Get the original stuff from behind the separator
NSArray* components = [output componentsSeparatedByString:@"."];
NSString *stuffBehindDot = ([components count] == 2) ? [components objectAtIndex: 1] : @"";

// Combine the 2 parts
NSString *result = [result stringByAppendingString:stuffBehindDot];
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top