目前,霍夫曼压缩算法将二进制代码分配给文本文件中使用的字符。频率较低的位数较少,频率较低的字符位数较多。
目前,我尝试将二进制代码 big-endian 保存在一个字节中。
所以,让我们说我使用unsigned char来保存它。
00000000
我想存储一些1101
的二进制代码。
事先,我想道歉,如果这看似微不足道或是一个骗局,但我已经浏览了几十个其他帖子,似乎无法找到我需要的东西。如果有人可以链接或快速解释,那么我们将非常感激。
这是正确的语法吗?
我会有一些外部方法,如
int length = 0;
unsigned char byte = (some default value);
void pushBit(unsigned int bit){
if (bit == 1){
byte |= 1;
}
byte <<= 1;
length++;
if (length == 8) {
//Output the byte
length = 0;
}
}
我看过一些解释 endianess 的视频,而我的理解是最重要的一点(第一个)被放入最低内存地址。
有些视频从左到右显示字节,这让我觉得我需要将所有东西都移开,但每当我设置,切换,擦除一点时,它从最右边是不是?如果这是微不足道的话,我再次感到遗憾。
因此,在我的方法完成将1101
推入此方法后,byte将类似于00001101
。这是大端吗?我对地址位置的了解非常薄弱,我不确定
** - &gt; 00001101
或00001101
&lt; - **
位置被认为是最重要的。
我需要左移剩余的金额吗?
因为我使用了4位,所以我将左移4位来制作11010000
。这是大端吗?
答案 0 :(得分:4)
首先,正如Killzone Kid所说,endianess和二进制代码的位顺序是两个完全不同的东西。 Endianess是指多字节整数存储在内存字节中的顺序。对于小端,首先存储最不重要的字节。对于big endian,首先存储最重要的字节。字节中的位不会改变顺序。 Endianess与你所要求的无关。
至于累积位,直到你有一个字节的值得写,你有基本的想法,但你的代码是不正确的。你需要先转移,然后转移或转移。你正在这样做的方式,你输掉了第一位,你所写的低位总是为零。只需将byte <<= 1;
放在if
。
你还需要以某种方式处理结束流,如果剩下少于8个,则写出最后一位。因此,如果位缓冲区中有多个位,则需要flushBits()
来写出位缓冲区。您的位流需要自行终止,或者您需要先发送位数,这样就不会将最后一个字节中的填充位误解为代码或代码。
答案 1 :(得分:2)
有两种类型的 endianness , Big-endian 和 Little-endian (技术上还有更多,如中间 - endian ,但大而小是最常见的)。如果你想拥有 big-endian 格式(如你所愿),那么最重要的字节首先出现, little-endian 是最不重要的字节先到了。
Wikipedia has some good examples
看起来你要做的就是将字节内的位本身存储在相反的顺序中,这不是你想要的。字节与字节序无关,不需要翻转。多字节类型(例如 uint32_t )可能需要更改其字节顺序,具体取决于您要实现的 endianness 。
也许你指的是bit numbering,在这种情况下,你所拥有的代码应该在很大程度上起作用(尽管你应该将长度与7比较,而不是8)。将这些位置于pushBit中的顺序最终会导致您传递的第一个位为最高位。
答案 2 :(得分:0)
根据定义,位不可寻址(如果我们讨论的是C ++,而不是C51或其C ++后继者),那么从高级语言的角度来看,即使是汇编程序伪代码的POV,无论方向是什么LSB - &GT; MSB是逐位<<
执行从LSB到MSB的转换。位顺序称为位编号,是与硬件实现相关的字节序的独立功能。
C ++中的位字段改变顺序,因为在大多数常见的用例中,通常位具有相反的顺序,例如在网络通信中,但事实上如何将位字段打包成字节是依赖于实现的,没有一致性保证没有间隙或保留顺序。
C ++中最小的可寻址内存单位大小为char
,这就是你对endian-ness的关注所在。如果您实际应该更改位顺序(当使用某些不兼容的硬件时?),这种情况很少见,您必须明确这样做。
请注意,在使用以太网或其他网络协议时,您不应该这样做,订单更改由硬件完成(通过线路发送的第一位是平台上最不重要的一位)。