有什么理由分配-0?
Any reason to assign -0?
我正在使用 Lint 检查一些旧的 C 代码,偶然发现了这一行:
int16_t max = -0;
Lint 消息是 "Constant expression evaluates to 0 in operation '-'"。
有人会使用 -0 有什么原因吗?
在 C 规范 (6.2.6.2 整数类型) 中,它声明如下(强调我的):
For signed integer types, the bits of the object representation shall be divided into three groups: value bits, padding bits, and the sign bit. There need not be any padding bits; there shall be exactly one sign bit. Each bit that is a value bit shall have the same value as the same bit in the object representation of the corresponding unsigned type (if there are
M value bits in the signed type and N in the unsigned type, then M £ N). If the sign bit is zero, it shall not affect the resulting value. If the sign bit is one, the value shall be modified in one of the following ways:
- the corresponding value with sign bit 0 is negated (sign and
magnitude);
- the sign bit has the value -(2N) (two’s complement);
- the sign bit has the value -(2N - 1) (one’s complement).
Which of these applies is implementation-defined, as is whether the
value with sign bit 1 and all value bits zero (for the first two), or
with sign bit and all value bits 1 (for one’s complement), is a trap
representation or a normal value. In the case of sign and magnitude
and one’s complement, if this representation is a normal value it is
called a negative zero.
也就是说,C支持三种不同的representations for signed integers and two of them have the concept of signed zero,区分了正零和负零
所以,我的解释是,您的代码片段的作者可能试图生成负零值。但是,正如中所指出的,这个表达式实际上不能产生负零,这意味着作者可能在那里做出了错误的假设。
不,我看不出有任何理由。其他人提到可以有 "negative zero" 的平台,但是这个表达式永远不会产生这样的负零,所以这是没有用的。
C标准中对应的段落是6.2.6.2 p3,重点是我的:
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.
例如,要在这样的平台上生成负零,您可以使用 ~INT_MAX
,但对于其他表示,这不会是零,因此代码不是很便携。
这是针对使用 CPU 和 one's complement 数字的架构。
- 补码是一种表示负数的方式,具有 -0。仍在使用浮点数。
- 对于无符号数,最大数确实是
-0
:全 1。
我们习惯了补码,多了一个负数。虽然一个人的补码在零附近有一些麻烦,但同样适用于 MIN_INT 附近的二进制补码:-MIN_INT == MIN_INT
.
上面的代码可能是无符号数:
uint16_t max = (uint16_t) -1;
C99 或更高版本没有理由。
int16_t
是精确宽度的整数类型。
The typedef name intN_t
designates a signed integer type with width N, no padding bits, and a two’s complement representation. Thus, int8_t
denotes such a signed integer type with a width of exactly 8 bits. C11dr §7.20.1.1 1
二进制补码中没有带符号的零。所以代码相当于
int16_t max = 0;
IMO,int16_t max = -0;
希望 的结果,在非 2 的补码平台上,是将 max
初始化为 -0
到标记长度为 0 或仅包含值为 -0
.
的元素的数组
我正在使用 Lint 检查一些旧的 C 代码,偶然发现了这一行:
int16_t max = -0;
Lint 消息是 "Constant expression evaluates to 0 in operation '-'"。
有人会使用 -0 有什么原因吗?
在 C 规范 (6.2.6.2 整数类型) 中,它声明如下(强调我的):
For signed integer types, the bits of the object representation shall be divided into three groups: value bits, padding bits, and the sign bit. There need not be any padding bits; there shall be exactly one sign bit. Each bit that is a value bit shall have the same value as the same bit in the object representation of the corresponding unsigned type (if there are M value bits in the signed type and N in the unsigned type, then M £ N). If the sign bit is zero, it shall not affect the resulting value. If the sign bit is one, the value shall be modified in one of the following ways:
- the corresponding value with sign bit 0 is negated (sign and magnitude);
- the sign bit has the value -(2N) (two’s complement);
- the sign bit has the value -(2N - 1) (one’s complement).
Which of these applies is implementation-defined, as is whether the value with sign bit 1 and all value bits zero (for the first two), or with sign bit and all value bits 1 (for one’s complement), is a trap representation or a normal value. In the case of sign and magnitude and one’s complement, if this representation is a normal value it is called a negative zero.
也就是说,C支持三种不同的representations for signed integers and two of them have the concept of signed zero,区分了正零和负零
所以,我的解释是,您的代码片段的作者可能试图生成负零值。但是,正如
不,我看不出有任何理由。其他人提到可以有 "negative zero" 的平台,但是这个表达式永远不会产生这样的负零,所以这是没有用的。
C标准中对应的段落是6.2.6.2 p3,重点是我的:
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.
例如,要在这样的平台上生成负零,您可以使用 ~INT_MAX
,但对于其他表示,这不会是零,因此代码不是很便携。
这是针对使用 CPU 和 one's complement 数字的架构。
- 补码是一种表示负数的方式,具有 -0。仍在使用浮点数。
- 对于无符号数,最大数确实是
-0
:全 1。
我们习惯了补码,多了一个负数。虽然一个人的补码在零附近有一些麻烦,但同样适用于 MIN_INT 附近的二进制补码:-MIN_INT == MIN_INT
.
上面的代码可能是无符号数:
uint16_t max = (uint16_t) -1;
C99 或更高版本没有理由。
int16_t
是精确宽度的整数类型。
The typedef name
intN_t
designates a signed integer type with width N, no padding bits, and a two’s complement representation. Thus,int8_t
denotes such a signed integer type with a width of exactly 8 bits. C11dr §7.20.1.1 1
二进制补码中没有带符号的零。所以代码相当于
int16_t max = 0;
IMO,int16_t max = -0;
希望 的结果,在非 2 的补码平台上,是将 max
初始化为 -0
到标记长度为 0 或仅包含值为 -0
.