我最近一直在研究表示数字的补码系统,据我所知,数字 0 有两种变体。有一个负零 (-0) 和一个正零 (+0)。
我的问题是,在一个补码架构上,这个异常在 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
另外,如果我从 +0 中减去 1,我会得到 -0 或 -1。换句话说,在一个补码架构中 +0 - 1 = -0 吗?总而言之,不要在本次讨论中走得太远,我只是想知道 C 如何处理补码架构中数字 0 的特殊性。
最佳答案
它是实现定义的,在一个补码架构上,“带符号位和所有值位为 1”的值是“陷阱表示”还是正常值。如果它是一个陷阱表示,任何试图用它做任何事情,甚至首先创建它,都会引发未定义的行为。如果它是一个正常值,它就是一个“负零”,并且有一个明确的允许产生它的操作列表:
(C11/N1570,第 6.2.6.2 节第 3 段。)
负零是否等于正常零似乎也未指定(通过省略)。类似的规则适用于符号和大小架构。
所以,这归结为,您的示例代码的行为是实现定义的,并且实现可能无法对其进行有效定义。您需要查阅这个假设的补码机器的编译器和体系结构手册,以确定它是否按照您的要求执行。
然而,整个问题都没有实际意义,因为至少在 25 年内没有人制造过非二进制补码 CPU。人们希望 C 标准的 future 修订将不再允许这种可能性;它会简化很多事情。
关于c - C 如何处理补码架构中的数字 0?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45260365/