Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c语言中的位运算_C_Bit Manipulation - Fatal编程技术网

c语言中的位运算

c语言中的位运算,c,bit-manipulation,C,Bit Manipulation,如何反转和旋转十六进制数,并使用位运算符返回C中的数字 例如: 0xabcd -> 0xdcba 0xabcd -> 0xdabc 很难知道从哪里开始这个问题。加上我闻到了家庭作业的味道 有几点: 没有“十六进制数”这样的东西。十六进制只是一种符号。如何反转和旋转十进制数并返回C中的数字?例如: 1776->6771 1776->6771 要解决这个问题,您需要对位置符号有深入的理解,不管它是以10为基数、以16为基数、以2为基数,还是其他什么 你所需要的一切都可以通过加、减

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

例如:

0xabcd -> 0xdcba

0xabcd -> 0xdabc

很难知道从哪里开始这个问题。加上我闻到了家庭作业的味道

有几点:

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

    1776->6771

    1776->6771

  • 要解决这个问题,您需要对位置符号有深入的理解,不管它是以10为基数、以16为基数、以2为基数,还是其他什么

  • 你所需要的一切都可以通过加、减、乘、除得到。这些是对数字的操作。模量也非常有用

  • 如果你想乘或除二的幂,我推荐你使用C左移
    操作符。对于使用C类型
    unsigned
    unsigned long
    表示的数字,这些函数非常适用


要使用位操作交换数字:

使用带有适当掩码的原始数字执行逐位AND操作,以从原始数字中提取十六进制数字(4位)

将此提取的位模式移动到其新位置

按位或重新定位的位模式组合在一起


希望这能有所帮助。

正如诺曼的回答所指出的,十六进制数就是数字。但是,1个十六进制数字=4位,因此这些操作实际上是有意义的,因为您可能希望对整数值执行这些操作


第二个是按位旋转4位。有关防止C/C++未定义行为的编译器友好循环的最佳实践,请参阅

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


第一个需要更多的代码:它颠倒了半字节的顺序。对于这一点,没有机器指令,也没有简单的方法可以通过对整个数字进行几次位运算来构建它


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

为了好玩,下面是一个适用于任意宽度数字的递归解决方案

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

+1用于解释(以适当的粗略方式)数字与其在特定基数中的符号之间的区别。真的吗?当人们认为你不知道定义时,我很生气。仅仅因为你用了一个语义错误的词,并不意味着你不知道它是什么。@Louis:我不认为诺曼是在暗示他不知道它是什么,我认为他是想把区别弄清楚。事实上,十进制中的“10”在十六进制中是“A”,但它们是相同的,所以在十六进制中“切换”数字123在数学上与在十进制中切换数字123是不同的操作,这对大多数人来说并不明显。哦,是的,我不是在谈论这个特殊的情况。我只是发现一般来说,如果你使用了一个错误的术语,很多响应最终都是定义。第二个是按位旋转4位。有关防止未定义行为的编译器友好循环的最佳实践,请参阅。
4321
54321
7654321
87654321