【问题标题】:Why is __builtin_parity opposite?为什么 __builtin_parity 是相反的?
【发布时间】:2021-12-04 10:40:53
【问题描述】:

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

根据what GCC states

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

这意味着如果 1 的位数是偶数,它会返回 0,如果是奇数则返回 1。

我在 Compiler Explorer 上测试的 Clang 也是如此。

但是,实际的parity flag是在设置位数为偶数时设置的。

为什么会这样?

【问题讨论】:

  • @NateEldredge 这确实有道理,因为如今奇偶校验标志已过时。我仍然不明白为什么函数以相反的方式执行
  • 仅供参考,当向一个数字添加奇偶校验位时,奇偶校验位最好是奇数位的偶数位,因为这意味着没有结果将所有位都关闭(如果数字为零,奇偶校验位将被设置)。因此,当您的纸带阅读器正在扫描您的纸带时,它可以依赖于每行磁带中始终至少有一个孔。它可能会使用它来帮助在磁带移动或检测错误时保持时间同步。 (我不明白为什么会实施 __builtin_parity 来扭转这种传统意义。)

标签: c++ c gcc clang


【解决方案1】:

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

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

我觉得GCC的选择比较合乎逻辑:0和1应该分别对应偶数和奇数,因为0是偶数,1是奇数。我不知道为什么 x86 及其前辈选择反其道而行之。你可能不得不回到过去问问设计师。

反正8086校验标志的实际值不是很重要;程序员通常会使用JPEJPO 汇编程序助记符对其进行测试,这让您只需指定“奇偶校验时跳转”或“奇偶校验时跳转”,而无需记住哪个对应于标志中的 0 或 1 位.只有当您想通过PUSHFLAHF 实际检查 FLAGS 寄存器中的位时,该值才会变得相关,这仅在非常模糊的情况下才有用。

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

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

然而,过去 10 年中几乎所有 x86 CPU 都支持popcnt 指令和GCC/clang will use this instead if it's available(然后只提取低位)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-10
    • 1970-01-01
    • 2022-08-18
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    相关资源
    最近更新 更多