为什么 __builtin_parity 相反?

PHD*_*PHD 4 c c++ gcc clang

GCC 和 Clang 都支持一个名为的实现定义函数__builtin_parity,该函数有助于确定数字的奇偶校验。

\n

根据海湾合作委员会的规定

\n
\n

内置函数:int __builtin_parity (unsigned int x)
\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0 返回 x 的奇偶校验,即 x 模 2 中 1 的位数。

\n
\n

这意味着如果 1 位的数量为偶数,则返回 0,如果为奇数,则返回 1。

\n

我在编译器资源管理器上测试的 Clang 也是如此

\n

然而,实际的奇偶校验标志然而,当设置的位数为偶数时,设置

\n

为什么会这样呢?

\n

Nat*_*dge 5

它们只是不同的任意选择。

首先请注意,“实际奇偶校验标志”是仅在某些架构上提供的硬件功能;在目前主流使用的架构中,我认为 x86 是唯一具有这样标志的架构。因此,这样一个标志的存在,更不用说确切的语义,无论如何都不是一个通用标准。

我认为GCC的选择更符合逻辑:0和1应该分别对应偶数和奇数,因为0是偶数,1是奇数。我不知道为什么 x86 及其前辈选择做相反的事情。你可能必须回到过去询问设计师。

不管怎样,8086奇偶校验标志的实际值并不是很重要;程序员通常会使用汇编程序助记符来测试它JPEJPO这样您只需指定“奇偶校验为偶数则跳转”或“奇偶校验为奇数则跳转”,而不必记住哪一个对应于标志中的 0 或 1 位。仅当您想通过PUSHF或实际检查 FLAGS 寄存器中的位时,该值才会变得相关LAHF,这仅在非常模糊的情况下才有用。

我稍微查了一下历史。Intel 8086 从 8080 复制了它的标志,它的作用是一样的。它的前身8008也有一个奇偶校验“触发器”,它似乎被设置为偶校验,但有点不清楚,因为你只能有条件地跳转触发器的状态,而不能真正读取它。据说 8008 源自 Datapoint 2200,后者实际上以相反的方式记录其奇偶校验翻转:设置为奇数,重置为偶数。但 80xx 语义可能是一些内部实现细节,没有任何深刻的意义,就像奇偶校验电路恰好以这种方式产生结果,并且他们没有费心添加另一个非门来反转它。任何进一步的调查可能更多地涉及 Retrocomputing.SE 的主题。

无论如何,x86 奇偶校验标志对于 GCC 来说只有一点用处__builtin_parity(),因为它只测试一个字节。通过将其字节异或在一起,可以将其用于更大的值,如果没有其他选项,GCC/clang 将执行此操作。setnp它通过在末尾使用代替来处理标志的反向含义setp(人类程序员只需编写setpo而不必考虑标志的设置/清除值)。

然而,过去 10 年几乎所有 x86 CPU 都支持该popcnt指令,如果可用,GCC/clang 将使用该指令(然后只提取低位)。