Biggs
Biggs

Reputation: 267

Rounding down a float to nearest 0.5 in Objective C / Cocoa Touch

I want to round a floating point number down such that I get that will be anywhere between 0.5 and 7 (with any number of decimals) while rounding anything below 0.5 up to 0.5.

For example,

0.1, 0.11442, 0.46 would all be 0.5.
1.1, 1.43, 1.35 would all be 1.
1.56, 1.6, 1.8 would all be 1.5.

Anything over 5 will be rounded down to 5.

The final data set I want is 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5.

I don't know any functions that round down for Objective C, without it being to whole numbers.

Upvotes: 5

Views: 5009

Answers (4)

dgrat
dgrat

Reputation: 2244

Well I noticed that determining the sign by dividing (as shown here) is bullshit because of floating point algebra. Also it is slow on many systems.

float round_half_f(float val) {
  short sign = (short)(val / fabs(val) );
  return floorf(fabs(val)*2.f) / 2.f * sign;
}

Do this:

float round_half_f(float val) {
  short sign = val < 0 ? -1 : 1;
  return floorf(fabs(val)*2.f) / 2.f * sign;
}

Upvotes: 0

mic
mic

Reputation: 11

first comment was good, but it skips zeros and negative values.. my 5 cents:

float roundToHalf (float val)
{
    if (val==0) return 0;
    int sign = fabs(val)/val;
    return sign * (fabs(val) < 0.5f ? 0.5f : floorf(fabs(val)) * 2 / 2);

}

Upvotes: 0

DrummerB
DrummerB

Reputation: 40211

floor() will round down floating point numbers to the next integer. If you first multiply by 2, round down, then divide by two, you will get the desired result.

float rounded = value < 0.5f ? 0.5f : floorf(value * 2) / 2;

Upvotes: 24

Hot Licks
Hot Licks

Reputation: 47729

To "round to nearest" interval, add half the interval and truncate to an interval boundary.

For rounding to nearest int that's (int) (value + 0.5) but it's a hair trickier with 0.5 boundaries -- the adding half the interval is easy, but the truncate to an 0.5 boundary isn't.

So the most practical approach is to double the number, round to an int boundary, then divide by 2.

Another way to do it is to separate the integer and fraction parts (fraction = value - (int) value;) and then use a simple "if ladder" to format the fraction part separately. (Beware -- negative numbers can be a hair tricky.) This might be a better choice if you need to round to some irregular set of boundaries.

Upvotes: 0

Related Questions