Perlator 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];
SETBIT(bits, 0, READBIT(sc, 0));
SETBIT(bits, 1, READBIT(sc, 1));
SETBIT(bits, 2, READBIT(sc, 2));
SETBIT(bits, 3, READBIT(sc, 3));
SETBIT(bits, 4, READBIT(sc, 4));
SETBIT(bits, 5, READBIT(sc, 5));
SETBIT(bits, 6, READBIT(sc, 6));
SETBIT(bits, 7, READBIT(sc, 7));

<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?

Answer

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

    SETBIT(bits2, 0, READBIT(sc, 0));
    SETBIT(bits2, 1, READBIT(sc, 1));
    SETBIT(bits2, 2, READBIT(sc, 2));
    SETBIT(bits2, 3, READBIT(sc, 3));
    SETBIT(bits2, 4, READBIT(sc, 4));
    SETBIT(bits2, 5, READBIT(sc, 5));
    SETBIT(bits2, 6, READBIT(sc, 6));
    SETBIT(bits2, 7, READBIT(sc, 7));

    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;
}
Comments