Question

I was asking about round a number half up earlier today and got great help from @alk. In that post, my thinking was to round up 4.5 to 5 but round 4.4 down to 4. And the solution given by @alk was:

int round_number(float x)
{
 return x + 0.5;
}

and it works very elegantly!

In this post, I would like to discuss how to implement the ceil() function in C. Along the same line as the last solution given by @alk, I came up with the following:

int round_up(float y)
{
   return y + 0.99999999;
}

This works for all situations except when the the float number y has .00000001. I am wondering if there's any better way to do the same thing as ceil() in C.

No correct solution

OTHER TIPS

Unless you reliably know the epsilon of float (I'm not sure standard C provides that), I think you're stuck with return (y < 0 || y == (int)y) ? y : y + 1;

This fails for negative numbers.

int round_up(float y) {
 return y + 0.99999999;
}

But let's use that to our advantage. float to int conversion is a truncate toward 0.0. Thus negative numbers are doing a "round up" or "ceiling" function. When we have a positive float, convert to int noting this is a "floor" function. Adjust when y is not an integer.

(Assume y within INT_MIN ... INT_MAX.)

int ceil(float y) {
   if (y < 0) {
     return y;  // this does a ceiling function as y < 0.
   }
   int i = y; // this does a floor function as y >= 0.
   if (i != y) i++;
   return i;
 }

void ceil_test(float y) {
   printf("%f %d\n", y, ceil(y));
}

The first snippet works incorrectly for negative numbers. -3.5 will be come -3, not -4. To round values properly use

int round_number(float x)
{
    if (x >= 0)
        return x + 0.5f;
    else
        return x - 0.5f
}

Even that way it's still incorrect for 2 values. See Why does Math.round(0.49999999999999994) return 1?. Note that you need to use the f suffix to get the float literal, otherwise the operation will be done in double precision and then downcast back to float

For ceiling, adding 1 is enough

int ceiling(float x)
{
    if (x < 0 || (int)x == x)
        return x;
    else
        return x + 1.0f;
}

When x is an integer, e.g. x = 3.0 (or -3.0), it returns 3 (or -3). For x = 3.1 it returns 4, for x = -3.1 it returns -3

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top