13

I've got a float value from an accelerometer which looks like this:

-3.04299553323

I'd like to get -3.04 for example. Is there an easy way for rounding that float value?

Edit:

Rounding numbers in Objective-C

Community
  • 1
  • 1
Thanks
  • 40,109
  • 71
  • 208
  • 322
  • possible duplicate of [Rounding numbers in Objective-C](http://stackoverflow.com/questions/752817/rounding-numbers-in-objective-c) – Sulthan Apr 21 '13 at 11:47
  • Floats cannot be rounded to a given number of decimal digits. They can be rounded only when converted to a string. – Sulthan Apr 21 '13 at 11:58

4 Answers4

42

I know this is old post but just in case someone else is looking for a quick Two step option.

float old = -3.04299553323;  
float new = [[NSString stringWithFormat:@"%.2f",old]floatValue];

Result = -3.04

The @"%.2f" will round to two decimal places. If you want three decimal places put @"%.3f" and so on.

Hope this helps!

FlippinFun
  • 1,124
  • 10
  • 9
  • I just made an edit to add the result just for clarity. – FlippinFun Dec 29 '13 at 02:43
  • 2
    This is *much* slower than and no better than `round (old * 100.0) / 100.0`; like the latter, it doesn't actually round to two decimal places, because you’re using floating point with a *binary* exponent (so decimal values cannot be accurately represented in all cases). – al45tair Aug 12 '14 at 16:39
  • tooo much overkill for such a trivial operation – Peter Lapisu Feb 17 '15 at 15:57
32

You should only ever do this while formatting a number for display to the end user, because there is no guarantee that

float rounded = roundf(orig * 100) / 100.0;

or similar will return an exact answer.

Indeed, in general, it won't. For instance consider

float f = 123456.3;
float r = roundf(f * 100) / 100.0;

printf("%.2f, %.10f\n", r, r);

which outputs

123456.30, 123456.2968750000

Oops!

Using double rather than float helps, but even so, if we change the code a little, you can see that it doesn't really solve the problem:

double f = 123456.3;
double r = round(f * 100) / 100.0;

printf("%.2f, %.20f\n", r, r);

Again, we get

123456.30, 123456.30000000000291038305

which shows quite clearly that it isn't exactly rounded.

Anyway, the moral of the story is that doing things like round(f * 100) / 100.0 only rounds approximately. It might be good enough in some cases, but you do need to keep in mind that the result is not really rounded.

If you want something better, you'll need to use decimal arithmetic instead. You can either do this by keeping your values as integers (e.g. for currency values, keep them in pence or cents instead of pounds or dollars), or by using one of the various decimal floating point packages you can find on Wikipedia's Decimal Floating Point page.

Alvaro
  • 1,188
  • 13
  • 21
al45tair
  • 4,405
  • 23
  • 30
  • Nice answer, thanks. I decided to go with fixed point representation – Rajavanya Subramaniyan Sep 19 '11 at 18:22
  • Hi, in the last paragraph, `NSDecimalNumber` should be mentioned. – Sulthan Apr 21 '13 at 12:00
  • What about 125456.355 ? it shoud give you 125456.35 instead of 125456.36 – Shamsudheen TK Apr 13 '16 at 11:36
  • @Ramshad Depends on the kind of rounding you’re using. If you’re using round-half-up or round-half-away-from-zero, 125456.36 is the correct result. But look, the point here is that floating point numbers are represented in *binary*, not decimal. If you need specific decimal rounding behaviour, you *need* to use decimal arithmetic — either fixed point (keeping values as integers multiplied by a power of 10), or decimal floating point (via various packages). – al45tair Apr 13 '16 at 11:40
  • I think this should work - NSNumberFormatter *formatterss = [[NSNumberFormatter alloc] init]; [formatterss setPositiveFormat:@"0.##"]; NSString* formattedSum = [formatterss stringFromNumber:@(125456.355)]; NSLog(@"%@",[NSString stringWithFormat:@"%.2f",[formattedSum floatValue]]); – Shamsudheen TK Apr 13 '16 at 11:42
  • @Ramshad Then you are wrong. `[formattedSum floatValue]` will not return an exact answer, because IEEE floating point uses a base-2 exponent. You would need a base-10 exponent to get accurate decimal rounding. – al45tair Apr 13 '16 at 11:44
  • Yeah, You are correct. How to fix this. My code is working with 125456.355 (this is rounded as 125456.36), However, not working with 48.425 (this is rounded as 48.42). Any suggestions to modufy the code? – Shamsudheen TK Apr 13 '16 at 12:13
  • @Ramshad I’ve already answered this question in my answer, above. Either use a decimal mathematics package (`NSDecimalNumber` might be an option as you’re using Foundation), or calculate using integers and make your display routines put the point in the right place. – al45tair Apr 13 '16 at 14:21
1

I just post my answer to this question cause it was the only way for me to get this working quickly as I merged two of the given answers to display a rounded float value to the user in an iPad app:

NSString *roundedAmount = [NSString stringWithFormat:@"%.2f", round ((floatValue / 1024) * 100.0) / 100.0];
Torsten Barthel
  • 3,059
  • 1
  • 26
  • 22
  • If this is just for display, `[NSString stringWithFormat:@"%.2f", floatValue/1024]` should work, without the pointless call to `round`. – al45tair Jan 21 '16 at 12:05
1

Multiply it by 100, (round up/down to nearest integer if necessary), take the integer portion, then divide by 100 again

Applies for any number decimals places, multiply/divide by 10^(no. of decimals).

  • See my comment above, which also applies to this "solution". – al45tair Jul 13 '11 at 15:35
  • @alastair, so there is no way to do this? – Dan Rosenstark Oct 05 '11 at 13:36
  • As I said in my answer above, the _right_ way is either to represent your data as an integer (and add the decimal point yourself, as required), or to use a decimal arithmetic package. For many applications you _can_ get away with approximate rounding and careful use of `printf()` specifiers, but you need to appreciate that the numbers are not _really_ rounded, even though they might look that way. – al45tair Oct 10 '11 at 16:08