/* * opt_int_div.h * * Author: Intel A80486DX2-66 * License: Creative Commons Zero 1.0 Universal */ #include #include // parameters #define OPT_INT_DIV_TEST_PRECISION 8 // constants #define OPT_INT_DIV_ROUNDING \ /* 10^OPT_INT_DIV_TEST_PRECISION */ \ powl(10.l, (long double) OPT_INT_DIV_TEST_PRECISION) \ // helper functions #define INT_BIN_DIV(a, b) ((a) >> (uintmax_t) log2l((b))) #define INT_DIV_NEG_RESULT_SIGN(a, b) (((a) < 0) ^ ((b) < 0)) #define INT_ABS(x) ((x) < 0 ? -(x) : (x)) // the main macro #define OPT_INT_DIV(a, b) \ ( /* beginning */ \ /* check for equality of a and b */ \ INT_ABS((a)) == INT_ABS((b)) ? \ /* if only one of the numbers is negative, the result is -1, */ \ /* otherwise it is 1. */ \ (INT_DIV_NEG_RESULT_SIGN(a, b) ? -1 : 1) : ( \ \ /* check if b is a power of 2 */ \ /* */ \ /* formula: round(log_2(b) % 1, OPT_INT_DIV_TEST_PRECISION digits */ \ /* after point) == 0 */ \ (roundl(fmodl(log2l((b)), 1.l) * OPT_INT_DIV_ROUNDING) == 0.l) ? ( \ /* if only one of the numbers is negative, the result is */ \ /* negative */ \ 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 */