简体   繁体   English

在位流中设置位

[英]Setting bits in a bit stream

I have encountered the following C function while working on a legacy code and I am compeletely baffled, the way the code is organized.我在处理遗留代码时遇到了以下 C 函数,我对代码的组织方式感到困惑。 I can see that the function is trying to set bits at given position in bit stream but I can't get my head around with individual statements and expressions.我可以看到该函数试图在位流中的给定位置设置位,但我无法理解单个语句和表达式。 Can somebody please explain why the developer used divison by 8 (/8) and modulus 8 (%8) expressions here and there.有人可以解释为什么开发人员在这里和那里使用除以 8 (/8) 和模数 8 (%8) 表达式。 Is there an easy way to read these kinds of bit manipulation functions in c?有没有一种简单的方法可以在 c 中读取这些类型的位操作函数?

static void setBits(U8 *input, U16 *bPos, U8 len, U8 val)
{
  U16 pos;
  if (bPos==0)
  {
    pos=0;
  }
  else
  {
    pos = *bPos;
    *bPos += len;
  }
  input[pos/8] = (input[pos/8]&(0xFF-((0xFF>>(pos%8))&(0xFF<<(pos%8+len>=8?0:8-(pos+len)%8)))))
                |((((0xFF>>(8-len)) & val)<<(8-len))>>(pos%8));
  if ((pos/8 == (pos+len)/8)|(!((pos+len)%8)))
    return;
  input[(pos+len)/8] = (input[(pos+len)/8]
                        &(0xFF-(0xFF<<(8-(pos+len)%8))))
                       |((0xFF>>(8-len)) & val)<<(8-(pos+len)%8);
}

please explain why the developer used divison by 8 (/8) and modulus 8 (%8) expressions here and there请解释为什么开发人员在这里和那里使用除以 8 (/8) 和模数 8 (%8) 表达式

First of all, note that the individual bits of a byte are numbered 0 to 7, where bit 0 is the least significant one.首先,请注意字节的各个位编号为 0 到 7,其中位 0 是最低有效位。 There are 8 bits in a byte, hence the "magic number" 8.一个字节有 8 位,因此是“幻数”8。

Generally speaking: if you have any raw data, it consists of n bytes and can therefore always be treated as an array of bytes uint8_t data[n] .一般而言:如果您有任何原始数据,它由n个字节组成,因此始终可以视为字节数组uint8_t data[n] To access bit x in that byte array, you can for example do like this:要访问该字节数组中的位x ,您可以这样做:

Given x = 17 , bit x is then found in byte number 17/8 = 2 .给定x = 17 ,然后在字节号17/8 = 2找到位 x。 Note that integer division "floors" the value, instead of 2.125 you get 2.请注意,整数除法“地板”该值,而不是 2.125,您得到 2。

The remainder of the integer division gives you the bit position in that byte, 17%8 = 1 .整数除法的余数为您提供该字节中的位位置17%8 = 1

So bit number 17 is located in byte 2, bit 1. data[2] gives the byte.所以第 17 位位于字节 2 的第 1 位。 data[2]给出了字节。

To mask out a bit from a byte in C, the bitwise AND operator & is used.为了从 C 中的字节中屏蔽掉一些位,使用按位 AND 运算符& And in order to use that, a bit mask is needed.为了使用它,需要一个位掩码。 Such bit masks are best obtained by shifting the value 1 by the desired amount of bits.这种位掩码最好通过将值 1 移位所需的位数来获得。 Bit masks are perhaps most clearly expressed in hex and the possible bit masks for a byte will be (1<<0) == 0x01 , (1<<1) == 0x02 , (1<<3) == 0x04 , (1<<4) == 0x08 and so on.位掩码可能最清楚地以十六进制表示,一个字节的可能位掩码将是(1<<0) == 0x01 , (1<<1) == 0x02 , (1<<3) == 0x04 , (1<<4) == 0x08等等。

In this case (1<<1) == 0x02 .在这种情况下(1<<1) == 0x02

C code:代码:

uint8_t data[n];
...
size_t  byte_index = x / 8;
size_t  bit_index  = x % 8;
bool    is_bit_set;

is_bit_set = ( data[byte_index] & (1<<bit_index) ) != 0;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM