4

简而言之,如果我正在处理二进制数字,例如0000 0110,并且假设我只想反转最后 3 位,是否有任何方法可以将其转换为0000 0011

我已经看到了其他问题和资源,其中reverse bits method实现但返回整数反转(即0110 0000,不是0000 0011)。

就像在标准方法中所做的那样,将其反转,然后根据需要进行尽可能多的移动就足够了吗?还是有更直接的方法来实现这一点?

格式:unsigned int reverse_select_bits(int number, int num_bits) { ... }

4

3 回答 3

1

简单参考

请参阅http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious是一个很好的开始,让您了解真正应该如何做。那里描述了一些相当有趣的技术。尤其是看看

http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64Bits

了解如何思考这些问题。

提示 A

对于任意字长,在使用掩码屏蔽您希望保存的位后使用明显的方法:

typeof(word) preserve_mask = \
     ((1 <<  8*sizeof(word)) - 1) & ~(typeof(word))((1 << K) - 1);

其中 K 是您希望“反转”的位数。preserve_mask 会给你一个掩码来保存你不想翻转的单词部分。请注意,上面并不是真正的 C 代码,而是您必须实现的概念。我建议先在你的 CPU 范围内做;然后稍后处理任意精度(并且仅在需要时)。

提示 B

你能看到如何使用 ReverseByteWith64Bits 的泛化来实现任意长度吗?

可以在 N ≢ 0 (mod 8) 的 N 位上零碎完成吗?你可以使用提示 A 的结果吗?

如果您需要进一步的帮助,请告诉我

于 2013-05-22T03:31:28.073 回答
0

由于您只需反转三位,因此准备一个包含八个条目的表是最简单的方法。

int rev_table[8] = {0, 4, 2, 6, 1, 5, 3, 7};
int rev_last_three_bits(int v) {
    return (v & (~7)) | rev_table[v&7];
}
于 2013-05-22T02:53:03.913 回答
-1

实现了一个可以交换一个字符中的两个特定位的函数。

借助此功能,您可以反转位的任何部分。

#include<stdio.h>
void swap_bits(char *a,unsigned char p1,unsigned char p2)
{
    if (p1==p2) return;//don't need swap
    unsigned char bit1=(1<<p1)&(*a);//access the bit in position 1(0-indexed);
    unsigned char bit2=(1<<p2)&(*a);//access the bit in position 2(0-indexed);
    (*a)^=bit1;//set the bit in position 1 to 0.
    if (bit2) (*a)^=1<<p1;// if bit2 is 1 then set the bit in position to 1 
    (*a)^=bit2;
    if (bit1) (*a)^=1<<p2;
}
int main()
{
    char a=0x06;
    swap_bits(&a,0,2);
    printf("%x\n",a);
}
于 2013-05-22T02:57:53.010 回答