阵列中的逐位循环移位

时间:2016-12-12 20:28:55

标签: c bit-manipulation

我有一个总共36个字节数据的uint8_t类型转换数组。我想循环移动整个数组(右移)。 我怎样才能做到这一点?例如:

uint8_t arr[3] = {0x03, 0x44, 0x32}

一班后应该是:

arr[3] = {0x01, 0xa2, 0x19}

3 个答案:

答案 0 :(得分:1)

循环遍历数组的每个字节。对于每个字节,首先检查低位,如果已设置,则设置进位标志。然后你可以将字节向右移动。

对下一个字节重复上述操作,但首先将进位标志设置为进位标志的当前值。移位后,检查进位标志,如果已设置,则设置当前字节的高位。继续前进,直到你到达阵列的末尾。如果在结尾设置了进位标志,则设置第一个字节的高位。

答案 1 :(得分:1)

假设数组索引从0变为N - 1,一种方法是:

  • 保存最后一个元素的最后一位。这将用于循环添加为第一个元素的进位:

    uint8_t circular_carry = (arr[N - 1] & 1) << 7;
    
  • 对于从iN - 1的每个元素1,右移元素(arr[i] >> 1),并将前一个元素的最低位设置为最高(即第8位)((arr[i - 1] & 1) << 7):

    int i;
    for(i = N - 1; i > 0; i--) {
        arr[i] >>= 1;                     // Right shift the (i)th byte
        arr[i] |= (arr[i - 1] & 1) << 7;  // Carry from the previous digit 
    }
    
  • 右移并将circular_carry添加到第一个元素:

    arr[0] >>= 1;
    arr[0] += circular_carry; 
    

答案 2 :(得分:0)

您可以使用以下代码循环移位数组。它的评论几乎是不言自明的。

int main()
{
    uint8_t arr[3] = {0x03, 0x44, 0x32};


    int i,
        l;


    uint8_t savedCarry,
            carry;


    // let `l` be the size (nr. of elements) of the array

    l = 3;


    // this will cause the array bit shift to be circular
    // by taking the "carry" bit (lowest bit) from the last element of the array
    // this "carry" bit will be used on the first element in the `for` loop

    carry = arr[ l - 1 ] & 1;


    // loop trought the array applying bit shift

    for( i = 0; i < 3; i++)
    {
        savedCarry = arr[i] & 1;        // save the lowest bit  
        arr[i] = arr[i] >> 1;           // right shift
        if( carry )
        {
            arr[i] |= (uint8_t) 0x80;   // the lowest bit of the previuos element becomes the highest bit of the current one
        }
        carry = savedCarry;             // the lowest bit of this element will become the highest of the next one
    }


    // display hex output

    for( i = 0; i < 3; i++)
    {
        printf( "0x%02x\n", arr[i] );
    }

    return( 0 );
}

将输出

0x01
0xa2
0x19

请注意,当你右移一个值时,你会失去最低位。这就是为什么在操作之前将最低位保存到savedCarry

在每个for迭代结束之前,savedCarry将被复制到carry,它将在下一个数组值上设置最高位(在下一次迭代中)。