C语言中使用位域反转位?

发布于 2024-11-03 22:52:44 字数 90 浏览 0 评论 0原文

如何使用c语言中的按位运算符反转位

例如:

i/p: 10010101
o/p: 10101001

how to reverse the bits using bit wise operators in c language

Eg:

i/p: 10010101
o/p: 10101001

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

佞臣 2024-11-10 22:52:44

如果它只是 8 位:

u_char in = 0x95;
u_char out = 0;
for (int i = 0; i < 8; ++i) {
    out <<= 1;
    out |= (in & 0x01);
    in >>= 1;
}

或者为了加分:

u_char in = 0x95;
u_char out = in;
out = (out & 0xaa) >> 1 | (out & 0x55) << 1;
out = (out & 0xcc) >> 2 | (out & 0x33) << 2;
out = (out & 0xf0) >> 4 | (out & 0x0f) << 4;

弄清楚最后一个是如何工作的对读者来说是一项练习;-)

If it's just 8 bits:

u_char in = 0x95;
u_char out = 0;
for (int i = 0; i < 8; ++i) {
    out <<= 1;
    out |= (in & 0x01);
    in >>= 1;
}

Or for bonus points:

u_char in = 0x95;
u_char out = in;
out = (out & 0xaa) >> 1 | (out & 0x55) << 1;
out = (out & 0xcc) >> 2 | (out & 0x33) << 2;
out = (out & 0xf0) >> 4 | (out & 0x0f) << 4;

figuring out how the last one works is an exercise for the reader ;-)

吐个泡泡 2024-11-10 22:52:44

Knuth 在计算机编程艺术第 4A 卷,按位技巧和技巧。

为了以分而治之的方式反转 32 位数字的位,他使用魔术常量

u0= 1010101010101010, (from -1/(2+1)

u1= 0011001100110011, (from -1/(4+1)

u2= 0000111100001111 , (from -1/(16+1)

u3= 0000000011111111, (from -1/(256+1)

方法归功于 Henry Warren Jr.,黑客们很高兴。16

    unsigned int u0 = 0x55555555;
    x = (((x >> 1) & u0) | ((x & u0) << 1));
    unsigned int u1 = 0x33333333;
    x = (((x >> 2) & u1) | ((x & u1) << 2));
    unsigned int u2 = 0x0f0f0f0f;
    x = (((x >> 4) & u2) | ((x & u2) << 4));
    unsigned int u3 = 0x00ff00ff;
    x = (((x >> 8) & u3) | ((x & u3) << 8));
    x = ((x >> 16) | (x << 16) mod 0x100000000); // reversed

和 8 位情况留给读者作为练习。

Knuth has a section on Bit reversal in The Art of Computer Programming Vol 4A, bitwise tricks and techniques.

To reverse the bits of a 32 bit number in a divide and conquer fashion he uses magic constants

u0= 1010101010101010, (from -1/(2+1)

u1= 0011001100110011, (from -1/(4+1)

u2= 0000111100001111, (from -1/(16+1)

u3= 0000000011111111, (from -1/(256+1)

Method credited to Henry Warren Jr., Hackers delight.

    unsigned int u0 = 0x55555555;
    x = (((x >> 1) & u0) | ((x & u0) << 1));
    unsigned int u1 = 0x33333333;
    x = (((x >> 2) & u1) | ((x & u1) << 2));
    unsigned int u2 = 0x0f0f0f0f;
    x = (((x >> 4) & u2) | ((x & u2) << 4));
    unsigned int u3 = 0x00ff00ff;
    x = (((x >> 8) & u3) | ((x & u3) << 8));
    x = ((x >> 16) | (x << 16) mod 0x100000000); // reversed

The 16 and 8 bit cases are left as an exercise to the reader.

無處可尋 2024-11-10 22:52:44

好吧,这可能不是最优雅的解决方案,但它是一个解决方案:

int reverseBits(int x) {
     int res = 0;
     int len = sizeof(x) * 8; // no of bits to reverse
     int i, shift, mask;

     for(i = 0; i < len; i++) {
          mask = 1 << i; //which bit we are at
          shift = len - 2*i - 1;
          mask &= x;
          mask = (shift > 0) ? mask << shift : mask >> -shift;
          res |= mask; // mask the bit we work at at shift it to the left     
     }

     return res;
}

在一张纸上测试它,它似乎有效:D

编辑:是的,这确实非常复杂。我不知道为什么,但我想找到一个不接触输入的解决方案,所以这来到了我的脑海

Well, this might not be the most elegant solution but it is a solution:

int reverseBits(int x) {
     int res = 0;
     int len = sizeof(x) * 8; // no of bits to reverse
     int i, shift, mask;

     for(i = 0; i < len; i++) {
          mask = 1 << i; //which bit we are at
          shift = len - 2*i - 1;
          mask &= x;
          mask = (shift > 0) ? mask << shift : mask >> -shift;
          res |= mask; // mask the bit we work at at shift it to the left     
     }

     return res;
}

Tested it on a sheet of paper and it seemed to work :D

Edit: Yeah, this is indeed very complicated. I dunno why, but I wanted to find a solution without touching the input, so this came to my haead

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文