以不同的字节c c ++写入位

时间:2014-03-20 21:06:07

标签: c++ c bit

我声明了一个字节数组:

uint8_t memory[123];

我已经填写:

memory[0]=0xFF;
memory[1]=0x00;
memory[2]=0xFF;
memory[3]=0x00;
memory[4]=0xFF;

现在我收到用户写入某些位的请求。例如,用户提供起始位(例如:10),位数(例如:9)和要设置的位。在我提供的示例中,我将收到2个字节:

setbit[0]=0b11110010;
setbit[1]=0b00000001; //padded with zeros for extra bits

这将用于Modbus,这是一个大端协议。我想出了以下代码:

for(int j=findByteINIT;j<(findByteFINAL);j++){

   aux[0]=(unsigned char) (setbit[j]>>(startingbit-(8*findByteINIT)));
   aux[1]=(unsigned char) (setbit[j+1]<<(startingbit-(8*findByteINIT)));

   memory[j]=(unsigned char) (aux[0] & memory[j] );
   memory[j+1]=(unsigned char) (aux[1] & memory[j+1] );


   aux[0]=0x00;//clean aux
   aux[1]=0x00;

        }

哪个不起作用但应该接近理想的解决方案。有什么建议吗?

3 个答案:

答案 0 :(得分:0)

您可以使用这些宏。

#define ISBITARRAYSET(b,arr)      (((arr)[(b)/8]&(1<<((b)%8)))==0?FALSE:TRUE)
#define ISBITARRAYCLR(b,arr)      (((arr)[(b)/8]&(1<<((b)%8)))==0?TRUE:FALSE)
#define SETBITARRAY(b,arr)        ((arr)[(b)/8]|= (1<<((b)%8)))
#define CLRBITARRAY(b,arr)        ((arr)[(b)/8]&= ~(1<<((b)%8)))

示例:

#define BIT10 0x0A;

    if( ISBITARRAYCLR(BIT10,myarray) )
    {
        SETBITARRAY(BIT10,myarray);
    }

问候。

答案 1 :(得分:0)

应该接近理想的解决方案,但

1)可能你想向左移动,然后向左移位

aux[0] = setbit[j] << (startingbit-(8*findByteINIT))
aux[1] = setbit[j] >> (8 - (startingbit-(8*findByteINIT)))

如果startbit为10,我怀疑findByteINIT会变为1,所以

startingbit-(8*findByteINIT)     ==  2
0b11110010 << 2    ==   0b11001000

和aux [1]:

8 - (startingbit-(8*findByteINIT))     ==  6
0b11110010 >> 6    ===  0b00000011

与findByteINIT跳过的8位:

   aux[1]    aux[0]   skipped
0b 000000011 11001000 00000000 
                  ^  11110010 starting at bit 10 

2)0b前缀不是标准的,它不是很便携

3)如果您想设置位,请使用或代替和。

  memory[j]=(unsigned char) (aux[0] | memory[j] );
  // (aux[0] & memory[j] )  just clears the bits of memory[j] not set in aux[0]
  // also, shorter form:
  memory[j] |= aux[0];

答案 2 :(得分:0)

我认为这应该有效。但是我只是轻轻地测试了它。

  int start_bit = 10; int bit_count = 9;
  uint8_t setbit[2] = { 0b11110010, 0b00000001 };

  int setbit_size = (bit_count + (CHAR_BIT - 1)) / CHAR_BIT;

  int start_byte = start_bit / CHAR_BIT;
  int shift = start_bit % CHAR_BIT;
  int modified_bytes =
      bit_count ? (bit_count + shift + (CHAR_BIT - 1)) / CHAR_BIT : 0;

  for (int i = 0; i < modified_bytes; ++i) {
    uint8_t mask = 0xFF;
    if (i == 0) {
      mask <<= shift;
    } else if (i == modified_bytes - 1) {
      mask >>= CHAR_BIT - (bit_count + shift) % CHAR_BIT;
    }

    uint8_t carried = i > 0 ? (setbit[i - 1] >> (CHAR_BIT - shift)) : 0;
    uint8_t added = i < setbit_size ? static_cast<uint8_t>(setbit[i] << shift) : 0;
    memory[start_byte + i] =
        (memory[start_byte + i] & ~mask) | ((carried | added) & mask);
  }