如何在2D数组中移位位

时间:2018-09-13 07:46:50

标签: c

让我们说我在c的部分代码中有这个2D数组:

unsigned short testing[5][3];

然后我将数据插入其中,并让我们对其进行监控

testing[0][0] = 00110010;
testing[0][1] = 01101001;
testing[0][2] = 11100001;

实际上,如果我们监视数组的第一个下标(使用调试工具进行监视)

testing[0] = 001100100110100111100001; /*which is combination of 3 second subscript of the array*/

问题是我如何才能将2D数组向左移一位

让我们说我希望得到这个输出

Original :
testing[0][0-2] = 001100100110100111100001;
The output I wish :
testing[0][0-2] = 011001001101001111000010;

我这样做的方法尚未完成,但我认为有另一种明智的方法可以在这里询问

for(int i = 0; i<5; i++)
{
    for(int j = 0; j < 3; j++)
    {
        testing[i][j] <<= 1; 
/*I believe here will cause the padding first bit disappear also*/
    }
}

如果是普通数组(或者可以说一维数组),我确实知道可以很容易地通过

int a[2];
a[0] <<= 1;

但是在2D数组中,任何人都可以提出建议,也许有一些简单的方法可以移动第一个下标的位?

要明确地说,我的问题是,是否可以移动2D数组的第一个下标

2 个答案:

答案 0 :(得分:0)

在澄清seconf索引可以大于4后进行编辑

void shiftleft(uint16_t *data, size_t nwords)
{
    data[nwords - 1] <<= 1;
    for(size_t index = nwords - 1; index > 0; index--)
    {
        uint32_t tmp;

        tmp = data[index - 1] << 1;
        data[index] |= !!(tmp & (1UL << 16));
        data[index - 1] = tmp & 0xffff;
    }
}

最初的问题是第二个索引是3,您可以使用位域/联合组合。

typedef union
{
    struct
    {
        uint64_t d48: 48;
        uint64_t : 16;
    };
    uint64_t d64;
    uint16_t d16[4];
}Data48;

void shiftleft(uint16_t *data)
{
    Data48 d48;
    d48.d16[0] = *data++;
    d48.d16[1] = *(data+1);
    d48.d16[2] = *(data+2);

    d48.d48 <<= 1;

    *data++ = d48.d16[0];
    *(data+1) = d48.d16[1];
    *(data+2) = d48.d16[2];
}

您只需将其更改为您的字节序

答案 1 :(得分:0)

作为开场白,我希望C支持8080 / Z80上存在的某些位操作,并且可能也可以在x86上使用。特别是,使用Z80来称呼RLC指令。

与OP问题相关的是RLC是专门为解决这一确切问题而设计的:移位/旋转多字节值。记住这一点,您可以使用C中可用的操作来实现相同的结果。这只是花了一点功夫。

void arrayshift(unsigned short *array, size_t elementCount)
{
    int carry = 0;
    size_t i;
    for (i = 0; i < elementCount; i++)
    {
        // This assumes 8 bit bytes and sizeof(short) == 2. Adjust as needed if this is not the case
        int newCarry = *array >> 15;
        *array = *array << 1 | carry;
        carry = newCarry;
        array++;
    }
}

总而言之,如果编译器支持它,并且愿意将可移植性抛诸脑后,则可以退回到汇编器并尝试使用目标CPU上可用的指令来有效地做到这一点。

这是一个决定,必须视具体情况而定,所以我仅将其列为可能的选择,而不是答案。