mirror of
https://gitlab.com/80486DX2-66/gists
synced 2025-05-31 08:31:41 +05:30
opt_int_div.h: make test precision limit optional
This commit is contained in:
@@ -11,7 +11,8 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// parameters
|
// 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
|
// constants
|
||||||
#define OPT_INT_DIV_ROUNDING \
|
#define OPT_INT_DIV_ROUNDING \
|
||||||
@@ -24,6 +25,16 @@
|
|||||||
/* the sign is negative only if one of the numbers is negative */ \
|
/* the sign is negative only if one of the numbers is negative */ \
|
||||||
(((a) < 0) ^ ((b) < 0)) /* 1 if sign is negative else 0 */
|
(((a) < 0) ^ ((b) < 0)) /* 1 if sign is negative else 0 */
|
||||||
#define INT_ABS(x) ((x) < 0 ? -(x) : (x))
|
#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
|
// the main macro
|
||||||
#define OPT_INT_DIV(a, b) \
|
#define OPT_INT_DIV(a, b) \
|
||||||
@@ -37,13 +48,8 @@
|
|||||||
INT_ABS((a)) < INT_ABS((b)) ? \
|
INT_ABS((a)) < INT_ABS((b)) ? \
|
||||||
0 : ( \
|
0 : ( \
|
||||||
\
|
\
|
||||||
/* check if b is a power of 2 */ \
|
OPT_INT_DIV_TEST((b)) ? \
|
||||||
/* */ \
|
(INT_DIV_NEG_RESULT_SIGN(a, b) ? \
|
||||||
/* 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) ? \
|
|
||||||
-INT_BIN_DIV(INT_ABS((a)), INT_ABS((b))) \
|
-INT_BIN_DIV(INT_ABS((a)), INT_ABS((b))) \
|
||||||
: \
|
: \
|
||||||
INT_BIN_DIV(INT_ABS((a)), INT_ABS((b)))) \
|
INT_BIN_DIV(INT_ABS((a)), INT_ABS((b)))) \
|
||||||
|
Reference in New Issue
Block a user