Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Based on Boaz Stuller's answer, I logged a bug to Apple for this issue. Until that is resolved, here are the workarounds I've decided upon as being the best approach to take. These workarounds simply rely upon rounding the decimal number to the appropriate precision, which is a simple approach that can supplement your existing code (rather than switching from formatters to scanners).</p> <p><strong>General Numbers</strong></p> <p>Essentially, I'm just rounding the number based on rules that make sense for my situation. So, YMMV depending on the precision you support.</p> <pre><code>NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; [formatter setFormatterBehavior:NSNumberFormatterBehavior10_4]; [formatter setGeneratesDecimalNumbers:TRUE]; NSString *s = @"0.07"; // Create your desired rounding behavior that is appropriate for your situation NSDecimalNumberHandler *roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:2 raiseOnExactness:FALSE raiseOnOverflow:TRUE raiseOnUnderflow:TRUE raiseOnDivideByZero:TRUE]; NSDecimalNumber *decimalNumber = [formatter numberFromString:s]; NSDecimalNumber *roundedDecimalNumber = [decimalNumber decimalNumberByRoundingAccordingToBehavior:roundingBehavior]; NSLog([decimalNumber stringValue]); // prints 0.07000000000000001 NSLog([roundedDecimalNumber stringValue]); // prints 0.07 </code></pre> <p><strong>Currencies</strong></p> <p>Handling currencies (which is the actual problem I'm trying to solve) is just a slight variation on handling general numbers. The key is that the scale of the rounding behavior is determined by the maximum fractional digits used by the locale's currency.</p> <pre><code>NSNumberFormatter *currencyFormatter = [[NSNumberFormatter alloc] init]; [currencyFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4]; [currencyFormatter setGeneratesDecimalNumbers:TRUE]; [currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; // Here is the key: use the maximum fractional digits of the currency as the scale int currencyScale = [currencyFormatter maximumFractionDigits]; NSDecimalNumberHandler *roundingBehavior = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundPlain scale:currencyScale raiseOnExactness:FALSE raiseOnOverflow:TRUE raiseOnUnderflow:TRUE raiseOnDivideByZero:TRUE]; // image s is some locale specific currency string (eg, $0.07 or €0.07) NSDecimalNumber *decimalNumber = (NSDecimalNumber*)[currencyFormatter numberFromString:s]; NSDecimalNumber *roundedDecimalNumber = [decimalNumber decimalNumberByRoundingAccordingToBehavior:roundingBehavior]; NSLog([decimalNumber stringValue]); // prints 0.07000000000000001 NSLog([roundedDecimalNumber stringValue]); // prints 0.07 </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload