C获得位/设置位合并

时间:2016-11-13 17:05:38

标签: c macros bit-manipulation

我这次有重要的代码:

#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>
}

我的问题是,如果可以进一步转换READBIT / SETBIT宏 - 可能将它们合并为一个宏并降低计算量。

如果我展开这些宏(将B作为变量),我得到(希望是正确的):

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

B可以取值0-7。我错过了一个更简单的等效逻辑操作吗?

1 个答案:

答案 0 :(得分:1)

目前还不完全清楚你的目标是什么。也许您希望能够灵活地复制N最低位,或者您希望能够将选定的位从源复制到目标。

以下是一些显示这两种方法的代码。宏COPYBITS复制N最低位,宏COPYBIT复制订单N位。

更新

我添加了一些宏来简化COPYBITCOPYBITS宏的定义,并使其逻辑更清晰:

#include <stdio.h>

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

//#define COPYBITS(T,S,N) ((T) = ((T) & (~0x0ul << (N))) | ((S) & ~(~0x0ul << (N))))

//#define COPYBIT(T, S, N) ((T) = ((T) & ~(0x1ul << (N))) | ((S) & (0x1ul << (N))))

/* A final refinement */
/* CLEARBIT evaluates to T with the order N bit to 0 */
#define CLEARBIT(T,N) ((T) & ~(0x1ul << (N)))

/* CLEARBITS evaluates to T with the N lowest order bits to 0 */
#define CLEARBITS(T,N) ((T) & (~0x0ul << (N)))

/* GETBIT evaluates to S, keeping only the order N bit */
#define GETBIT(S,N) ((S) & (0x1ul << (N)))

/* GETBITS evaluates to S, keeping only the N lowest order bits */
#define GETBITS(S,N) ((S) & ~(~0x0ul << (N)))

/* COPYBIT copies the order N bit of S to T */
#define COPYBIT(T,S,N) ((T) = ((T) & CLEARBIT((T),(N))) | (GETBIT((S),(N))))

/* COPYBITS copies the N lowest order bits of S to T */
#define COPYBITS(T,S,N) ((T) = ((T) & CLEARBITS((T),(N))) | (GETBITS((S),(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;
}