【问题标题】:Check even parity from byte从字节检查偶校验
【发布时间】:2019-10-09 07:02:05
【问题描述】:

我在 Stackoverflow 上找到了一段代码,并根据我的需要对其进行了编辑。来源:How to check if value has even parity of bits or odd?

它就像一个魅力,但我无法理解它为什么起作用。

我试着把它写出来,例如字节 0b01101101。

   01101101
   00000110
   -------- ^
   01101011
   00011010
   -------- ^
   01110001
   00111000
   -------- ^
   01001001

虽然我的单元测试给出了答案; 1

uint8_t check_even_parity(uint8_t value){
     value ^= value >> 4;
     value ^= value >> 2;
     value ^= value >> 1;

     return value & 1;
}

预期是; 0 尝试写出时的实际结果; 01001001

【问题讨论】:

  • 别忘了最后一个& 1。最后只有最右边的部分很重要。
  • 01001001 & 1 == 1。我不明白你为什么期望它是0
  • 您的手动遍历似乎不会将值传递到下一行。 "^=" 执行 XOR,然后将值设置为 XOR 的结果。

标签: c bit parity


【解决方案1】:

每一步都将两个位集 L 和 R 组合在一起,以便 L 的奇偶校验与 R 的合并。 R 最终具有与 L+R 最初相同的奇偶性。

在第 1 步中,我们取 8 位并产生一个与 8 位具有相同奇偶性的 4 位数字。在第 2 步中,我们产生一个与 4 具有相同奇偶性的 2 位数字。在最后一步中,我们产生一个与 2 具有相同奇偶性的 1 位数字。这意味着在三个步骤中我们得到一个具有相同奇偶性的位与原 8 平价。

让我一步一步地告诉你我的意思。

  1. 让我们从第一步开始,其中 L 是左 4 位 (0110),R 是右 4 (1101)。

    xxxx1101 (R)
    xxxx0110 (L)
    --------
    xxxx1011 (R^L)
    

    我已经把每个数字的左半部分删掉了。那些位无关紧要。随着我们的进步,你会明白为什么:每一步相关的位越来越少。

    L 为偶数,R 为奇数,即 L+R 为奇数。因此,R ^= L 应该使 R 具有奇校验。可以?确实如此。 0110 有两个设置位,因此 R ^= 0110 翻转 R 的两个位。翻转偶数位不会改变奇偶校验。 R 仍然是奇数

  2. 第二步,L是左2位(10),R是右2(11)。

    xxxxxx11 (R)
    xxxxxx10 (L)
    --------
    xxxxxx01 (L^R)
    

    现在六个位被删除了。我们只关心每个数字的两位。

    这次 L 是奇数,R 是偶数。结合起来,L+R 是奇数,所以这次我们需要翻转 R 的奇偶性。 R ^= L 会这样做吗?再次,它确实如此。 L 设置了奇数位,因此 XOR 将翻转 R 的奇数位,保证 R 的奇偶校验被切换。 R 变为奇数

  3. 在最后一步中,L 和 R 各只有 1 位。

    xxxxxxx1 (L)
    xxxxxxx0 (R)
    --------
    xxxxxxx1 (L^R)
    

    L 为 1,R 为 0。就像前面的步骤一样,我们希望 R ^= L 是奇数,它确实是。 R 是奇数

太棒了。我们从具有奇校验的 8 位开始,通过成功地将两半合并在一起,我们得到了具有相同奇校验的 1 位。

【讨论】:

    【解决方案2】:

    我想提出一个可以给人一些直觉的比喻:

    假设您面前有 4 张卡片,您需要将它们堆叠起来。作为一个有两只手的人,您可以同时拿起每只手的一张牌并将它们放在另外两只手的顶部,然后拿起其中一对并将其放在另一对的顶部。

    这会在 2 个动作中堆积 4 张牌。

    现在假设您需要堆 32 张牌并拥有 16 手(或更多)手。您可以使用相同的技术:创建 16 堆 2 卡,然后创建 8 堆 4 卡,4 堆 8 卡,2 堆 16 卡,最后是单堆 32 卡。

    这会在 5 步中堆积 32 张牌。

    现在将“pile”替换为“xor”,将“cards”替换为“bits”,将“hands”替换为处理器的能力。在 5 次移位和异或中,​​将一个数字的 32 位进行异或运算,如果该数字具有偶校验,则为 0,否则为 1。

    【讨论】:

      猜你喜欢
      • 2019-03-08
      • 1970-01-01
      • 2015-05-31
      • 1970-01-01
      • 2015-06-29
      • 2011-05-27
      • 2020-08-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多