【问题标题】:Create string based on bitfield基于位域创建字符串
【发布时间】:2019-03-16 14:47:14
【问题描述】:

我在 python 脚本中使用 5 位位域来跟踪警报系统的状态。例如,MSB 中的 0 表示“Not Armed”,而 MSB 中的 1 表示“Armed”等。这使得对先前状态和当前状态的 XOR 可以快速得出哪些位已更改:

previous = 0b11001
current =  0b10011
delta = current ^ previous   # delta = 0b01010

我的代码中的下一步是根据delta 生成一个描述更改内容的字符串。有 10 种可能的状态和描述。我想知道创建此字符串的最佳方法。我在下面的工作,但似乎很笨重:

statusKey = {
         0: ' * Disarmed',
        10: ' * No Alarm',
        20: ' * No Fire',
        30: ' * No Check',
        40: ' * No AC',
         1: ' * Armed',
        11: ' * Alarm',
        21: ' * Fire',
        31: ' * Check',
        41: ' * AC'
         }

alert = ''
for i in range (5):
    if (0b10000 & (delta << i)):
         alert = ''.join((alert,statusKey[(10*i) + (0b01 & (current >> (4-i)))]))

#alert = 'No Alarm * Check'

有没有更好的方法来构造 statusKey 中的数据? 有没有更好的方法来基于该结构生成alert 字符串?

【问题讨论】:

  • 您可以在列上使用numpy.bitwise_and,但对于这么少的数据来说有点过分了。你的方法还不错。
  • @stevedc 这个问题可能更适合Code Review 如果你想在那里问的话。

标签: python bit-fields


【解决方案1】:

尝试使用尽可能少的按位数学运算符,因为这会使您的代码非常不可读。一个简单的列表理解就是你真正需要的。此外,您希望您的位状态数据结构是自描述的。第一次阅读的人应该立即明白其中的逻辑。

bit_status = {
    0: ("Disarmed", "Armed"),
    1: ("No Alarm", "Alarm"),
    2: ("No Fire", "Fire"),
    3: ("No Check", "Check"),
    4: ("No AC", "AC")
}

previous = 0b11001
current =  0b10011

current_bits = [current >> i & 1 for i in reversed(range(5))]
delta_bits = [(current ^ previous) >> i & 1 for i in reversed(range(5))]

status = [bit_status[index][current_bits[index]] 
    for index, delta_bit in enumerate(delta_bits) if delta_bit == 1]

print(" * ".join(status))
# No Alarm * Check

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-11
    • 1970-01-01
    相关资源
    最近更新 更多