将数组连接到位
concatenate array to bits
如何将低密度数组 data
的 1 和 0 连接成一个更小、更密集的数组 c
uint8_t data[16] = {1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1};
uint8_t c[2] = {0};
/* desired result
c[0] = 11011011
c[1] = 10001101
*/
我在这里有点挣扎,到目前为止,我已经得到了它,但它似乎没有像我预期的那样工作:
static void compress(unsigned char *out, unsigned char *in, int length)
{
for(int i=0; i<length; i++)
{
if((i+1)%9==0)
out++;
*out |= in[i]<<((length-i)%9);
}
}
int main(){
compress(c,data,16);
printf("%d",c[0]); //should be 219
printf("%d",c[1]); //should be 177 (edit)
}
谢谢你帮助我!
在您的代码中添加一行 printf ("%d %d\n", i,(length-i)%9 );
,您就会看到问题出在哪里。
不使用取模运算,添加保存移位数的变量(初始值为7),当它为负时重新设置:
static void compress2(unsigned char *out, unsigned char *in, int length)
{
int shift = 7;
for(int i=0; i<length; i++)
{
*out |= in[i] << shift;
if (--shift < 0)
{
++out;
shift = 7;
}
}
}
unit8_t 的大小只有 8 位,而不是 9 位。所以从根本上说,错误在 %9 而不是 %8。
您可以使用单独的计数器 (b) 来计算从 7 到 0 的位移量。一旦达到 -1,就前进。从 (length-1) 开始,因为对于长度 1,您希望它是最低位,即移位量为 0.
static void compress(unsigned char *out, unsigned char *in, int length)
{
for(int* p=in, int b=(length-1)%8; p<in+length; p++, b--)
{
if(b < 0)
{
out++;
b = 7;
}
*out |= *p << b;
}
}
你也可以使用 out[(length-i-1) / 8] |= in[i] << (length-i-1) % 8
P.S。位顺序取决于平台...
static void compress(uint8_t *out, uint8_t *in, size_t length)
{
memset(out, 0, length >> 3 + !!(length & 7));
for(size_t i = 0; i < length; i++)
{
out[i >> 3] |= (in[i] << (7 - (i & 7)));
//out[i >> 3] |= ((!!in[i]) << (7 - (i & 7))); - if array elements may be not only 0 or 1.
}
}
int main()
{
uint8_t data[16] = {1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1};
uint8_t c[sizeof(data) >> 3 + !!(sizeof(data) & 7)];
compress(c,data,16);
printf("%d\n",c[0]); //should be 219
printf("%d\n",c[1]); //should be 141
}
如何将低密度数组 data
的 1 和 0 连接成一个更小、更密集的数组 c
uint8_t data[16] = {1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1};
uint8_t c[2] = {0};
/* desired result
c[0] = 11011011
c[1] = 10001101
*/
我在这里有点挣扎,到目前为止,我已经得到了它,但它似乎没有像我预期的那样工作:
static void compress(unsigned char *out, unsigned char *in, int length)
{
for(int i=0; i<length; i++)
{
if((i+1)%9==0)
out++;
*out |= in[i]<<((length-i)%9);
}
}
int main(){
compress(c,data,16);
printf("%d",c[0]); //should be 219
printf("%d",c[1]); //should be 177 (edit)
}
谢谢你帮助我!
在您的代码中添加一行 printf ("%d %d\n", i,(length-i)%9 );
,您就会看到问题出在哪里。
不使用取模运算,添加保存移位数的变量(初始值为7),当它为负时重新设置:
static void compress2(unsigned char *out, unsigned char *in, int length)
{
int shift = 7;
for(int i=0; i<length; i++)
{
*out |= in[i] << shift;
if (--shift < 0)
{
++out;
shift = 7;
}
}
}
unit8_t 的大小只有 8 位,而不是 9 位。所以从根本上说,错误在 %9 而不是 %8。
您可以使用单独的计数器 (b) 来计算从 7 到 0 的位移量。一旦达到 -1,就前进。从 (length-1) 开始,因为对于长度 1,您希望它是最低位,即移位量为 0.
static void compress(unsigned char *out, unsigned char *in, int length)
{
for(int* p=in, int b=(length-1)%8; p<in+length; p++, b--)
{
if(b < 0)
{
out++;
b = 7;
}
*out |= *p << b;
}
}
你也可以使用 out[(length-i-1) / 8] |= in[i] << (length-i-1) % 8
P.S。位顺序取决于平台...
static void compress(uint8_t *out, uint8_t *in, size_t length)
{
memset(out, 0, length >> 3 + !!(length & 7));
for(size_t i = 0; i < length; i++)
{
out[i >> 3] |= (in[i] << (7 - (i & 7)));
//out[i >> 3] |= ((!!in[i]) << (7 - (i & 7))); - if array elements may be not only 0 or 1.
}
}
int main()
{
uint8_t data[16] = {1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1};
uint8_t c[sizeof(data) >> 3 + !!(sizeof(data) & 7)];
compress(c,data,16);
printf("%d\n",c[0]); //should be 219
printf("%d\n",c[1]); //should be 141
}