3

I have an issue with rounding the result of a calculation to two decimal places.

It is a financial calculation and when the result involves half a penny I would expect the number to be rounded up but it is in fact being rounded down.

To replicate the issue:

float raw = 16.695;
NSLog(@"All DP: %f",raw);
NSLog(@"2 DP: %.2f",raw);

Returns:

All DP: 16.695000
2 DP: 16.69

Whereas I would expect to see:

All DP: 16.695000
2 DP: 16.70

Can anyone advise if this is by design or if (most likely) I am missing something and if there is anything I can do to get around it. It is vital that it rounds up in this scenario.

Thanks in advance, Oli

mskfisher
  • 3,028
  • 3
  • 31
  • 47
faroligo
  • 585
  • 2
  • 12

4 Answers4

8

Don't use floats for financial calculations!

There are values that floats cannot represent exactly. 16.695 is one of them. When you try to store that value in a float, you actually get the closest representable value. When you perform a series of operations on a float, you can lose precision, and then you lose accuracy. This leads to losing money.

Use an actual currency type, use NSDecimalNumber, or do all your calculations with ints that count the smallest unit you care about (i.e., 1050 is $10.50 in whole cents, or $1.050 if you want fractions of pennies).

Community
  • 1
  • 1
jscs
  • 62,161
  • 12
  • 145
  • 186
  • I believe this style of post is know as the ["bbum"](http://stackoverflow.com/questions/3730804/how-many-times-do-i-release-an-allocated-or-retained-object/3730835#3730835), and I've heard they're considering adding it to SO as a formatting tag: ``. – jscs Jun 13 '11 at 18:21
3

As far as I am aware the NSLog() function only takes formatting arguments and makes no attempt to round.

You may be use to using a printf() style function that does support rounding.

I suggest using one of the many functions in math.h to round your value before output and only rely on NSLog() for formatting.

Richard Stelling
  • 25,151
  • 27
  • 105
  • 186
  • Thanks but the NSLog is just for this example - in the real application I am using [NSString stringWithFormat:@"%.2f,xxx]. I was led to believe this did rounding in the same way printf() did. What function are you suggesting? – faroligo Jun 13 '11 at 17:23
0

After seeing the comments

Use the C standard function family round(). roundf() for float, round() for double, and roundl() for long double. You can then cast the result to the integer type of your choice

Aravindhan
  • 15,380
  • 10
  • 51
  • 71
-1

you could try this:

 - (void)testNSlogMethod {

    float value = 16.695; //--16.70
    value = value *100;

    int mulitpler = round(value);

    NSLog(@"%.2f",mulitpler/100.0f);
}
Sergey Glotov
  • 19,479
  • 11
  • 78
  • 93