0

I am developing an app and want to round off values i.e if the output is 4.8 I want to display 4.8 while if the output is 4.0 , I want to display 4

Also, it would be great if I could precisely round values : as in if value is 4.34 then round to 4.3 while if its 4.37 then round it to 4.4

iDev
  • 2,163
  • 10
  • 39
  • 64
  • So you want to round to the nearest tenth? That'll get sticky, as floating-point numbers can't actually hold such values. Is this just for display? – Jonathan Grynspan Nov 05 '11 at 00:43
  • possible duplicate of [Rounding numbers in Objective-C](http://stackoverflow.com/questions/752817/rounding-numbers-in-objective-c). If this is just for display, just use formatters. Keep the display of a number separate from the actual number. – Abizern Nov 05 '11 at 00:43
  • Just code exactly what you want. What's the question? Are you having some kind of difficulty precisely specifying what you want? Or are you having trouble coding it? Or what? – David Schwartz Nov 05 '11 at 00:46
  • I am having a problem coding it.. I want don't want to round 1.4 but if its 4.0 then only 4 – iDev Nov 05 '11 at 00:49
  • 1
    So what have you tried to do so far? – Abizern Nov 05 '11 at 00:52
  • I dont understand how do I implement it – iDev Nov 05 '11 at 00:54
  • Can you manage the 1.43 → 1.4 truncation? If you can then you can manage the 4.0001 → 4.0 truncation. Then you just need to tailor the way you present the value based on whether the first decimal digit is `0` or not. – Abizern Nov 05 '11 at 01:00
  • how can I check that the 1st decimal digit is 0 or not? – iDev Nov 05 '11 at 01:02
  • @iDev - Go through the normal truncation procedure, turn the resulting float into an int, subtract this int from the truncated float. Now, think of what the result would be in the case where the truncated float is, say, 4.1. What would be the result if the truncated float is 4.0? Have I given you enough clues yet? – Abizern Nov 05 '11 at 01:07
  • I am not getting it, can you please explain it to me with a code sample – iDev Nov 05 '11 at 01:31
  • 1
    @iDev - I've given you a hint, and you have some answers below. Try writing your own code to solve this and we'll have a look at it. – Abizern Nov 05 '11 at 01:42
  • 1
    This is an old thread, but I just stumbled on it while looking for something else. I found it amusing that everyone missed the point of what the OP was trying to achieve: if the number is a whole number, he did not want to have a decimal point. – electrichead Jul 16 '12 at 21:51

4 Answers4

7

One way to round floating point values is to just add 0.5 and then truncate the value.

double valueToRound = GetTheValueFromSomewhere();
double roundedValue = (double)((int)(valueToRound + 0.5));

This will round 1.4 down to 1.0 and 1.5 up to 2.0 for example. To round to other decimal places as you mentioned, simply multiply the initial value by 10, or 100, etc. use the same sort of code, and then divide the result by the same number and you'll get the same result at whatever decimal place you want.

Here's an example for rounding at an arbitrary precision.

double valueToRound = GetTheValueFromSomewhere();
int decimalPrecisionAtWhichToRound = 0;
double scale = 10^decimalPrecisionAtWhichToRound;
double tmp = valueToRound * scale;
tmp = (double)((int)(tmp + 0.5));
double roundedValue = tmp / scale;

So, if decimalPrecisionAtWhichToRound is set to 0 as in the above it'll round to the nearest whole integer. 1.4 will round to 1.0. 1.5 will round to 2.0.

If you set decimalPrecisionAtWhichToRound to 1, it would round to the nearest tenth. 1.45 would round to 1.5 and 1.43 would round to 1.4.

Nerdtron
  • 1,486
  • 19
  • 32
  • I want to round 1.4 to 1.4 only and 1.0 to 1, Is that possible? – iDev Nov 05 '11 at 00:48
  • If you applied the code I posted, and multiplied by 10 first and then dividied by 10 afterwards, 1.4 would round to 1.4 and 1.0 would round to 1.0. Also, 1.44 would round to 1.4 and 1.46 would round to 1.5. So its the same thing, you're just pre-multiplying and post-dividing by 10 based on how far out you want the rounding to occur. – Nerdtron Nov 05 '11 at 00:59
  • But then I also want 1.0 to round to 1 in my app – iDev Nov 05 '11 at 01:01
  • How do I display it, I mean if I use %.f then it gives me 4.0, if I use %f then 4.000000 and %i the I lose the precision for 4.1 – iDev Nov 05 '11 at 01:32
  • When formatting you can use "%.*f" and then provide 2 arguments, the precision first, then the actual value. This lets you control to what precision the number is formatted. – Nerdtron Nov 05 '11 at 01:47
  • @DanielRHicks I've never used it with two *s. That's an interesting variation to keep in mind though. My use of it has always been just to control the # digits after the decimal point. – Nerdtron Nov 05 '11 at 15:31
  • Yeah, supposedly you can use the `*` any place a number would appear in the format. – Hot Licks Nov 05 '11 at 18:30
2
    float number=17.125;
NSNumberFormatter *format = [[NSNumberFormatter alloc]init];
[format setNumberStyle:NSNumberFormatterDecimalStyle];
[format setRoundingMode:NSNumberFormatterRoundHalfUp];
[format setMaximumFractionDigits:2];
NSString *temp = [format stringFromNumber:[NSNumber numberWithFloat:number]];
NSLog(@"%@",temp);
2

You need to first understand how to do rounding on paper, without someone showing you the code to do it. Write down some numbers and figure out how to round them.

To round to a specific decimal position you add half the value of that position and then truncate. Ie, 1.67 + 0.05 = 1.72 then truncate to 1.7.

But there are two tricky things in programming that aren't there when you do it on paper:

  1. Knowing how to truncate -- There are several ways to do it while programming, but they're non-trivial.
  2. Dealing with the fact that floating-point numbers are imprecise. Ie, there is no exact representation of, say, 1.7, but rather the two closest numbers are apt to be something like 1.69998 and 1.700001

For truncating the trick of multiplying the number by the appropriate power of 10 to produce an integer works pretty well. Eg, (1.67 + 0.05) * 10 = 17.2, then convert to int to get 17, then convert back to float and divide by 10 to get 1.7 (more or less). Or (if you're printing or displaying the value) just format the integer number with the decimal point inserted. (By formatting the integer value you don't have to deal with the problem of imprecise floating point representations.)

If you want to suppress trailing zeros it gets a bit trickier and you probably have to actually write some code -- format the number, then scan backwards and take off any trailing zeros up to the decimal point. (And take the decimal point too, if you wish.)

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
  • I still think subtracting the integer value and then comparing the result to 0 (within the small error for float arithmetic) is faster for finding the trailing zero – Abizern Nov 05 '11 at 01:41
1
double myNumber = 7.99;
NSString *formattedNumber = [NSString stringWithFormat:@"%.*f",
    fmod(round(myNumber * 10), 10) ? 1 : 0, myNumber];
rob mayoff
  • 375,296
  • 67
  • 796
  • 848