需要使用Bit Manipulation进行一些错误识别

时间:2016-10-07 10:24:12

标签: c bit-manipulation bit-shift

问题是SegmentOFF。例如,在调用DATA[18] = 0x10之后SegmentON,并且我希望清除DATA[18]的第6位。致电SegmentOFF会清除所有位并最终DATA[18] = 0x00

代码有什么问题。

unsigned char DATA[24];     
unsigned int Segment2BitMap[48] = 
{
    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
    0x0204, 0x0300, 0x0302, 0x0307, 0x0600, 0x0601, 0x0602, 0x0603,
    0x0604, 0x0605, 0x0606, 0x0607, 0x0804, 0x0900, 0x0902, 0x0907,
    0x0C00, 0x0C01, 0x0C02, 0x0C03, 0x0C04, 0x0C05, 0x0C06, 0x0C07,
    0x0E04, 0x0F00, 0x0F02, 0x0F07, 0x1200, 0x1201, 0x1202, 0x1203,
    0x1204, 0x1205, 0x1206, 0x1207, 0x1404, 0x1500, 0x1502, 0x1507    
};

void SegmentON(unsigned char Number)
   {
    unsigned int Data = Segment2BitMap[Number];
    unsigned char UpperByte = (Data/256); //upper byte
    unsigned char LowerByte = (Data%256 & 0x07); //lower byte
    DATA[UpperByte] |= (0x01<<LowerByte);
}

void SegmentOFF(unsigned char Number)
{
    unsigned int Data = Segment2BitMap[Number];
    unsigned char UpperByte = (Data/256); //upper byte
    unsigned char LowerByte = (Data%256 & 0x07); //lower byte
    DATA[UpperByte] &= (0x01<<LowerByte);
}

int main()
{
    SegmentON(40);
    SegmentOFF(42);
}

2 个答案:

答案 0 :(得分:0)

 1010 & 0101 == 0000 

如果要清除特定位而其余部分不应更改,则必须将其反转。

对于8位:

var &= (1<<2)^0xFF

这将设置第3个最低有效位(1<<2) == 0x04然后用xor将其反转为

然后将该掩码应用于var以将第3位设置为零,其余位保持不变

这将是

var = var & 0b11111011

答案 1 :(得分:0)

好吧,我主要做ruby但是逐位运算符看起来一样。 (因此我假设它们是相同的)

让我们使用随机数表示201.二进制表示如下: 1100 1001

要开启一点,只需执行OR操作。

201 | = 1&lt;&lt; 2

然后机器向左移位0000 0001 2步,创建0000 0100,然后进行OR操作,如果其中任何一个数字在第n个位置有1,则结果数字在同一位置有1。 / p>

1100 1001#first input

0000 0100#second input

1100 1101#output =&gt; 209

到目前为止一直很好,但是当你尝试使用AND运算符将某个位设置为0时出错了。 201&amp; = 1&lt;&lt;&lt; 2&lt; / p&gt;

与之前相同,但现在它执行AND操作。如果数字在第n个位置共享1,则结果数字在同一位置将为1。

1100 1001#first input

0000 0100#second input

<00> 0000 0000#output =&gt; 0

这是因为他们没有共同的1。这可以通过两种方式解决。 (均使用XOR操作)

&#39;条件&#39;方式。

if 209&(1<<2) != 0
  209 ^= 1<<2
end

此代码将执行以下操作。如果201和1 <&lt;&lt; 2(8)不等于0,则执行异或操作。在这种情况下,它不等于0,因此它将执行如下操作。如果位相同,它将放置0并且它们不同的位置将放置1。

1100 1101#first input(209)

0000 0100#second input(8)

1100 1001#output =&gt; 201

纯粹的比特&#39;溶液

209及(255 ^(1 <<;&2))

这将产生以下操作。

1100 1101#first input(209)

1111 1011#第二输入数字(247)

1100 1001#output =&gt; 201

我们最终做了一个额外的位操作,但我们也松开了条件。所以它应该更快。得到它,呵呵。这里的代码不能直接在c中实现,但主体应该是相同的。

PS你对低位字节的定义看起来有点奇怪,你知道它只返回前3位,对吗?

希望它有所帮助。