From 0957b5dc4925d2fa3f749bcd411e1d37379fc979 Mon Sep 17 00:00:00 2001 From: Intel A80486DX2-66 Date: Sat, 9 Mar 2024 19:29:11 +0300 Subject: [PATCH] opt_int_div.h: make test precision limit optional --- c-programming/math/opt_int_div.h | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/c-programming/math/opt_int_div.h b/c-programming/math/opt_int_div.h index 2a15fb2..0484269 100644 --- a/c-programming/math/opt_int_div.h +++ b/c-programming/math/opt_int_div.h @@ -11,7 +11,8 @@ #include // parameters -#define OPT_INT_DIV_TEST_PRECISION 8 +#define OPT_INT_DIV_IS_TEST_PRECISION_LIMITED 0 /* true (1) or false (0) */ +#define OPT_INT_DIV_TEST_PRECISION 8 /* only if the above parameter is 1 */ // constants #define OPT_INT_DIV_ROUNDING \ @@ -24,6 +25,16 @@ /* 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 LOG2_DEC_PORTION(b) fmodl(log2l(INT_ABS((b))), 1.l) +#define OPT_INT_DIV_TEST(b) \ + /* check if b is a power of 2 */ \ + /* */ \ + /* formula: round(log_2(b) % 1, OPT_INT_DIV_TEST_PRECISION digits */ \ + /* after point) == 0 */ \ + OPT_INT_DIV_IS_TEST_PRECISION_LIMITED ? \ + roundl(LOG2_DEC_PORTION((b)) * OPT_INT_DIV_ROUNDING) == 0.l \ + : \ + LOG2_DEC_PORTION((b)) == 0.l // the main macro #define OPT_INT_DIV(a, b) \ @@ -37,13 +48,8 @@ INT_ABS((a)) < INT_ABS((b)) ? \ 0 : ( \ \ - /* 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(INT_ABS((b))), 1.l) * OPT_INT_DIV_ROUNDING) \ - == 0.l) ? ( \ - INT_DIV_NEG_RESULT_SIGN(a, b) ? \ + 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)))) \