/* * opt_int_div.h * * "Optimized integer division": A header-only library * * NOTE: This code will work only on a computer that uses bits. * * Author: Intel A80486DX2-66 * License: Unlicense */ #ifndef _OPT_INT_DIV_H #define _OPT_INT_DIV_H #include #include // helper functions #define INT_BIN_DIV(a, b) ((a) >> (uintmax_t) log2l((b))) /* NOTE: log2l may slow things down */ #define INT_DIV_NEG_RESULT_SIGN(a, b) \ /* the sign is negative only if one of the numbers is negative */ \ (((a) < 0) != ((b) < 0)) /* 1 if sign is negative else 0 */ #define INT_ABS(x) ((x) < 0 ? -(x) : (x)) #define OPT_INT_DIV_TEST(b) \ /* check if b is a power of 2 */ \ /* */ \ /* condition: ( X & (X - 1) ) == 0 */ \ ((b) & ((b) - 1)) == 0 // the main macro #define OPT_INT_DIV(a, b) \ ( /* beginning */ \ /* check for equality of abs(a) and abs(b) */ \ INT_ABS((a)) == INT_ABS((b)) ? \ /* the result is +/-1 */ \ (INT_DIV_NEG_RESULT_SIGN(a, b) ? -1 : 1) : ( \ \ /* check if abs(a) < abs(b) */ \ INT_ABS((a)) < INT_ABS((b)) ? \ /* if abs(a) < abs(b), then the result is less than 1 (i.e., 0) */\ 0 : ( \ \ OPT_INT_DIV_TEST((b)) ? \ (INT_DIV_NEG_RESULT_SIGN(a, b) ? \ -INT_BIN_DIV(INT_ABS((a)), INT_ABS((b))) \ : \ INT_BIN_DIV(INT_ABS((a)), INT_ABS((b)))) \ : \ ((a) / (b)) )) \ ) /* end */ #endif /* _OPT_INT_DIV_H */