views:

161

answers:

2

I have a NSNumberFormatter instance like this:

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

Then I provide a value like this and print it:

NSNumber *number = [NSNumber numberWithFloat:4932.79661];
NSLog(@"%@", [formatter stringFromNumber:number]);

What I get is:

4,932.796

there are missing 2 digits. Now the strange thing is, if I make the number much bigger, i.e. 49328324.79661, I would get only 2 fractional digits. Any idea what might be wrong with the formatter? Must I explicitely tell it to use a specific precision?

+1  A: 

I'm not an expert here but I believe floats are limited to 7 significant digits. You have 9. Someone can correct me if I'm wrong. You could use a double or better still an NSDecimalNumber and don't create it from a float but from one of the other initializers. Perhaps decimalNumberWithString or decimalNumberWithDecimal.

Meltemi
thanks, that sounds good. Well actually the value I have is some kind of calculated value. I could switch all calculations to use double. Would that help?
HelloMoon
+1  A: 

Try setting:

[formatter setMaximumFractionDigits:20];

remember that floating point numbers might not be 100% accurately representable internally. So, for example, the output from your program above would be:

4,932.79638671875
rein
indeed that seems to help out, but it forces to show 20 of them which is not always correct. I wonder how calculator-developers and other guys do that, showing nice formated floating point numbers with only as much precision as needed individually to what wants to be displayed.
HelloMoon
Calculators usually have a fixed number of characters they can display. Surely they would just set that number to the number of characters they could possibly display and then, once the value is in a string, just trim off the end.
rein