From: Gerhard Sittig Date: Tue, 17 Oct 2023 19:20:56 +0000 (+0200) Subject: strutil: introduce power-of-two calculation routine X-Git-Url: https://sigrok.org/gitaction?a=commitdiff_plain;h=a2f3645bcf73a421192591fc7d2d030f9997fda7;p=libsigrok.git strutil: introduce power-of-two calculation routine Introduce the sr_next_power_of_two() routine which determines how many bits are required to store a value. Decorate it as SR_API because some applications may want it, but more importantly to make it available to the test suite. --- diff --git a/include/libsigrok/proto.h b/include/libsigrok/proto.h index 4e8d36ec..2c3b2559 100644 --- a/include/libsigrok/proto.h +++ b/include/libsigrok/proto.h @@ -268,6 +268,8 @@ SR_API char *sr_text_trim_spaces(char *s); SR_API char *sr_text_next_line(char *s, size_t l, char **next, size_t *taken); SR_API char *sr_text_next_word(char *s, char **next); +SR_API int sr_next_power_of_two(size_t value, size_t *bits, size_t *power); + /*--- version.c -------------------------------------------------------------*/ SR_API int sr_package_version_major_get(void); diff --git a/src/strutil.c b/src/strutil.c index 63cd2fdf..841a682a 100644 --- a/src/strutil.c +++ b/src/strutil.c @@ -1819,4 +1819,47 @@ SR_API char *sr_text_next_word(char *s, char **next) return word; } +/** + * Get the number of necessary bits to hold a given value. Also gets + * the next power-of-two value at or above the caller provided value. + * + * @param[in] value The value that must get stored. + * @param[out] bits The required number of bits. + * @param[out] power The corresponding power-of-two. + * + * @return SR_OK upon success, SR_ERR* otherwise. + * + * TODO Move this routine to a more appropriate location, it is not + * strictly string related. + * + * @since 0.6.0 + */ +SR_API int sr_next_power_of_two(size_t value, size_t *bits, size_t *power) +{ + size_t need_bits; + size_t check_mask; + + if (bits) + *bits = 0; + if (power) + *power = 0; + + if (!value) + return SR_ERR_ARG; + + need_bits = 0; + check_mask = 0; + do { + need_bits++; + check_mask <<= 1; + check_mask |= 1UL << 0; + } while (value & ~check_mask); + + if (bits) + *bits = need_bits; + if (power) + *power = ++check_mask; + return SR_OK; +} + /** @} */