2

I've got an NSNumberFormatter set up to format using significant digits, so it should only show as many decimal digits as are necessary to correctly display the value.

When it is used to format 7.0 it works exactly as expected and produces @"7", but when it is used to format 0.0 the formatter produces @"0.0" instead of @"0" as would be expected.

NSNumberFormatter *doubleValF = [[NSNumberFormatter alloc] init];
[doubleValF setNumberStyle:NSNumberFormatterDecimalStyle];
[doubleValF setRoundingMode:NSNumberFormatterRoundHalfUp];

doubleValF.maximumFractionDigits = 9;
doubleValF.minimumFractionDigits = 0;
doubleValF.minimumSignificantDigits = 0;
doubleValF.maximumSignificantDigits = 30;
[doubleValF setUsesSignificantDigits:YES];

double value1 = 0.0;
NSString *value1String = [doubleValF stringFromNumber:[NSNumber numberWithDouble:value1]];

double value2 = 7.0;
NSString *value2String = [doubleValF stringFromNumber:[NSNumber numberWithDouble:value2]];

NSLog(@"value1=%@", value1String);
NSLog(@"value2=%@", value2String);

When I run this code, I get the following output:

2012-12-15 15:57:03.425 StackOverflowTests[41701:11303] value1=0.0
2012-12-15 15:57:03.426 StackOverflowTests[41701:11303] value2=7
Kenny Wyland
  • 20,844
  • 26
  • 117
  • 229

3 Answers3

1

Following David's LaMacchia's post, just check for a zero value and set the sig fig mode:

if(fabs(value) < 1e-6) {
    self.numberLabelFormatter.usesSignificantDigits = NO;
}
else {
    self.numberLabelFormatter.usesSignificantDigits = YES;
}
self.numberLabel.text = [self.numberLabelFormatter stringFromNumber:[NSNumber numberWithDouble:value]];

This may not be the correct method, but it works for me.

danomatika
  • 101
  • 1
  • 4
  • 1
    Whenever you see a floating point value and == together, you should have a siren go off in your head, because you should not trust that the variable is EXACTLY 0.0 through the entire value. – Kenny Wyland Mar 08 '13 at 07:21
  • Sure. But I don't need much accuracy and it's working fine. In this case, I'm not worried. – danomatika Mar 08 '13 at 21:46
  • It's not the accuracy of the number itself when it comes to calculations, I'm referring to whether or not the if() statement will evaluate to true. You could have a number which 0.00000001 which you think should be 0, but it will evaluate to false when compared to 0.0 and your else clause will fire instead of if. – Kenny Wyland Mar 08 '13 at 22:53
  • Your code will most likely work every time you test it, but it's possible for it to fail arbitrarily. You should consider changing your if() statement to something like `if (fabs(value) < 1e-6)` which will evaluate to true as long as value is between -0.000001 and 0.000001. – Kenny Wyland Mar 08 '13 at 22:56
  • @KennyWyland Good advice. The exact value to test against is FLT_EPSILON for a float. – Echelon Jan 29 '15 at 16:13
0

The issue is related to your having set usesSignificantDigits to YES. I believe the trailing digit, in 0.0, is considered significant.

There's a good discussion of a related issue here: https://stackoverflow.com/a/13110633/1435955

Community
  • 1
  • 1
  • I read the linked article and I don't believe it addresses my specific problem, which is that the .0 is included only if the value is 0. In the case of 7.0, it is not included. – Kenny Wyland Dec 16 '12 at 05:03
0

Try to set zeroSymbol property of number formatter to @"0".

doubleValF.zeroSymbol = @"0"; 
ninjaproger
  • 2,024
  • 1
  • 27
  • 26