c - C 如何处理补码架构中的数字 0?

标签 c ones-complement

我最近一直在研究表示数字的补码系统,据我了解,数字 0 有两种变体。负零 (-0) 和正零 (+0)。

我的问题是,在 one's complement 架构中,C 中如何处理这种异常? C 是否区分 -0 和 +0,或者这两种形式都被简单地视为零。

如果测试为零时 +0 和 -0 都返回 TRUE,那么我想知道如果我们输入 -0 作为整数,下面的示例代码将如何计算整数中的设置位数输入。

int bitcount(int x)
{
    int b;
    for (b = 0; x != 0; b++)
        x &= (x-1);
    return b;
}

由于 -0 在一个补码中将其所有位设置为 1,因此 -0 应该返回任何其他数字中设置的最高数量的位;然而,这段代码似乎无法通过 x != 0 的循环测试条件,甚至不会进入循环,从而给出错误的结果。

在 C 中,在一个补码架构中,是否有可能以某种方式使循环条件对正零敏感,如:x != +0 另外,如果我从 + 中减去 1 0,我会得到 -0 还是 -1。换句话说,+0 - 1 = -0 在补码架构中吗?

总而言之,在这个讨论中不要离题太远,我只是想知道 C 如何处理补码架构中数字 0 的特殊性。

最佳答案

在一个补码架构上,“带符号位且所有值位为 1”的值是“陷阱表示”还是正常值是实现定义的。如果它是一个陷阱表示,任何试图用它做任何,甚至首先创建它的尝试都会引发未定义的行为。如果它是一个正常值,它就是一个“负零”,并且有一个明确的允许产生它的操作列表:

If the implementation supports negative zeros, they shall be generated only by:

  • the &, |, ^, ~, <<, and >> operators with operands that produce such a value;
  • the +, -, *, /, and % operators where one operand is a negative zero and the result is zero;
  • compound assignment operators based on the above cases.

It is unspecified whether these cases actually generate a negative zero or a normal zero, and whether a negative zero becomes a normal zero when stored in an object.

(C11/N1570,第 6.2.6.2 节第 3 段。)

负零是否等于正常零似乎也未指定(通过省略)。类似的规则适用于符号和大小架构。

所以,归根结底,您的示例代码的行为是实现定义的,实现定义它可能不会有帮助。您需要查阅此假设的补码机的编译器和体系结构手册,以确定它是否按照您的要求执行。

但是,整个问题都没有实际意义,因为至少 25 年来没有人制造过非二进制补码 CPU。人们希望 C 标准的 future 修订将不再允许这种可能性;它会简化很多事情。

关于c - C 如何处理补码架构中的数字 0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45260365/

相关文章:

c - 帮助2个C宏

java - 1's complement to 2' s 补码转换

位运算符可以有未定义的行为吗?

c++ - 在 C/C++ 中使用 ~ 的 1 补码

binary - 将十进制转换为补码

c - Linux操作系统的udp中的sendto api?

c - 如何确定 float 尾数的最大正基数 10 值?

c - 如何使用当前区域设置打印日期?

c - 获取核心数(*不是* HT 线程)

c++ - 将较小整数的最大值分配给较大整数