I want to implement my own ceil() in C. Searched through the libraries for source code & found here, but it seems pretty difficult to understand. I want clean & elegant code.
I also searched on SO, found some answer here. None of the answer seems to be correct. One of the answer is:
#define CEILING_POS(X) ((X-(int)(X)) > 0 ? (int)(X+1) : (int)(X))
#define CEILING_NEG(X) ((X-(int)(X)) < 0 ? (int)(X-1) : (int)(X))
#define CEILING(X) ( ((X) > 0) ? CEILING_POS(X) : CEILING_NEG(X) )
AFAIK, the return type of the ceil() is not int. Will macro be type-safe here?
Further, will the above implementation work for negative numbers?
What will be the best way to implement it?
Can you provide the clean code?
The macro you quoted definitely won’t work correctly for numbers that are greater than
INT_MAXbut which can still be represented exactly as a double.The only way to implement
ceil()correctly (assuming you can’t implement it using an equivalent assembly instruction) is to do bit-twiddling on the binary representation of the floating point number, as is done in thes_ceil.csource file behind your first link. Understanding how the code works requires an understanding of the floating point representation of the underlying platform — the representation is most probably going to be IEEE 754 — but there’s no way around this.Edit:
Some of the complexities in
s_ceil.cstem from the special cases it handles (NaNs, infinities) and the fact that it needs to do its work without being able to assume that a 64-bit integral type exists.The basic idea of all the bit-twiddling is to mask off the fractional bits of the mantissa and add 1 to it if the number is greater than zero… but there’s a bit of additional logic involved as well to make sure you do the right thing in all cases.
Here’s a illustrative version of
ceil()for floats that I cobbled together. Beware: This does not handle the special cases correctly and it is not tested extensively — so don’t actually use it. It does however serve to illustrate the principles involved in the bit-twiddling. I’ve tried to comment the routine extensively, but the comments do assume that you understand how floating point numbers are represented in IEEE 754 format.