// ufn_round.h: More feature-rich rounding functions. // Under MIT-License. Copyright by Eric-Paul Ickhorn (epickh). #ifndef UFN_ROUND_H #define UFN_ROUND_H #include /// @brief Rounds a value down to the last multiple of a stepping. /// @param value Value to round down (floor). /// @param stepping Stepping to round the value to. /// @return Rounded value int64_t ufn_floor_i64(int64_t value, int64_t stepping); /// @brief Rounds a value up to the next multiple of a stepping. /// @param value Value to round up (ceil). /// @param stepping Stepping to round the value to. /// @return Rounded value int64_t ufn_ceil_i64(int64_t value, int64_t stepping); /// @brief Rounds down (Floors) a value to the last power of 2. /// @param value Value to find the nearest lower power of 2 of. /// @return Power of 2 which is nearest lower one to 'value'. uint64_t ufn_floor_pow2(uint64_t value); /// @brief Rounds up (Ceils) a value to the next power of 2. /// @note Internally, this uses the 'ufn_floor_pow2'-function but multiplies /// its result by two to get the next higher power. /// @param value Value to round up to the next power of 2. /// @return Power of 2 which is the nearest higher one from 'value'. uint64_t ufn_ceil_pow2(uint64_t value); #ifdef UFN_IMPLEMENTATION int64_t ufn_floor_i64(int64_t value, int64_t stepping) { return value - (value % stepping); } int64_t ufn_ceil_i64(int64_t value, int64_t stepping) { return ufn_floor_i64(value, stepping) + stepping; } uint64_t ufn_floor_pow2(uint64_t value) { // Find highest-priority bit which is 1 int8_t bit_index = 63; while(bit_index >= 0) { if(value & (1 << bit_index)) { break; } --bit_index; } return 1 << bit_index; } uint64_t ufn_ceil_pow2(uint64_t value) { uint64_t floored = ufn_floor_pow2(value); if(value == floored) { return value; } return floored * 2; } #endif // UFN_IMPLEMENTATION #endif // UFN_ROUND_H