]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Add bits_is_power_of_two()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 18 Apr 2017 12:38:59 +0000 (15:38 +0300)
committerGitLab <gitlab@git.dovecot.net>
Thu, 27 Apr 2017 07:00:08 +0000 (10:00 +0300)
src/lib/bits.h
src/lib/test-bits.c

index b9e5f59f2638d07e3a1dc357ecac464b0837313b..d030382267a844f79e9c3cb1b4019f0d3ec65006 100644 (file)
@@ -8,6 +8,13 @@
 
 size_t nearest_power(size_t num) ATTR_CONST;
 
+/* Returns TRUE if 2^x=num, i.e. if num has only a single bit set to 1. */
+static inline bool ATTR_CONST
+bits_is_power_of_two(uint64_t num)
+{
+       return num > 0 && (num & (num - 1)) == 0;
+}
+
 #if __GNUC__ > 2
 static inline unsigned int ATTR_CONST
 bits_required32(uint32_t num)
index e370f79af84c9db579700d77bf209b9bcf71f234..0f20d054942abc697c7083abcfb9db73fb1c4297 100644 (file)
@@ -39,6 +39,20 @@ static void test_nearest_power(void)
        test_end();
 }
 
+static void test_bits_is_power_of_two(void)
+{
+       test_begin("bits_is_power_of_two()");
+       for (unsigned int i = 0; i < 64; i++)
+               test_assert_idx(bits_is_power_of_two(1ULL << i), i);
+       for (unsigned int i = 2; i < 64; i++) {
+               test_assert_idx(!bits_is_power_of_two((1ULL << i) - 1), i);
+               test_assert_idx(!bits_is_power_of_two((1ULL << i) + 1), i);
+       }
+       test_assert(!bits_is_power_of_two(0));
+       test_assert(!bits_is_power_of_two(0xffffffffffffffffULL));
+       test_end();
+}
+
 static void test_bits_requiredXX(void) 
 {
        /* As ..64 depends on ..32 and tests it twice,
@@ -135,6 +149,7 @@ static void test_bits_fraclog_const(void)
 void test_bits(void)
 {
        test_nearest_power();
+       test_bits_is_power_of_two();
        test_bits_requiredXX();
        test_bits_fraclog();
        test_bits_fraclog_const();