Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.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 如何将32位数组元素压缩为所需的最小位元素?_C_Arrays_Compression - Fatal编程技术网

C 如何将32位数组元素压缩为所需的最小位元素?

C 如何将32位数组元素压缩为所需的最小位元素?,c,arrays,compression,C,Arrays,Compression,假设我有一个如下所示的输入数组 int input_arr[100] = {10,20,1255,1200,50,55,1,5,6,1000}; 在这里存储数组的每个元素需要32位,即使数组元素的值非常小,即1255是数组中的最大元素,并且存储该元素只需要11位,这意味着在11位中,我可以适应数组的所有其他元素 因此,我的任务是将数组的32位元素压缩为11位数组元素?预期的压缩数组如下所示 int output_arr[] = {00000001010 00000010100 .... 100

假设我有一个如下所示的输入数组

int input_arr[100] = {10,20,1255,1200,50,55,1,5,6,1000};
在这里存储数组的每个元素需要
32
位,即使数组元素的值非常小,即
1255
是数组中的最大元素,并且存储该元素只需要
11位
,这意味着在
11位
中,我可以适应数组的所有其他元素

因此,我的任务是将数组的
32位元素
压缩为
11位数组元素
?预期的压缩数组如下所示

int output_arr[] = {00000001010 00000010100 .... 10011111111 ... }
                        |             |               |
                   11 bits(1)    11 bits(2)     11 bits( 1255)
为了完成上述任务,我所做的就是在这里

  • 查找给定数组中的
    最大
    元素
  • 查找存储
    最大元素所需的
    位(上一步)
  • 查找存储
    位数所需的
    字节
    ,例如存储
    11
    位,我需要等效的
    2字节
    (在下面的代码
    新大小中包含此项)这是我需要你的帮助。这是我的经理告诉我的内存浪费,因为要存储
    11
    位,我的
    new\u大小
    2字节
    ,即
    5位仍然是额外的或浪费的。我怎样才能避免这种情况
这是我试过的

int my_pow(int input_num,int p) {
        int temp = 1;
        for(int iter = 0;iter < p; iter++) {
                temp = temp * input_num;
        }
        return temp;
}
int main() {
        #if 0
        int input_array[53069] = {1,2,2,3,4,1,2,4,6,1255,1,2,5,1233};
        #endif
        int input_array[] = {1,2,3,4,6,1255,1,2,5,1233};

        int max = input_array[0], ele = sizeof(input_array)/sizeof(input_array[0]);
        /* finding max elements in a array */
        for(int i = 0;i < ele; i++) {
                if(input_array[i] > max) {
                        max = input_array[i];
                }
        }
        /* finding no of bits required to store highest elements of array */
        int bit_required = 0;
        while(1) {
                if(max < my_pow(2,bit_required))
                        break;
                bit_required+=1;
        }
        /* when above loop fails bit_required is nothing 
           but no of bit required to store the highest element of array */

        /* finding size of new/compressed array */
        int new_size = 0;
        if(bit_required % 8 == 0) {
                new_size = bit_required/8;
        }
        else {
                new_size = (bit_required/8) + 1;
        }
        /* construct the new array again */
        typedef struct array_task {
                unsigned char new_array[new_size];/* in each cmp_arr, can store new_size char
                                                     now for each B[] I'm not using 32 bits , its new_size bits */
        }cmp_arr;/* creating new array of ele elements */
        cmp_arr cmpressed[ele];
        /* store elements of input_array[] into output_array[] */
        for(int row = 0 ; row < ele ;row++) {
                for(int col = bit_required - 1; col >= 0; col-- ) {
                        cmpressed[row].new_array[col] = ((input_array[row] >> col & 1) + 48) ;
                        printf("%d",(cmpressed[row].new_array[col]) - 48);
                }
                printf("\n");
        }
        #if 0
        printf("Size of A before %d\n",sizeof(input_array)); /* 40 bytes */
        printf("size of compressed array %d\n",sizeof(cmp_arr));/* same task, it perform in 2 bytes, 
                                                                each elements won't take 32 bits  */
        #endif
        return 0;
}
int my_pow(int input_num,int p){
内部温度=1;
对于(int-iter=0;itermax){
max=输入_数组[i];
}
}
/*查找存储数组最高元素所需的位的数目*/
int bit_required=0;
而(1){
如果(最大值<我的功率(需要2位))
打破
所需位_+=1;
}
/*当上述循环失败时,不需要位_
但存储数组的最高元素不需要任何位*/
/*查找新/压缩数组的大小*/
int new_size=0;
如果(需要位_%8==0){
新尺寸=所需位/8;
}
否则{
新的_大小=(需要位_/8)+1;
}
/*重新构造新数组*/
类型定义结构数组任务{
无符号字符new_数组[new_size];/*在每个cmp_arr中,可以存储新的_size字符
现在,对于每个B[]我没有使用32位,它是新的大小位*/
}cmp_arr;/*创建新的元素数组*/
cmp_arr cmpressed[ele];
/*将输入_数组[]的元素存储到输出_数组[]*/
for(int行=0;行=0;col--){
cmpressed[row]。新建_数组[col]=((输入_数组[row]>>col&1)+48);
printf(“%d”,(cmpressed[row].new_数组[col])-48);
}
printf(“\n”);
}
#如果0
printf(“在%d\n之前的大小”,sizeof(输入数组));/*40字节*/
printf(“压缩数组的大小%d\n”,sizeof(cmp_arr));/*同一任务,它用2个字节执行,
每个元素不会占用32位*/
#恩迪夫
返回0;
}

