1

我无法猜测如何解决以下问题。假设我有一个字符串或整数类型变量的数组(uchar、char、整数等)。这些数据类型中的每一个都是 1 字节长或更长。

我想从这样的数组中读取,但读取小于 1 字节的片段,例如 3 位(值 0-7)。我试着做一个像

cout << ( (tab[index] >> lshift & lmask) | (tab[index+offset] >> rshift & rmask)  );

但是猜测如何设置这些变量是我无法企及的。解决此类问题的方法是什么?

抱歉,如果有人问过问题,但搜索没有答案。

4

3 回答 3

1

我确信这不是最好的解决方案,因为可以消除代码中的一些低效率,但我认为这个想法是可行的。我只是简单地测试了一下:

void bits(uint8_t * src, int arrayLength, int nBitCount) {
   int idxByte = 0;      // byte index
   int idxBitsShift = 7; // bit index: start at the high bit
   // walk through the array, computing bit sets
   while (idxByte < arrayLength) {
       // compute a single bit set
       int nValue = 0;
       for (int i=2; i>=0; i--) {
        nValue += (src[idxByte] & (1<<idxBitsShift)) >> (idxBitsShift-i);
        if ((--idxBitsShift) < 0) {
            idxBitsShift=8;
            if (++idxByte >= arrayLength) 
                break;
        }
       }
       // print it
       printf("%d ", nValue);
   }

}

int main() {
    uint8_t a[] = {0xFF, 0x80, 0x04};
    bits(a, 3, 3);
}

跨字节边界收集位的事情有点像 PITA,所以我一次做一点,然后将这些位一起收集到nValue. 您可以拥有更智能的代码,一次执行这三个(或多个)位,但就我而言,对于这样的问题,通常最好从一个简单的解决方案开始(除非您已经知道如何做更好的一个)然后做一些更复杂的事情。

于 2013-04-01T00:40:37.390 回答
0

简而言之,数据在内存中的排列方式严格取决于:

  • 端倪_
  • 用于计算/表示的标准(通常是IEEE 754
  • 给定变量的类型

现在,您不能在不破坏其自身含义的情况下以这种基本原理“分解”数据结构,简单地说,如果您要将变量细分为“位域”,那么您只是在描绘一个未定义的值。

在计算机科学中,数据结构或信息以块的形式结构化,就像许多散列算法/散列结果一样,但数值不是这样存储的,你应该知道你在做什么来防止任何数据丢失。

另一件需要注意的事情是,您对“小于 1 字节的片段”的定义没有多大意义,它也非常具有侵入性,您在这里失去了抽象,您也可以做一些坏事。

于 2013-03-31T23:59:26.400 回答
0

这是我能想到的设置变量的各个位的最佳方法:假设我们需要将 variable1(char 或其他字节长变量)的前四位设置为 1010

variable1 &= 0b00001111; //Zero the first four bytes
variable1 |= 0b10100000; //Set them to 1010, its important that any unaffected bits be zero

这可以扩展到所需的任何位,方法是在与您希望设置的位相对应的第一个数字中放置零(在示例的情况下为前四个),并在与您希望保留的位相对应的第二个数字中放置零第二个数字中性(示例中的最后四个)。第二个数字也可以通过将您想要的值移位适当数量的位置(在示例的情况下为四个)来导出。

根据您的评论,可以进行如下修改以适应增加的可变性:

对于此操作,假设您希望能够修改非起始位和非结束位,我们将需要两个班次。在这种情况下有两组位,第一组(从左起)不受影响的位和第二组。如果您希望修改从左侧跳过第一位的四位(将这四个位111 用于单个字节),则第一个移位将是 7,第二个移位将是 5。

variable1 &= ( ( 0b11111111 << shift1 ) | 0b11111111 >> shift2 );

接下来,我们希望分配的值需要进行移位和或运算。但是,我们需要第三次移位来说明我们要设置多少位。这种转变(我们称之为shift3shift1减去我们希望修改的位数(如前所述 4)。

variable1 |= ( value << shift3 );
于 2013-04-01T00:00:48.870 回答