【问题标题】:Bit shift once to left upon an event发生事件时向左移位一次
【发布时间】:2015-01-01 12:37:42
【问题描述】:

我正在寻找一个需要增加计数器的问题。此计数器的工作方式类似于大小为 3 的事件内存持有者。这意味着您可以存储在过去三个时间段内发生的事件。

例如:

  • 在时隙 0 发生了一个事件:set mem_holder = 001
  • 在时间段 1,另一个事件:将 mem_holder 移到 1 和新事件 -> 011
  • 在时隙 2 处,没有事件,因此我们将两个位都向左移一位 -> 110
  • 在时间段 3,没有事件再次向左移动 -> 100
  • 在时间段 4,新事件 -> 001
  • 在时隙 5,没有事件 -> 010
  • 在时间段 6,新事件 -> 101

等等等等

我正在寻找的是有关如何以适当且有效的方式解决此问题的提示或示例。 标准是低复杂度和低内存要求,即没有大的变量分配。

我对位操作知之甚少,但我知道基础知识,例如> & ^ 但是将它们组合在一个“大”的上下文中是具有挑战性的,所以任何建议/帮助都值得赞赏!

感谢高级

【问题讨论】:

  • 你已经描述了怎么做,所以我不太明白你想让我们告诉你什么
  • && 不是位操作
  • 我希望得到一些面向实施的建议,例如如何将给定的示例带到实际的代码示例中
  • (buffer << 1) | new_event 怎么样(这会在缓冲区中留下超过 3 个,但您可以忽略多余的)
  • 谢谢哈罗德,这可能只是解决方案,执行起来很简单。是的,缓冲区可能会变大,但正如您所说,这可以忽略不计。再次感谢!

标签: c


【解决方案1】:

基本上,您有一个 3 位整数,这意味着它可以保存从 b000 到 b111 的值,因此是 0 到 7。如果您将任何整数与 7 进行“与”,则除了最右边的 3 位之外,您将清除任何内容。

所以,你要做的是左移一位来为新的位腾出位置,然后按位和 7。由于你的左移,最新的最右边的位现在是 0。在此之后,如果有新事件,则使用按位或将最右边的位设置为 1。

#include <stdio.h>

void mark(int new_event) {
    static int bits = 0;

    /* Shift the bits one left to make place for the new event bit.
     * Make sure only 3 bits are used. */
    bits <<= 1;
    bits &= 7;          /* 7 is in binary 111, all other bits get removed */

    /* Put in the rightmost bit a 1 if new_event is 'true', else it's
     * already zeroed-out due to the above leftshift */
    if (new_event)
        bits |= 1;
    /* Note: if you're sure that new_event can only have values 0 and 1, then
     * you can do an unconditional:
     *    bits |= new_event
     */

    /* Output what we've done for demo purposes */
    printf("New event: %d. Bits: ", new_event);
    putchar(bits & 4 ? '1' : '0');
    putchar(bits & 2 ? '1' : '0');
    putchar(bits & 1 ? '1' : '0');
    putchar('\n');
}

int main() {
    /* at time slot 0, there was a event: set mem_holder = 001
       at time slot 1, another event: shift mem_holder with 1
                       and and the new event -> 011
       at time slot 2, no event so we shift both bits with one to left -> 110
       at time slot 3, no event shift both again to left -> 100
       at time slot 4, new event -> 001
       at time slot 5, no event -> 010
       at time slot 6, new event -> 101
    */
    mark(1);
    mark(1);
    mark(0);
    mark(0);
    mark(1);
    mark(0);
    mark(1);

    return 0;
}

输出:

New event: 1. Bits: 001
New event: 1. Bits: 011
New event: 0. Bits: 110
New event: 0. Bits: 100
New event: 1. Bits: 001
New event: 0. Bits: 010
New event: 1. Bits: 101        

【讨论】:

    【解决方案2】:

    您也可以采用不那么复杂的逻辑:

    mem_holder = (mem_holder*2)%8 + event
    where event can take values [0,1].
    

    【讨论】:

    • 嗯,它并不比 mem_holder = ((mem_holder
    • 这里的所有操作都比按位等价的操作更复杂,并且只是等价的,因为它们是碰巧很简单的特殊情况。
    猜你喜欢
    • 2019-10-15
    • 1970-01-01
    • 1970-01-01
    • 2017-12-23
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多