【问题标题】:Setting a bit of an unsigned char with the another bit of another unsigned char without conditional用另一个无符号字符的另一位无条件地设置一个无符号字符的位
【发布时间】:2012-06-23 15:35:29
【问题描述】:

我用这种方式按位打开和关闭位:

unsigned char myChar = ...some value
myChar |= 0x01 << N // turn on the N-th bit

myChar &= ~(0x01 << N) //turn off the N-th bit

现在,假设 N 的值是已知的,但设置/取消设置操作取决于另一个无符号字符的位的值。 从现在开始,我就是这样做的:

if ((otherChar & (0x01 << M)) != 0)
{
    //M-th bit of otherChar is 1
    myChar |= 0x01 << N; 
}else
{
    myChar &= ~(0x01 << N);
}

这应该是一种从无符号字符到另一个字符的“移动位”操作。

我的问题: 有没有办法在不使用条件的情况下做到这一点? (也没有 std::bitset)

【问题讨论】:

  • 当你说N-th bit时,是不是从零开始计数?
  • 是..从零开始。这相关吗?

标签: c++ c bit-manipulation


【解决方案1】:

简短的回答是“是”。

更长的答案是您直接从源代码中使用该位:

unsigned char bit = 1 << N;

myChar &= ~bit;             // Zero the bit without changing anything else
myChar |= otherChar & bit;  // copy the bit from the source to the destination.

这假设您要将位 N 从源复制到目标的位 N。如果源位和目标位可能处于不同的偏移量,事情就会变得更加困难。您不仅从源中提取了正确的位,而且还必须将其移动到正确的位置,然后将其 OR 到目标。基本思路和上面差不多,但是移位的代码有点繁琐。问题是你想做这样的事情:

unsigned char temp = source & 1 << M;
temp <<= N - M;
dest |= temp;

如果 N > M,这将正常工作,但如果 M > N,你最终会得到类似temp &lt;&lt;= -3; 的东西。您喜欢的是左移-3最终右移3-但这不是发生的情况,因此您需要一些条件代码来获取绝对值和确定是进行右移还是左移以将源中的位移到目标中的正确位置。

【讨论】:

  • @MarkTolonen:你是对的,它使用的变量与他在问题中所做的不同。我已经重新编写它以使用与他在问题中相同的方式使用相同的(我认为无论如何)变量。
  • 是的,你是对的。他最初的回答并不完全正确,但我明白了。
  • dest |= ((source &gt;&gt; M) &amp; 1) &lt;&lt; N 怎么样?
  • @FredOverflow:好点——似乎这也应该有效。
【解决方案2】:

一种解决方案是首先始终取消设置该位,然后按位或在otherChar 的适当移位和屏蔽版本中。

【讨论】:

    【解决方案3】:

    这会读取 c1 的 from 位并将其写入 c2 的 to 位。

    #include <stdio.h>
    
    typedef unsigned char uchar;
    
    uchar move_bit(uchar c1, int from, uchar c2, int to)
    {
        int bit;
        bit = (c1 >> from) & 1;            /* Get the source bit as 0/1 value */
        c2 &= ~(1 << to);                  /* clear destination bit */
        return (uchar)(c2 | (bit << to));  /* set destination bit */
    }
    
    int main()
    {
        printf("%02X\n",move_bit(0x84,3,0x42,5));
        printf("%02X\n",move_bit(0x81,0,0x03,7));
        printf("%02X\n",move_bit(0xEF,4,0xFF,6));
        return 0;
    }
    

    结果:

    42
    83
    BF
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-23
      相关资源
      最近更新 更多