einpoklum
einpoklum

Reputation: 131996

Compile-time ceiling function, for literals, in C?

I have a C program which involves some floating-point literal that's defined by a macro. And - it just so happens that in a performance-critical part of the code, I need the ceiling of that floating-point number, as an integer (say, an int). Now, if it were an actual literal, then I would just manually take the ceiling and be done with it. But since it's a macro, I can't do that.

Naturally, ceilf(MY_DOUBLE_LITERAL) works, but - it's expensive. (int)(MY_DOUBLE_LITERAL) + 1 will also work... except if the literal is itself an integer, in which case it will be wrong.

So, is there some way - preprocessor macros are fine - to obtain the ceiling of MY_DOUBLE_LITERAL, or alternatively to determine whether it is an integer or not?

Notes:

Upvotes: 2

Views: 535

Answers (2)

einpoklum
einpoklum

Reputation: 131996

If your literal fits nicely within the int representation range, you will often be able to rely on compiler optimizations. clang and gcc, for example, will go as far as simply optimizing ceilf() away when it's provided a literal, so ceifl(MY_DOUBLE_LITERAL) will result in a literal being used and no time wasted at run-time.

If somehow that doesn't work with your compiler, you could use:

int poor_mans_ceil(double x)
{
    return (int) x + ( ((double)(int) x < x) ? 1 : 0);
}

which should be "easier" for a compiler to optimize. You can see this happening on GodBolt.


Having said that - Some compilers in more exotic setting might fail to optimize both ceil() and the function above. Example: NVIDIA's NVCC compiler for CUDA.

Upvotes: 3

Spyros K
Spyros K

Reputation: 2605

A solution could be to statically store the rounded float macro literal in a const variable outside the critical part of the code and use the precomputed int const value in the critical part. This will work as long as the float returned by the macro is always the same value.

Upvotes: 0

Related Questions