【问题标题】:How to convert an array of bits to a char如何将位数组转换为字符
【发布时间】:2013-04-03 23:31:49
【问题描述】:

我正在尝试通过根据某些要求修改 LSB(最低有效位)来编辑缓冲区的每个字节。 我使用 unsigned char 类型作为字节,所以请让我知道 IF 正确/错误。

unsigned char buffer[MAXBUFFER];

接下来,我正在使用这个功能

char *uchartob(char s[9], unsigned char u)

修改第一个参数并将其作为位数组返回。这个函数工作得很好,因为数组中的位代表第二个参数。

麻烦从这里开始。我将指出我正在尝试做的事情一步一步,所以你们可以让我知道我在哪里走错了路。

我将上述函数(为缓冲区的每个元素调用)的结果保存在一个变量中

char binary_byte[9];             // array of bits

我正在测试 LSB,只是将它与上面的某个标志进行比较。

if (binary_byte[7]==bit_flag)     // i go on and modify it like this
binary_byte[7]=0;                // or 1, depending on the case

接下来,我正在尝试将位数组 binary_byte(它是位数组,不是吗?)重新转换为字节/无符号字符并更新同时缓存中的数据。我希望我说得足够清楚,因为我现在真的很困惑。

buffer[position_in_buffer]=binary_byte[0]<<7| // actualize the current BYTE in the buffer
                        binary_byte[1]<<6|
                        binary_byte[2]<<5|
                        binary_byte[3]<<4|
                        binary_byte[4]<<3|
                        binary_byte[5]<<2|
                        binary_byte[6]<<1|
                        binary_byte[7];

请记住,binary_byte[7] 位置的位可能会被修改,这就是所有这些的重点。

该解决方案不是很优雅,但它正在工作,即使我对我所做的事情真的很不安全(我尝试使用位运算符但没有成功)

奇怪的是当我试图从缓冲区打印更新的字符时。它与前一个字符具有相同的位,但它是一个完全不同的位。

我的最后一个问题是:只改变一个字节中的 LSB 有什么影响?我应该期待什么?。正如你所看到的,即使我不应该得到“新”字符,我也只会得到。

【问题讨论】:

  • 按位:设置位 => a |= 1 a &= ~(1 1 == a & (1
  • 您没有正确测试您的位。我不记得头顶上的位操作,但它与if (binary_byte[7] | bit_flag ==bit_flag)
  • 我会考虑在数组上使用std::bitset
  • 请把代码作为 1 块。我不明白。

标签: c++ visual-studio-2010 byte bit-manipulation unsigned


【解决方案1】:

按位:

设置位 => a |= 1 &lt;&lt; x;

复位位 => a &amp;= ~(1 &lt;&lt; x);

位校验 => a &amp; (1 &lt;&lt; x);

翻转位 => a ^= (1 &lt;&lt; x)

如果您无法管理,您可以随时使用std::bitset

帮助宏

#define SET_BIT(where, bit_number) ((where) |= 1 &lt;&lt; (bit_number))

#define RESET_BIT(where, bit_number) ((where) &amp;= ~(1 &lt;&lt; (bit_number)))

#define FLIP_BIT(where, bit_number) ((where) ^= 1 &lt;&lt; (bit_number))

#define GET_BIT_VALUE(where, bit_number) (((where) &amp; (1 &lt;&lt; (bit_number))) &gt;&gt; bit_number) //这将返回 0 或 1

帮助应用程序打印位

#include <iostream>
#include <cstdint>

#define GET_BIT_VALUE(where, bit_number) (((where) & (1 << (bit_number))) >> bit_number)

template<typename T>
void print_bits(T const& value)
{
    for(uint8_t bit_count = 0;
        bit_count < (sizeof(T)<<3);
        ++bit_count)
    {
        std::cout << GET_BIT_VALUE(value, bit_count) << std::endl;
    }
}

int main()
{
    unsigned int f = 8;
    print_bits(f);
}

【讨论】:

  • 位校验错误,应该是a &amp; (1 &lt;&lt; x),否则只适用于x == 0。
【解决方案2】:

所以我仍然有点不确定您要在这里完成什么,但由于您尝试修改字节的各个位,我建议使用以下数据结构:

union bit_byte
{
    struct{
        unsigned bit0 : 1;
        unsigned bit1 : 1;
        unsigned bit2 : 1;
        unsigned bit3 : 1;
        unsigned bit4 : 1;
        unsigned bit5 : 1;
        unsigned bit6 : 1;
        unsigned bit7 : 1;
    } bits;

    unsigned char all;
};

这将允许您访问字节的每一位并仍然获得字节表示。这里有一些快速示例代码:

bit_byte myValue;
myValue.bits.bit0 = 1;    // Set the LSB

// Test the LSB
if(myValue.bits.bit0 == 1) {
    myValue.bits.bit7 = 1;
}

printf("%i", myValue.all);

【讨论】:

  • * 位字段顺序取决于平台。
  • 是的。可以轻松修改实现以适应不同的字节序。
猜你喜欢
  • 2018-09-02
  • 2019-05-11
  • 2021-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多