2

If I use the following code:

- (NSString*)formatToCurrency:(float)inFloat {
  NSNumberFormatter *currencyFormatter = [[[NSNumberFormatter alloc] init] autorelease];
  [currencyFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
  [currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
  [currencyFormatter setMaximumFractionDigits:2];
  [currencyFormatter setLocale:[NSLocale currentLocale]];

  NSNumber *x = [NSNumber numberWithFloat:inFloat];
  return [NSString stringWithFormat:@"  %@", [currencyFormatter stringFromNumber:x]];
}

then pass in 203500 when calling the code, I receive the output: $203,500.02.

I'd love to hear some thoughts on what is happening.

Thanks,

Matt

EDIT: XCode was reporting 203500 when I viewed it with the debugger, but when I converted the float to an NSString, it would also show 203500.018. Meaning the problem was in the float and not in the NSNumberFormatter.

deleted_user
  • 3,817
  • 1
  • 18
  • 27
Matt Hansen
  • 73
  • 1
  • 5

2 Answers2

6

You are creating the NSNumber with a float. Floats always can have a rounding error

What Every Computer Scientist Should Know About Floating-Point Arithmetic

You should familiarize yourself with NSDecimals and NSDecimalNumbers

Cocoa is my GF: Don't be lazy with NSDecimalNumber (like me)

Community
  • 1
  • 1
vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
  • 3
    +1 for `NSDecimal`, but if fractional amounts of cents are not allowed, a better solution would be to encode the dollar amount in cents instead, and use an integral value type to store it – yfrancis Nov 04 '12 at 21:47
  • Thanks. I completely blanked that. – Matt Hansen Nov 05 '12 at 04:43
0

Clearly I've lots to learn on this. But at the risk of getting dinged further, I'll report one thing that did help me.

I had this code:

self.myDollarFormat.roundingIncrement = [NSNumber numberWithFloat:roundingInc];
return [self.myDollarFormat stringFromNumber:[NSNumber numberWithFloat: dollars]];

And found 638198.2 with a roundingIncrement of 0.1 was yielding @"$638,198.21".

I changed my code to use double instead of float, and then I got the expected result.

self.myDollarFormat.roundingIncrement = [NSNumber numberWithDouble: roundingInc];
return [self.myDollarFormat stringFromNumber:[NSNumber numberWithDouble: dollars]];

I defer to those who know more, but I thought I'd at least mention this worked for me. Good luck.

jbbenni
  • 1,158
  • 12
  • 31