user-0 提问: 关于bit操作的问题（数据压缩）

回复:
user: user-1
content: 一般使用硬件解决，线路传输方案中有专用的系统解决方案。

user: user-0
content: 引用 13 楼 lin5161678 的回复:[quote=引用 12 楼 早打大打打核战争 的回复:] 实际上楼主这个压缩没有多少意义，不如把数据用zlib之类的压缩再传输 同意  我也是这样想的 昨天 楼主C语言贴吧也发过同一个问题的帖子 当时我就对他说 现成的压缩算法挑一个 [/quote]  我其实是用过数据压缩算法，一次压缩后才产生了这个14bit的东东。看了下大家的回复，也没什么好的方法，最后写的代码也只能是移位加填充这么搞定了。

user: user-2
content: 引用 7 楼 幻夢之葉 的回复:[quote=引用 6 楼 幻夢之葉 的回复:] 位移+位或就处理完了啊 short src[4] unsigned long long dst = 0; dst |= ((unsigned long long)src[0] << 0); dst |= ((unsigned long long)src[1] << 14); dst |= ((unsigned long long)src[2] << 28); dst |= ((unsigned long long)src[3] << 42);  其中dst有一个字节的内容可能是随变的，是否要处理掉看你实际流程 上面的有问题，应该是这样子才对，并且忽略红色标注那句话 short src[4] unsigned long long dst = 0; dst |= ((unsigned long long)src[0] & 3FFF) << 0; dst |= ((unsigned long long)src[1] & 3FFF)<< 14); dst |= ((unsigned long long)src[2] & 3FFF)<< 28); dst |= ((unsigned long long)src[3] & 3FFF) << 42); [/quote]对了 补充一下 因为第二个unsigned long long 先填充了6bit 所以不能在使用 0 14 28 42... 作为位移操作数 应该是6 20 34 48 .....  现在还觉得直接位移够用吗?

user: user-2
content: 引用 7 楼 幻夢之葉 的回复:[quote=引用 6 楼 幻夢之葉 的回复:] 位移+位或就处理完了啊 short src[4] unsigned long long dst = 0; dst |= ((unsigned long long)src[0] << 0); dst |= ((unsigned long long)src[1] << 14); dst |= ((unsigned long long)src[2] << 28); dst |= ((unsigned long long)src[3] << 42);  其中dst有一个字节的内容可能是随变的，是否要处理掉看你实际流程 上面的有问题，应该是这样子才对，并且忽略红色标注那句话 short src[4] unsigned long long dst = 0; dst |= ((unsigned long long)src[0] & 3FFF) << 0; dst |= ((unsigned long long)src[1] & 3FFF)<< 14); dst |= ((unsigned long long)src[2] & 3FFF)<< 28); dst |= ((unsigned long long)src[3] & 3FFF) << 42); [/quote]你的做法还没有涉及到最麻烦的地方  unsigned long long 64bit每次填充14bit 那么最后是有8bit 不够直接填充 需要把14bit拆成8+6 8bit填充这个unsigned long long 6bit填充下一个unsigned long long 而第二个unsigned long long先填充了6bit  那么最后会有2bit 不够直接填充 依次类推  这才是最麻烦的

user: user-2
content: 引用 12 楼 早打大打打核战争 的回复:实际上楼主这个压缩没有多少意义，不如把数据用zlib之类的压缩再传输 同意  我也是这样想的 昨天 楼主C语言贴吧也发过同一个问题的帖子 当时我就对他说 现成的压缩算法挑一个

user: user-3
content: 实际上楼主这个压缩没有多少意义，不如把数据用zlib之类的压缩再传输

user: user-2
content: 引用 10 楼 早打大打打核战争 的回复:这个不是问题，他可以只使用56位，不必填满64位，每次存7字节有效数据即可，麻烦的是处理零头，每次写8字节（写的地址按7字节步进）最后一次可能越界，需要分配的缓冲区大一些才行。unsigned long long 做中转 存7字节有效数据之后 再用&操作写到目标缓冲区 这样的确方便很多  那么就只剩下2个问题了 一个是你所说的零头  另一个是必须有至少64bit并且支持位操作的类型   备注: 不能用memcpy一次性操作7字节

user: user-3
content: 这个不是问题，他可以只使用56位，不必填满64位，每次存7字节有效数据即可，麻烦的是处理零头，每次写8字节（写的地址按7字节步进）最后一次可能越界，需要分配的缓冲区大一些才行。

user: user-4
content: 引用 6 楼 幻夢之葉 的回复:位移+位或就处理完了啊 short src[4] unsigned long long dst = 0; dst |= ((unsigned long long)src[0] << 0); dst |= ((unsigned long long)src[1] << 14); dst |= ((unsigned long long)src[2] << 28); dst |= ((unsigned long long)src[3] << 42);  其中dst有一个字节的内容可能是随变的，是否要处理掉看你实际流程 上面的有问题，应该是这样子才对，并且忽略红色标注那句话 short src[4] unsigned long long dst = 0; dst |= ((unsigned long long)src[0] & 3FFF) << 0; dst |= ((unsigned long long)src[1] & 3FFF)<< 14); dst |= ((unsigned long long)src[2] & 3FFF)<< 28); dst |= ((unsigned long long)src[3] & 3FFF) << 42);

user: user-4
content: 引用 4 楼 lin5161678 的回复:[quote=引用 3 楼 幻夢之葉 的回复:] 7个字节装下4个数据 那么用一个8字节的类型的整数，比如long long 按顺序移位+位或即可，每次填装四个数据  第二次和后续，先转char*指针，取7的倍数偏移，再转成long long*类型，填装下一组的四个数据  如果不是c11标准不支持long long，可以用个系统或者API提供的其他64位整形类型替代你理解错了  是2个字节里面2bit不用 直接移位是不行的[/quote] 位移+位或就处理完了啊 short src[4] unsigned long long dst = 0; dst |= ((unsigned long long)src[0] << 0); dst |= ((unsigned long long)src[1] << 14); dst |= ((unsigned long long)src[2] << 28); dst |= ((unsigned long long)src[3] << 42);  其中dst有一个字节的内容可能是随变的，是否要处理掉看你实际流程

user: user-4
content: 7个字节装下4个数据 那么用一个8字节的类型的整数，比如long long 按顺序移位+位或即可，每次填装四个数据  第二次和后续，先转char*指针，取7的倍数偏移，再转成long long*类型，填装下一组的四个数据  如果不是c11标准不支持long long，可以用个系统或者API提供的其他64位整形类型替代

user: user-5
content: 用unsigned char 传输，取8 bit 和14 bit的最小公倍数（56），移位来填满每个字节。 只在乎带宽而不在乎CPU的或者凑字节用并行硬件执行的可以考虑，否则性价比太低。

user: user-2
content: 引用 3 楼 幻夢之葉 的回复:7个字节装下4个数据 那么用一个8字节的类型的整数，比如long long 按顺序移位+位或即可，每次填装四个数据  第二次和后续，先转char*指针，取7的倍数偏移，再转成long long*类型，填装下一组的四个数据  如果不是c11标准不支持long long，可以用个系统或者API提供的其他64位整形类型替代你理解错了  是2个字节里面2bit不用 直接移位是不行的

user: user-0
content: 低效的代码也行

user: user-2
content: 没有