2010-01-13 93 views
4

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

例如:

0xabcd -> 0xdcba 

0xabcd -> 0xdabc 
+0

的第二一个是由4位按位旋转。请参阅http://stackoverflow.com/questions/776508/best-practices-for-circular-shift-rotate-operations-in-c了解防止未定义行为的编译器友好旋转的最佳实践。 – 2015-08-17 21:15:35

回答

13

很难知道从哪里开始这个问题。另外我闻到功课。

几点:

  • 有没有这样的事,作为一个 “十六进制数”。十六进制只是一个符号。你如何反转和旋转十进制数并返回C中的数字?例如:

    1776 - > 6771

    1776 - > 6771?

  • 为了解决这个问题,就需要位置符号的深刻理解,无论是基地10,基地16,基地2个,或者你有什么。

  • 所有你需要的可以通过加,减,乘和除。 那些号码的操作。模量也很有帮助。

  • 如果你碰巧要乘以或除以2的幂,我向你推荐C左移<<和右移>>操作符。这些适用于使用C类型unsignedunsigned long表示的数字。

+6

+1用于解释(以适当粗略的方式)*数字*及其在特定*基数*中的表示法之间的区别。 – 2010-01-13 04:05:46

+0

真的吗?当人们认为你不知道定义时,我很恼火。仅仅因为你使用了一个语义错误的词并不意味着你不知道它是什么。 – Louis 2010-01-13 04:59:40

+0

@路易斯:我不认为诺曼暗示他不知道它是什么,我认为他试图让这个区别更清楚。事实上,十进制中的“10”是十六进制中的“A”,但它们是相同的,所以在十六进制中“切换”数字123将是一种数学上不同的操作,人。 – 2010-01-13 05:41:20

-1

要使用位操作交换数:

执行使用具有适当的掩模的原始数目,以提取从原始数是十六进制数字(4位)按位与运算。

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

按位或重新定位位模式在一起。

希望这会有所帮助。

1

十六进制数字是数字,正如诺曼的答案指出的那样。然而,1个十六进制数字= 4位,所以这些操作实际上是有意义的,因为您可能想要对整数值进行操作。

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

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


第一个将需要更多的代码:它颠倒半字节的顺序。没有机器指令,或者一次只需要对整个数字进行一些按位操作的简单方法。

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

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