0

背景:给定一些输入字节 B0、B1、B2、B3 和 B4,我想从这 5 个字节中提取选定的位并生成一个输出字。

例如,将B i的第n位表示为,我希望能够写出一个映射f: (B0, B1, B2, B3, B4) → 。所以会回来。Bi[n]B2[4] B3[5] B3[4] B3[3] B3[2] B3[1] B0[5] B0[3] B0[1]f(0b11001, 0b01100, 0b10101, 0b10011, 0b11111)0b010011101

C 中可能会执行此确切示例的表达式是

(B2 & 4 << 5) | (B3 << 3) | (B0 & 16 << 2) | (B0 & 4 << 1) | (B0 & 1)

使用简单的位掩码和位移。


问题:有什么方法可以简化这样的表达式以最小化需要执行的操作数量?

例如,我注意到 B3 被完整地复制到输出的某些位中,因此我将其放置在适当的位置,B3 << 3而不是屏蔽和移动单个位。我首先想到的是卡诺图,因为它们在简化布尔表达式时派上用场,但我意识到,由于我在一个字节的不同部分提取和放置各个位,因此使用布尔代数不可能进行简化。


推理:我想这样做的原因是能够在 BBC micro:bit 上以程序员友好的方式点亮 LED。我希望 B0 到 B4 表示在物理 5x5 排列中打开了哪些 LED,但这些 LED 在电子上以复杂的 3x9 配置连接。有关 LED 的更多信息,请参见此处

通常,模式会根据物理 3x9 排列存储在内存中,以便能够在单个指令中将此模式输出到 LED,但我希望能够以编程方式将 5x5 模式映射到 3x9 模式。然而,如上所示的表达式需要 5 次加载指令、9 次按位 AND/OR 运算和 4 次逻辑移位,这至少比普通方法的效率低 9 倍。

4

1 回答 1

0

首先考虑每个位需要移动多少(而不仅仅是其最终位置)。然后,您可以使用一个命令对移位相同的输入位组执行多个位的所需移位量。例如,(B3 & 31) << 3)。如果被屏蔽的位被移出,您也可以消除“屏蔽”(使用按位 AND 和 & 完成)。

于 2022-02-21T15:57:41.560 回答