summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2023-11-10 12:28:00 -0500
committerTavian Barnes <tavianator@tavianator.com>2023-11-10 21:13:36 -0500
commit208376ef99da243545efcd6fb02d3469b4c068ed (patch)
treeb7155aa6823ad9488fa23402e689cf131878ef9d
parent4efbe8eca395c90fc0053c7ba1038ccb7bf69e61 (diff)
downloadbfs-208376ef99da243545efcd6fb02d3469b4c068ed.tar.xz
bit: Implement a branchless has_single_bit()
-rw-r--r--src/bit.h3
-rw-r--r--tests/bit.c3
2 files changed, 5 insertions, 1 deletions
diff --git a/src/bit.h b/src/bit.h
index 21a8076..e680fed 100644
--- a/src/bit.h
+++ b/src/bit.h
@@ -350,7 +350,8 @@ UINT_OVERLOADS(FIRST_TRAILING_ONE)
#define HAS_SINGLE_BIT(type, suffix, width) \
static inline bool has_single_bit##suffix(type n) { \
- return n && !(n & (n - 1)); \
+ /** Branchless n && !(n & (n - 1)) */ \
+ return n < (n ^ (n - 1)) + 1; \
}
UINT_OVERLOADS(ROTATE_LEFT)
diff --git a/tests/bit.c b/tests/bit.c
index cb339f4..7b20770 100644
--- a/tests/bit.c
+++ b/tests/bit.c
@@ -117,5 +117,8 @@ int main(void) {
verify_eq(bit_floor(0), 0);
verify_eq(bit_ceil(0), 1);
+ bfs_verify(!has_single_bit(0));
+ bfs_verify(!has_single_bit(UINT32_MAX));
+
return EXIT_SUCCESS;
}