]> sigrok.org Git - libsigrok.git/commitdiff
strutil: introduce power-of-two calculation routine
authorGerhard Sittig <redacted>
Tue, 17 Oct 2023 19:20:56 +0000 (21:20 +0200)
committerGerhard Sittig <redacted>
Wed, 18 Oct 2023 19:35:13 +0000 (21:35 +0200)
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.

include/libsigrok/proto.h
src/strutil.c

index 4e8d36ec4533c78af79e9d84539bbc02dbb2ee49..2c3b255972d7f2a5655f8c5055c4db438b82b834 100644 (file)
@@ -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);
index 63cd2fdfc62baf8e2ea65b88f9a0378ceee3a23e..841a682a2f4b89779043704c279e0c406eb244ab 100644 (file)
@@ -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;
+}
+
 /** @} */