gpt4 book ai didi

c - 有什么比这更好的将 4 个字节打包成 3 个字节的方法?

转载 作者:太空狗 更新时间:2023-10-29 15:21:03 25 4
gpt4 key购买 nike

我有一个 0 - 63 范围内的值数组,并决定我可以将每 4 个字节打包成 3 个,因为这些值只需要 6 位,我可以使用额外的 2 位来存储数组的前 2 位下一个值等等。

在我使用 switch 语句和 nextbit 变量(类似设备的状态机)进行打包并跟踪起始位之前,我从未这样做过。不过,我相信一定有更好的方法。

请提供建议/线索,但不要破坏我的乐趣 ;-)

关于大端/小端的任何可移植性问题?

顺便说一句:我已通过再次解压缩并与输入进行比较来验证此代码是否有效。不,这不是家庭作业,只是我给自己设置的练习。

/* build with gcc -std=c99 -Wconversion */
#define ASZ 400
typedef unsigned char uc_;
uc_ data[ASZ];
int i;
for (i = 0; i < ASZ; ++i) {
data[i] = (uc_)(i % 0x40);
}
size_t dl = sizeof(data);
printf("sizeof(data):%z\n",dl);
float fpl = ((float)dl / 4.0f) * 3.0f;
size_t pl = (size_t)(fpl > (float)((int)fpl) ? fpl + 1 : fpl);
printf("length of packed data:%z\n",pl);

for (i = 0; i < dl; ++i)
printf("%02d ", data[i]);
printf("\n");

uc_ * packeddata = calloc(pl, sizeof(uc_));
uc_ * byte = packeddata;
uc_ nextbit = 1;
for (int i = 0; i < dl; ++i) {
uc_ m = (uc_)(data[i] & 0x3f);
switch(nextbit) {
case 1:
/* all 6 bits of m into first 6 bits of byte: */
*byte = m;
nextbit = 7;
break;
case 3:
/* all 6 bits of m into last 6 bits of byte: */
*byte++ = (uc_)(*byte | (m << 2));
nextbit = 1;
break;
case 5:
/* 1st 4 bits of m into last 4 bits of byte: */
*byte++ = (uc_)(*byte | ((m & 0x0f) << 4));
/* 5th and 6th bits of m into 1st and 2nd bits of byte: */
*byte = (uc_)(*byte | ((m & 0x30) >> 4));
nextbit = 3;
break;
case 7:
/* 1st 2 bits of m into last 2 bits of byte: */
*byte++ = (uc_)(*byte | ((m & 0x03) << 6));
/* next (last) 4 bits of m into 1st 4 bits of byte: */
*byte = (uc_)((m & 0x3c) >> 2);
nextbit = 5;
break;
}
}

最佳答案

所以,这有点像 code-golf ,对吧?


#include <stdlib.h>
#include <string.h>

static void pack2(unsigned char *r, unsigned char *n) {
unsigned v = n[0] + (n[1] << 6) + (n[2] << 12) + (n[3] << 18);
*r++ = v;
*r++ = v >> 8;
*r++ = v >> 16;
}

unsigned char *apack(const unsigned char *s, int len) {
unsigned char *s_end = s + len,
*r, *result = malloc(len/4*3+3),
lastones[4] = { 0 };
if (result == NULL)
return NULL;
for(r = result; s + 4 <= s_end; s += 4, r += 3)
pack2(r, s);
memcpy(lastones, s, s_end - s);
pack2(r, lastones);
return result;
}

关于c - 有什么比这更好的将 4 个字节打包成 3 个字节的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1664563/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com