Perlator - 21 days ago 6
C Question

# C get bit / set bit consolidation

I have this time critical code:

``````#define READBIT(A, B) ((A >> (B & 7)) & 1)
#define SETBIT(T, B, V) (T = V ? T | (1<<B) : T & ~(1<<B))

for (int j = 0; j < 32; j++) {
bits = 0;
sc   = seckey[31 - j];

<do something with bits>
}
``````

My question is, if it is possible to transform the READBIT/SETBIT macros further - possibly consolidating them into one macro and lowering computational effort.

If I expand these macros (leaving B as a variable), I get (hopefully correct):

``````bits = ((sc >> (B & 7)) & 1) ? bits | (1<<B) : bits & ~(1<<B)
``````

Where B can take values 0-7. Am I missing a simpler equivalent logical operation?

It is not entirely clear what your goal is here. Maybe you want the flexibility of being able to copy the `N` lowest order bits, or maybe you want to be able to copy a chosen bit from the source to the target.

Here is some code that shows both of these approaches. The macro `COPYBITS` copies the `N` lowest order bits, and the macro `COPYBIT` copies the order `N` bit:

``````#include <stdio.h>

#define READBIT(A, B) ((A >> (B & 7)) & 1)
#define SETBIT(T, B, V) (T = V ? T | (1<<B) : T & ~(1<<B))

/* COPYBITS copies the N lowest order bits of S to T */
#define COPYBITS(T, S, N) ((T) = ((T) & ~((0x1ul << (N)) - 1)) | ((S) & ((0x1ul << (N)) - 1)))

/* COPYBIT copies the order N bit of S to T */
#define COPYBIT(T, S, N) ((T) = ((T) & ~(0x1ul << (N))) | ((S) & (0x1ul << (N))))

int main(void)
{
unsigned sc;
unsigned bits2 = 4u;
unsigned bits3 = 4u;

sc = 0x10Fu;

printf("sc = %u\n", sc);
putchar('\n');
puts("Before copying:");
printf("bits2 = %u\n", bits2);
printf("bits3 = %u\n", bits3);

COPYBITS(bits3, sc, 8);

putchar('\n');
puts("After copying the lowest 8 bits of sc:");
printf("bits2 = %u\n", bits2);
printf("bits3 = %u\n", bits3);

bits2 = 0u;
COPYBITS(bits2, sc, 9);

putchar('\n');
puts("After copying the lowest 9 bits of sc:");
printf("bits2 = %u\n", bits2);

bits2 = 0u;
COPYBITS(bits2, sc, 1);

putchar('\n');
puts("After copying the lowest 1 bit of sc:");
printf("bits2 = %u\n", bits2);

bits2 = 0u;
COPYBITS(bits2, sc, 0);

putchar('\n');
puts("After copying the lowest 0 bits of sc:");
printf("bits2 = %u\n", bits2);

bits2 = 0u;
for(size_t i = 0; i < 8; i++)
COPYBIT(bits2, sc, i);

putchar('\n');
puts("After copying the lowest 8 bits of sc:");
printf("bits2 = %u\n", bits2);

COPYBIT(bits2, 0xFF, 7);

putchar('\n');
puts("After copying order 7 bit of 0xFF (1) to order 7 bit of bits2:");
printf("bits2 = %u\n", bits2);

COPYBIT(bits2, 0x0, 7);

putchar('\n');
puts("After copying order 7 bit of 0x0 (0) to order 7 bit of bits2:");
printf("bits2 = %u\n", bits2);

return 0;
}
``````
Source (Stackoverflow)