C中位运算何时未定义?聚焦C99及C标准相关要求
C标准中的整数“负零”详解
咱们今天就唠唠C标准里的整数负零——这玩意儿在不同的整数表示体系里可是大有讲究,而且咱们只抠标准要求,不管主流编译器的常见行为哈。
C99标准第6.2.6.2节明确引入了整数类型的“负零”概念,这玩意儿只在符号-大小和一补码这两种整数表示的系统里存在,二进制补码系统是没有负零的。
不同表示系统里的负零位模式
- 符号-大小表示系统:负零的位模式是最高位(符号位)为1,其余所有位都是0,也就是十六进制的
0x8000...(后面的0位数取决于具体整数类型的宽度,比如16位int就是0x8000,32位就是0x80000000)。 - 一补码表示系统:负零的位模式是所有位全为1,十六进制就是
0xFFFF...(同样,位数对应类型宽度,16位int是0xFFFF,32位是0xFFFFFFFF)。
标准还提到,这类支持负零的系统里,程序运行过程中可能会产生负零值,但在大多数操作里,负零和普通的正零会被视为等价的。不过也有例外,比如当你把负零作为函数参数传递,或者进行某些位操作的时候,它的位模式可能会被保留下来。
不同C标准的差异
- C89/ANSI C:早期的C89并没有明确提及“负零”这个概念,只是对整数表示的三种形式(符号-大小、一补码、二进制补码)做了规定,并没有专门针对负零的行为做细化说明。这就导致在C89环境下,负零的处理全看具体实现的“心情”,标准没给硬约束。
- C11:C11基本继承了C99对负零的规定,不过在一些细节上做了补充,比如明确了在比较操作中,负零和正零是相等的(
-0 == 0的结果是真),而且在转换为浮点类型的时候,负零会被转换成对应的浮点负零值。
要注意哦,咱们全程说的都是C标准的要求,毕竟现在绝大多数系统用的都是二进制补码,根本没负零这回事,但标准得考虑到所有可能的实现情况嘛。
内容的提问来源于stack exchange,提问作者dubiousjim
相关产品推荐
相关产品推荐

