c中的位操作

时间:2010-01-13 03:55:54

标签: c bit-manipulation

如何反转和旋转十六进制数并使用按位运算符返回C中的数字?

例如:

0xabcd -> 0xdcba

0xabcd -> 0xdabc

4 个答案:

答案 0 :(得分:13)

很难知道这个问题从哪里开始。另外我闻到了作业。

有些观点:

  • 没有“十六进制数”这样的东西。 Hex只是一种表示法。如何反转和旋转十进制数并在C中返回数字?例如:

      1776年 - > 6771

         1776年 - > 6771?

  • 要解决这个问题,你需要深刻理解位置符号,无论是基数10,基数16,基数2,还是你有什么。

  • 您可以通过添加,减去,乘法和除法来获得所需的一切。 那些是对数字的操作。模数也非常有用。

  • 如果您想要乘以或除以2的幂,我向您推荐C左移<<和右移>>运算符。这些对于使用C类型unsignedunsigned long表示的数字非常有效。

答案 1 :(得分:1)

十六进制数字是数字,正如Norman的答案所指出的那样。但是,1个十六进制数字= 4位,因此这些操作实际上是您可能想要对整数值执行的操作。

第二个是按位旋转4位。有关编译器友好轮换的最佳实践,请参阅Best practices for circular shift (rotate) operations in C++以防止C / C ++未定义行为。

如果您的输入不是8,16,32或64位,那么您可能需要手动移动+掩码,而不是依赖于shift-in-zero。

第一个需要更多代码:它会颠倒半字节的顺序。没有机器指令,或者通过对整个数字的一​​些按位操作来简单地构建它。

我认为您必须颠倒字节的顺序,然后在每个字节内反转半字节的顺序(8位旋转4)。

答案 2 :(得分:0)

为了好玩,请遵循适用于任何数字宽度的递归解决方案。

#include <limits.h>
unsigned ReverseHex(unsigned x, unsigned DigitWidth) {
  if (DigitWidth <= 1) {
    return x;
  }
  unsigned SideDigitWidth = DigitWidth / 2;
  unsigned SideBitWidth = SideDigitWidth * 4;
  unsigned CenterAndRightDigitWidth = DigitWidth - SideDigitWidth;
  unsigned CenterAndRightBitWidth = CenterAndRightDigitWidth * 4;
  unsigned CenterAndRight = x & ((1u << CenterAndRightBitWidth) - 1);
  unsigned Right = x & ((1u << SideBitWidth) - 1);
  unsigned Center = CenterAndRight - Right;

  return ReverseHex(x >> CenterAndRightBitWidth, SideDigitWidth) + Center
      + (ReverseHex(Right, SideDigitWidth) << CenterAndRightBitWidth);
}

int main(void) {
  printf("%X\n", ReverseHex(0x1234, 4));
  printf("%X\n", ReverseHex(0x12345, 5));
  printf("%X\n", ReverseHex(0x1234567, 7));
  printf("%X\n", ReverseHex(0x12345678, 8));
  return 0;
}

输出

4321
54321
7654321
87654321

答案 3 :(得分:-1)

使用位操作交换数字:

使用带有适当掩码的原始数字进行按位AND运算,从原始数字中提取十六进制数字(4位)。

将此提取的位模式移位到它的新位置。

按位或重新定位位模式。

希望这有帮助。