仅使用位操作来反转四边形(nybbles)以获得镜像十六进制

时间:2017-03-07 17:30:06

标签: c++ bit-manipulation bit-shift

我得到了一个有趣的任务来帮助别人;这是:

  

只使用位操作,常量,编写一个函数来反转一个数字中的四分位数,〜! * + - sizeof()<< >> &安培; ^和|。

     

如果,do,while,for,goto,switch等不被允许,没有宏,c ++函数(甚至编译器的内部函数),&&,||,ternary和任何其他数据类型和结构,unsigned int除外。

这是我所拥有的,它有效,但它使用了一个微小的循环,这是一个问题......

unsigned ReverseTetrads(unsigned x)
{
   unsigned reversed = x&0xF;

   while ((x >>= 4) != 0) {
      reversed <<= 4;
      reversed |= x&0xF;
   }

   return reversed;
}

示例:

  

0x12ABCD应该反转为0xDCBA21

2 个答案:

答案 0 :(得分:2)

以下是我提出的建议:

unsigned ReverseTetrads(unsigned x)
{
   unsigned
      reversed = x&0xF,
      offsets = 0;

   reversed <<= 4;
   x >>= 4;
   offsets += !!x;
   reversed |= x&0xF;

   reversed <<= 4;
   x >>= 4;
   offsets += !!x;
   reversed |= x&0xF;

   reversed <<= 4;
   x >>= 4;
   offsets += !!x;
   reversed |= x&0xF;

   reversed <<= 4;
   x >>= 4;
   offsets += !!x;
   reversed |= x&0xF;

   reversed <<= 4;
   x >>= 4;
   offsets += !!x;
   reversed |= x&0xF;

   reversed <<= 4;
   x >>= 4;
   offsets += !!x;
   reversed |= x&0xF;

   reversed <<= 4;
   x >>= 4;
   offsets += !!x;
   reversed |= x&0xF;

   reversed >>= (7 - offsets) * 4;

   return reversed;
}

适用于任何unsigned int

答案 1 :(得分:1)

首先使用标准bit-hack反转四分法,忽略前导零:交换顶部和底部16位,然后在每个16位内交换顶部和底部字节,然后在每个字节内交换顶部和底部的nybble。

然后你可以通过检查底部16位,底部字节然后底部nybble是否为零并适当移动来摆脱前导零(现在尾随为零)。我们可以依赖这样的事实:!x的值为0时计算结果为1,否则为0。

*

根据问题,x >>= !(x & 0x0000ffff) << 4;是允许的,但如果您认为它不算作位操作,那么您可以将x >>= !(x & 0x0000ffff) * 16;替换为html += "<a href='../InspectionView.aspx' class='list-group-item' id=''>Inspection ID: " + inspectionID + " - Due Date: " + inspDueDate + " - Inspector(s): Bob Williams <span style='min-width:75px' class='label label-primary pull-right'>" + status + "</span></a>"; 等。