C 有效的整数数组位移位?

C 有效的整数数组位移位?,c,arrays,bit-manipulation,bit-shift,C,Arrays,Bit Manipulation,Bit Shift,为了在同一页上,我们假设sizeof(int)=4,sizeof(long)=8 给定一个整数数组,什么是将数组逻辑位移到左侧或右侧的有效方法 我正在考虑一个辅助变量,比如long,它将计算第一对元素(索引0和1)的位移位,并设置第一个元素(0)。以这种方式继续,元素(索引1和2)的位移位将在计算机上进行,然后设置索引1 我认为这实际上是一个相当有效的方法,但也有缺点。我不能进行大于32位的位移位。我认为使用多个辅助变量是可行的,但我设想在这条线上的某个地方使用递归。看看它,它在内部将数据存储为

为了在同一页上,我们假设sizeof(int)=4,sizeof(long)=8

给定一个整数数组,什么是将数组逻辑位移到左侧或右侧的有效方法

我正在考虑一个辅助变量,比如long,它将计算第一对元素(索引0和1)的位移位,并设置第一个元素(0)。以这种方式继续,元素(索引1和2)的位移位将在计算机上进行,然后设置索引1


我认为这实际上是一个相当有效的方法,但也有缺点。我不能进行大于32位的位移位。我认为使用多个辅助变量是可行的,但我设想在这条线上的某个地方使用递归。

看看它,它在内部将数据存储为字节数组。具体来说,您可以签出函数leftShift()。语法与C中的相同,因此编写一对这样的函数不会太困难。还要考虑到,当涉及到位移位时,您可以利用C中的非单类型。这意味着在Java中,为了安全地移位数据而不与符号混淆,您通常需要更大的类型来保存数据(例如,一个int来移位一个短的,一个long来移位一个int,…)没有必要使用
长的
作为中介。如果要向左换档,从最高的整数开始,向右换档从最低的整数开始。在修改相邻图元之前,添加相邻图元的进位

void ShiftLeftByOne(int * arr, int len)
{
    int i;
    for (i = 0;  i < len - 1;  ++i)
    {
        arr[i] = (arr[i] << 1) | ((arr[i+1] >> 31) & 1);
    }
    arr[len-1] = arr[len-1] << 1;
}
void ShiftLeftByOne(int*arr,int len)
{
int i;
对于(i=0;i31&1);
}

arr[len-1]=arr[len-1]对于任何其他人来说,这是一个更通用的版本,适用于任何位数和任何类型的数组:

/* This function shifts an array of byte of size len by shft number of
bits to the left. Assumes array is big endian. */

#define ARR_TYPE uint8_t

void ShiftLeft(ARR_TYPE * arr_out, ARR_TYPE * arr_in, int arr_len, int shft)
{
    const int int_n_bits = sizeof(ARR_TYPE) * 8;
    int msb_shifts = shft % int_n_bits;
    int lsb_shifts = int_n_bits - msb_shifts;
    int byte_shft = shft / int_n_bits;
    int last_byt = arr_len - byte_shft - 1;
    for (int i = 0;  i < arr_len;  i++){
        if (i <= last_byt){
            int msb_idx = i + byte_shft;
            arr_out[i] = arr_in[msb_idx] << msb_shifts;
            if (i != last_byt)
                arr_out[i] |= arr_in[msb_idx + 1] >> lsb_shifts;
        }
        else arr_out[i] = 0;
    }
}
/*此函数将大小为len的字节数组移位shft个数
左边的位。假设数组是大端数*/
#定义ARR_类型uint8_t
无效移位(ARR_类型*ARR_out,ARR_类型*ARR_in,int ARR_len,int shft)
{
常量int\u n\u位=sizeof(ARR\u类型)*8;
int msb_shift=shft%int_n_位;
int lsb_移位=int_n_位-msb_移位;
int byte_shft=shft/int_n_位;
int last_byt=arr_len-byte_shft-1;
对于(int i=0;i
@nn-这里有点不清楚您要找的是什么。您想对移位和丢失的数据做什么?您想对数据进行逻辑移位还是算术移位?还是只是在随机读取一组二进制数据位之后?例如,从100字节二进制dat的第27位到第59位读取一个4字节int流?@ChrisBD:抱歉,问得好。逻辑移位。我实际上是在处理一个大整数,它表示为一个整数数组,其中每个整数对应于基数2^(sizeof(int)*8)中的一个数字=2^32.我一直在寻找一些复杂的引用,但我没有看到任何技巧,我想显而易见的方法是唯一的方法:-/你能澄清从何处开始移位吗?你说使用最高阶int开始向左移位。但是在你的代码片段中,似乎你是从最低阶int开始移位的。同样打开左移一,什么是(&1)指示?谢谢。对不起,我对你说了大端。你是对的,数组顺序是倒序的。去掉一个位的&1掩码;要得到2位将是&3,4位将是&0xf,7位将是&0x3f等等。呃,对不起,我的意思是说,去掉位意味着什么?它是说,移位后,去掉重要的位,即(32-1)位?我认为移位33不起作用,因为假设长度=4,在for循环中,首先设置arr[0],然后设置arr[1],此时I=4-2,所以我们从不将arr[2]设置为任何值,然后arr[3]得到0'd。
/* This function shifts an array of byte of size len by shft number of
bits to the left. Assumes array is big endian. */

#define ARR_TYPE uint8_t

void ShiftLeft(ARR_TYPE * arr_out, ARR_TYPE * arr_in, int arr_len, int shft)
{
    const int int_n_bits = sizeof(ARR_TYPE) * 8;
    int msb_shifts = shft % int_n_bits;
    int lsb_shifts = int_n_bits - msb_shifts;
    int byte_shft = shft / int_n_bits;
    int last_byt = arr_len - byte_shft - 1;
    for (int i = 0;  i < arr_len;  i++){
        if (i <= last_byt){
            int msb_idx = i + byte_shft;
            arr_out[i] = arr_in[msb_idx] << msb_shifts;
            if (i != last_byt)
                arr_out[i] |= arr_in[msb_idx + 1] >> lsb_shifts;
        }
        else arr_out[i] = 0;
    }
}