My goal with this program is that I want to be able to set 1000 bits to 0 or 1 separately, for this I'm using an array of 128 bit integers.
Now the issue is when I simply clear_bit(3), bit 35 is also being cleared (and vice versa). 3 & 35 are always cleared together, same for 4 & 36, 5 & 37 etc. So there's clearly a pattern. I simply want 3 to be cleared while the rest stays 1.
Any ideas why this is happening? Thanks!
#include <stdio.h>
__uint128_t array [(1000/128) + 1];
// Set bit to 0.
void clear_bit(int k)
{
array[k/128] &= ~(1 << (k%128));
}
// Find the value of bit.
int test_bit(int k)
{
return((array[k/128] & (1 << (k%128) )) != 0);
}
// Set bit to 1.
void set_bit(int k)
{
array[k/128] |= 1 << (k%128); // Set the bit at the k-th position in A[i]
}
int main (void)
{
// Set all bits to 1.
for(int i = 0; i < 40; i++) {
set_bit(i);
}
// I want to clear bit 3, but it also clears 35 for an unknown reason.
clear_bit(3);
for(int i = 0; i < 40; i++) {
printf("%d is now:%d\n", i, test_bit(i));
}
return (0);
}
OP's code is not using 128-bit math with 1 << (k%128)
. @user2357112
Insure the integer math is done with at least 128-bit math.
array[k/128] &= ~(1 << (k%128));
array[k/128] &= ~((__uint128_t)1 << (k%128));
Alternative, use unsigned
in a portable fashion should unsigned
have a bit width of be 16,32 64, 36, etc. No need to rely on __uint128_t
.
#include <limits.h>
#define UNS_WIDTH (sizeof(unsigned)*CHAR_BIT)
unsigned array[(1000 + UNS_WIDTH - 1)/UNS_WIDTH];
void clear_bit(int k) {
array[k/UNS_WIDTH] &= ~(1u << (k%UNS_WIDTH));
}
Best to insure the 1
is unsigned
with 1u
.