SJacobs - 3 years ago 159

C Question

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);

}

Recommended for you: Get network issues from **WhatsUp Gold**. **Not end users.**

Answer Source

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`

.

Recommended from our users: **Dynamic Network Monitoring from WhatsUp Gold from IPSwitch**. ** Free Download**