我最近一直在研究表示数字的补码系统,据我了解,数字 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”的值是“陷阱表示”还是正常值,由实现定义。如果它是一个陷阱表示,则任何尝试anything使用它,甚至首先创建它,都会引发未定义的行为。如果它是正常值,则它是“负零”,并且有一个允许产生它的显式操作列表:
如果实现支持负零,则它们只能通过以下方式生成:
- &、|、^、~、> 运算符以及产生此类值的操作数;
- +、-、*、/ 和 % 运算符,其中一个操作数为负零且结果为零;
- 基于上述情况的复合赋值运算符。
未指定这些情况实际上是否生成负零或正常零,以及存储在对象中时负零是否变为正常零。
(C11/N1570,第 6.2.6.2 节第 3 段。)
似乎也未指定(通过省略)负零是否与正常零比较。类似的规则适用于符号和幅度架构。
因此,这可以归结为,示例代码的行为是实现定义的,并且实现可能无法有效地定义它。您需要查阅这个假设的补码机器的编译器和体系结构手册,以确定它是否执行您希望它执行的操作。
然而,整个问题没有实际意义,因为至少 25 年来没有人制造过非二进制补码 CPU。人们希望 C 标准的未来修订将不再允许这种可能性;它会简化很多事情。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)