diff options
Diffstat (limited to 'common/common.c')
-rw-r--r-- | common/common.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/common/common.c b/common/common.c index d0b2382b78..967ab961c0 100644 --- a/common/common.c +++ b/common/common.c @@ -318,3 +318,21 @@ char **mp_dup_str_array(void *tctx, char **s) MP_TARRAY_APPEND(tctx, r, num_r, NULL); return r; } + +// Return rounded down integer log 2 of v, i.e. position of highest set bit. +// mp_log2(0) == 0 +// mp_log2(1) == 0 +// mp_log2(31) == 4 +// mp_log2(32) == 5 +unsigned int mp_log2(uint32_t v) +{ +#if defined(__GNUC__) && __GNUC__ >= 4 + return v ? 31 - __builtin_clz(v) : 0; +#else + for (int x = 31; x >= 0; x--) { + if (v & (((uint32_t)1) << x)) + return x; + } + return 0; +#endif +} |