如何在 Smalltalk 中操作位?

How to manipulate bits in Smalltalk?

我目前正在研究基于霍夫曼解码的文件压缩器。所以我有一个像这样的解码树:

我必须按照特定标准在输出文件中对这棵树进行编码:

”对于每片叶子,写出一个0位,然后是8位 相应的字符。按照第 7 位、第 6 位、...的顺序写出位。 . ., bit 0,即高位在前。作为一种特殊情况,如果字节为 0,则写出位 8,对于字节值为 0 为 0,对于字节值为 256(EOF 标记)为 1。”对于内部节点,只需写入有点 1.

所以我打算做的是创建一个位数组并向其中添加指定格式的相应位。问题是我不知道如何在smalltalk中将数字转换为二进制。

例如,如果我想对第一片叶子进行编码,我想做类似 01101011 的事情,即 0 后跟 k 的位表示,然后将每一位一位一位地添加到数组中。

我不知道你具体使用的是哪种方言,但一般来说,你可以访问 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 也是如此,即使它们通常被实现为符号幅度(class 对符号进行编码),也会模拟二补码。

然后你可以用 bitAnd: bitOr: bitXor: bitInvert bitShift: 操作,在某些情况下 bitAt:put:

您可以使用 (2 bitAt: index) 访问这些位,其中索引从 1 开始表示最低有效位,或者逐渐增加。如果缺少,请使用 bitAnd: 和 bitShift:...

实现

positive可以求高位(2 highBit)的排位

所有这些操作都应该创建一个新的整数(不可能进行就地修改)。

从概念上讲,ByteArray 是 8 位无符号整数的集合(介于 0 和 255 之间),因此您可以用它们实现一个位数组(如果它在方言中尚不存在)。或者您可以使用整数(但无法控制无限大的大小,也无法进行适当的修改,操作将花费副本)。