我目前正在研究基于霍夫曼解码的文件压缩器。所以我有一个像这样的解码树:
我必须按照一定的标准在输出文件上对此树进行编码:
"对于每个叶子,写出一个0位,然后是8位 相应的字符。写出位7,位6,...的位。 。 。,位0,这是高位优先。作为一种特殊情况,如果字节为0,则写出位8,对于字节值0将为0,对于字节值为256(EOF标记)将为1。"对于内部节点,只需写入1位。
所以我打算做的是创建一个位数组并添加指定格式的相应位。问题是我不知道如何在smalltalk中将数字转换为二进制数。
例如,如果我想编码第一个叶子,我想做一些像01101011,即0后跟k的位表示然后将每个位逐个添加到数组中。
答案 0 :(得分:3)
我不知道你正在使用哪种方言,但一般来说,你可以访问Integer的位。它们被建模为好像表示是双补码的,具有无限的位序列。
2 is ....0000000000010
1 is ....0000000000001
0 is ....0000000000000 with infinitely many 0 on the left
-1 is ....1111111111111 with infinitely many 1 on the left
-2 is ....1111111111110
对于LargeIntegers也是如此,即使它们通常被实现为符号幅度(类对符号进行编码),也会模拟双补码。
然后你可以使用bitAnd:bitOr:bitXor:bitInvert bitShift:,并且在某些版本中bitAt:put:
您可以使用(2 bitAt:index)访问位,其中索引从1开始,用于最低有效位,或者增长更高。如果它丢失了,请用bitAnd:和bitShift:...
实现它对于正数,您可以要求高位(2 highBit)的等级。
所有这些操作都应该创建一个新的整数(没有可能的修改)。
从概念上讲,ByteArray是8位(0到255之间)的无符号整数的集合,因此您可以使用它们实现位数组(如果方言中尚不存在)。或者您可以使用整数(但无法控制无限大小,也不能使用mofifications,操作将花费一份副本)。