I wanted a general solution, regardless of the number formatting configuration.
I used the category to add functions to NSNumberFormater;
@interface NSNumberFormatter (PreventNegativeZero) - (NSString *)stringFromNumberWithoutNegativeZero:(NSNumber *)number; @end
With implementation:
@implementation NSNumberFormatter (PreventNegativeZero) - (NSString *)stringFromNumberWithoutNegativeZero:(NSNumber *)number { NSString *const string = [self stringFromNumber: number]; NSString *const negZeroString = [self stringFromNumber: [NSNumber numberWithFloat: -0.0f]]; if([string isEqualToString: negZeroString]) { NSString *const posZeroString = [self stringFromNumber: [NSNumber numberWithFloat: 0.0]]; return posZeroString; } return string; } @end
How it works
Function is to set the formatting number, how it will format -0.0f (i.e. floating point minus zero) as NSString so that we can detect this and take corrective measures.
What for? Depending on the formatting configuration, -0.0f can be formatted as: @"-0" , @"-0.0" , @"-000" , @"-0ΒΊC" , @"Β£-0.00" , @"----0.0" , @"(0.0)" , @"π‘π.βͺιΆ" really, almost everything. So, weβll ask you to format how it will format -0.0f using the line: NSString *const negZeroString = [self stringFromNumber: [NSNumber numberWithFloat: -0.0f]];
Armed with the -0.0f unwanted line, when an arbitrary input number is formatted, you can test it to see if it -0.0f unwanted line.
The second important feature is that the number of formatter is also proposed to put a replacement positive zero string. This is necessary so that its formatting is still respected. This is done using the string: [self stringFromNumber: [NSNumber numberWithFloat: 0.0]]
Optimization that doesn't work
It is mysterious to perform a numerical test on whether the input number will be formatted as a string -0.0f , but this is extremely nontrivial (i.e., generally impossible at all). This is because the set of numbers that will be formatted in the -0.0f line depends on the formatting configuration. If, if rounding is rounded to the nearest million, then -5,000f as input will be formatted as the string -0.0f .
Implementation error to avoid
Entering these formats into the -0.0f line reveals a positive zero equivalent output line using [self stringFromNumber: [NSNumber numberWithFloat: 0.0]] . Please note that in particular:
- The code formats the floating literal
0.0f and returns it. - The code does not use the negation of input.
-0.1f input -0.1f will result in 0.1f formatting. Depending on the formatting behavior, this can be rounded and lead to @"1,000" , which you don't need.
Final note
For what it's worth, the approach / template / algorithm used here will translate into other languages ββand various string formatting APIs.