Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 数组中的位循环移位_C_Bit Manipulation - Fatal编程技术网

C 数组中的位循环移位

C 数组中的位循环移位,c,bit-manipulation,C,Bit Manipulation,我有一个总共36字节数据的uint8\ttypecast数组。我想在整个数组中循环移位位(右移)。 我该怎么做?例如: uint8_t arr[3] = {0x03, 0x44, 0x32} 一个班次后应为: arr[3] = {0x01, 0xa2, 0x19} 循环遍历数组的每个字节。对于每个字节,首先检查低位,如果已设置,则设置执行标志。然后可以将字节右移一位 对下一个字节重复上述操作,但首先将进位标志设置为进位标志的当前值。移位后,检查进位标志,如果已设置,则设置当前字节的高位。继续

我有一个总共36字节数据的
uint8\t
typecast数组。我想在整个数组中循环移位(右移)。 我该怎么做?例如:

uint8_t arr[3] = {0x03, 0x44, 0x32}
一个班次后应为:

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

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


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

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

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

    uint8_t circular_carry = (arr[N - 1] & 1) << 7;
    
    arr[0] >>= 1;
    arr[0] += circular_carry; 
    
  • 右移并将
    循环进位
    添加到第一个元素:

    uint8_t circular_carry = (arr[N - 1] & 1) << 7;
    
    arr[0] >>= 1;
    arr[0] += circular_carry; 
    

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

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 );
}
请注意,右移值时会丢失最低位。这就是为什么在操作之前,最低位将保存到
savedCarry


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

您知道如何进行非循环移位吗?为什么循环移位的结果会占用一个额外的字节?循环移位右键,也称为旋转右键,意味着序列中的最低位循环到最高有效位。使用单字节示例,将0x03向右旋转为0x81。其中,右移的相同值为0x01。你在想什么?@PeterCamilleri-我认为OP要求在整个阵列中旋转位。因此元素
n
的最低位成为元素
n+1
的最高位。最后一个元素的最低位变为第一个元素的最高位。可能需要解释如何使用C处理进位。事实上,你能假设有一个进位吗?@ScottHunter应该是“进位标志”。已编辑。将进位标志初始化为最后一个元素的低位,不需要在末尾返回。。。