有没有其他方法可以有效地完成同样的任务?所有的建议都是最受欢迎的?

我觉得“有趣”的另一种方法是分配一个字符数组,并对符合最大值的类型执行强制转换。大概是这样的:

NumBytesMaxValue = ...;
void* pointers = malloc(NumBytesMaxValue * NumValues);

if (NumBytesMaxValue == 1)
  cast_pointer_to_char_and_fill_it();
else if (NumBytesMaxValue == 2)
  cast_pointer_to_short_and_fill_it();
...

数据压缩是一个庞大的课题,一个活跃的研究领域。。。压缩数据可以通过许多不同的方式来完成,从而使其脱离主题

但是,可以通过实用程序或初步阶段找到阵列的最小类型:

#include <limits.h>
#include <stdio.h>

int main() {
    int input_array[] = { 1, 2, 2, 3, 4, 1, 2, 4, 6, 1255, 1, 2, 5, 1233 };
    size_t i, count = sizeof(input_array) / sizeof(input_array[0]);
    int min, max;
    int nc = 0;
    min = max = input_array[0];
    for (i = 1; i < count; i++) {
        if (min > input_array[i]) min = intput_array[i];
        if (max < input_array[i]) max = intput_array[i];
    }
    printf("min value is %d, max value is %d\n", min, max);
    if (min >= SCHAR_MIN && max <= SCHAR_MAX)
        nc += printf("type signed char is appropriate\n");
    if (min >= 0 && max <= UCHAR_MAX)
        nc += printf("type unsigned char is appropriate\n");
    if (min >= SHRT_MIN && max <= SHRT_MAX)
        nc += printf("type short is appropriate\n");
    if (min >= 0 && max <= USHRT_MAX)
        nc += printf("type unsigned short is appropriate\n");
    if (nc == 0)
        printf("no type smaller than int is appropriate\n");
    return 0;
}
#包括
#包括
int main(){
int-input_数组[]={1,2,2,3,4,1,2,4,6,1255,1,2,5,1233};
size\u ti,count=sizeof(输入数组)/sizeof(输入数组[0]);
最小整数,最大整数;
int nc=0;
最小=最大=输入_数组[0];
对于(i=1;iinput_数组[i])min=input_数组[i];
if(max如果(min>=SCHAR\u min&&max=0&&max=SHRT\u min&&max=0&&max要将值移位11位,而不是8位,16位或32位,则需要对位进行操作。您基本上必须在一个(比如32位)整数数组中模拟一个位数组。在这种情况下,如果一个值存储在位偏移量X处,它将是(可能的)存储在数组中索引X/32和X/32+1的某个位置(如果它跨越32位边界)。每次必须在数组中设置一个值时,都必须加载这两个值并将数字“放”在那里。实现有点技术性,请尝试以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#define MASK32 ((uint64_t)0xffffffff)

void setValue(uint32_t *a, int bits, int i, int n) {
    int bitoffset = i * bits;
    int index = bitoffset / 32;
    int shift = bitoffset % 32;
    uint64_t maskbits = (~(uint64_t)0) >> (64-bits);
    uint64_t val = ((uint64_t)a[index+1]<<32) + a[index];
    val = val & ~(maskbits << shift) | ((n & maskbits) << shift);
    a[index] = (val & MASK32);
    a[index+1] = (val >> 32) & MASK32;
}

int getValue(const uint32_t *a, int bits, int i) {
    int bitoffset = i * bits;
    int index = bitoffset / 32;
    int shift = bitoffset % 32;
    uint64_t maskbits = (~(uint64_t)0) >> (64-bits);
    int val = ((((uint64_t)a[index+1]<<32) + a[index]) >> shift) & maskbits;
    return(val);
}

int input_arr[100] = {10,20,1255,1200,50,55,1,5,6,1000};

int main() {
    int        i, j;
    uint32_t   a[100*11/32+2];

    for(i=0; i<100; i++) setValue(a,11,i,input_arr[i]);
    for(j=0; j<100; j++) printf("a[%d/11] == %d\n", j, getValue(a,11,j));
}
#包括
#包括
#包括
#定义掩码32((uint64_t)0xffffffff)
无效设置值(uint32_t*a,整数位,整数i,整数n){
int bit offset=i*位;
int索引=位偏移量/32;
int shift=位偏移量%32;
uint64掩码位=(~(uint64)0)>>(64位);
uint64_t val=((uint64_t)a[索引+1](64位);
int val=((uint64_t)a[index+1]移位)和maskbits;
返回(val);
}
int input_arr[100]={10,2012551200,50,55,1,5,61000};
int main(){
int i,j;
uint32_t a[100*11/32+2];

对于(i=0;iThanks.In
cast\u pointer\u to\u char\u and\u fill\u it()
我可以填充值,但有多少位?我想可能仍然有一些
未使用的位
为什么不能有
变量