Last active
June 17, 2025 00:27
-
-
Save jweinst1/ad0c096b2cd641f81962eb61205dfd76 to your computer and use it in GitHub Desktop.
uses continuous bit fields to get first set or unset to an arbitrary size
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <stdint.h> | |
// allows a set for a number over field of 64 bit blocks of bits | |
void set_bit_for_number(size_t* nums, size_t key) { | |
const size_t tabs = key / 64; | |
const size_t rem = key % 64; | |
printf("Setting block %zu, bit %zu, mask %zu\n", tabs, rem, 1 << rem); | |
nums[tabs] |= 1 << rem; | |
} | |
size_t find_unset_bit(size_t num) { | |
return ~num & (num + 1); | |
} | |
size_t find_first_set_bit(size_t num) { | |
return num & -num; | |
} | |
size_t find_unset_bit_2(const size_t* num) { | |
return num[0] ? find_unset_bit(num[0]) : find_unset_bit(num[1]); | |
} | |
size_t find_first_set_bit_2(const size_t* num) { | |
return num[0] ? find_first_set_bit(num[0]) : find_first_set_bit(num[1]); | |
} | |
struct bit_field { | |
size_t size; | |
size_t first_set; | |
size_t* blocks; | |
}; | |
int main(int argc, char const *argv[]) | |
{ | |
printf("%zu %zu\n", (size_t)-1, find_unset_bit((size_t)-1)); | |
printf("%zu %zu\n", 0, find_first_set_bit(0)); | |
size_t nums[4] = {0}; | |
set_bit_for_number(nums, 76); | |
printf("%zu\n", find_first_set_bit_2(nums)); | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include <cstdint> | |
#include <cstdlib> | |
inline size_t find_unset_bit(size_t num) { | |
return ~num & (num + 1); | |
} | |
inline size_t find_first_set_bit(size_t num) { | |
return num & -num; | |
} | |
template <size_t widthSpan> | |
size_t getFirst(size_t* span) { | |
constexpr size_t numSpan = widthSpan / 64; | |
size_t i = 0; | |
do { | |
if (span[i]) { | |
return find_first_set_bit(span[i]); | |
} | |
++i; | |
} while (i < numSpan); | |
return 0; | |
} | |
template<> | |
size_t getFirst<64>(size_t* span) { | |
return find_first_set_bit(span[0]); | |
} | |
int main(int argc, char const *argv[]) | |
{ | |
size_t foo = 0b100; | |
printf("%zu\n", getFirst<64>(&foo)); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment