Recently I tried to make a "clever" macro for float (32bit) division with rounding up to unsigned int (32bit):
#include "float.h"
#include "stdint.h"
#define DIV_ROUND_UP(x, y) (uint32_t)(((float)(x) / (float)(y)) + (float)(1.0f - FLT_EPSILON))
The FLT_EPSILON
was used, to add something less than 1, so DIV_ROUND_UP(10u, 1u) will result in 10u, not 11u.
I was very surprised when DIV_ROUND_UP(10u, 1u) actually returned 11u. I checked experimentally that I have to use 5 * FLT_EPSILON to get 10u, but I still don't understand why. I assumed that if I add something less than 1, it will be truncated during conversion to uint32_t. Could anyone explain why it is not truncated? And why 5 * FLT_EPSILON works?
EDIT: I end up with the following solution, which works for positive numbers:
#define DIV_ROUND_UP(x, y) (((float)(x) / (float)(y)) > (uint32_t)((float)(x) / (float)(y)) ? \
(uint32_t)((float)(x) / (float)(y)) + 1u : \
(uint32_t)((float)(x) / (float)(y)))