C++11 标准是不是保证零值有符号整数的一元减号为零?
Posted
技术标签:
【中文标题】C++11 标准是不是保证零值有符号整数的一元减号为零?【英文标题】:Does the C++11 standard guarantee that the unary minus of a zero-valued signed integer is zero?C++11 标准是否保证零值有符号整数的一元减号为零? 【发布时间】:2020-05-01 17:54:06 【问题描述】:C++11 标准是否保证零值有符号整数的一元减号为零?
例如:
int zero = 0;
int n = -zero;
int m = -0;
assert(memcmp(&n, &zero, sizeof(int)) == 0);
assert(memcmp(&m, &zero, sizeof(int)) == 0);
我知道 -0
和 0
在二进制补码表示中是相同的,但我想知道标准是否允许有符号整数零的否定对于其他表示为负零,例如一个恭维或符号量级。
我在 C++11 草案中只能找到 §5.3.1 第 8 段:
一元运算符的操作数应具有算术或无作用域 枚举类型和结果是其操作数的否定。 对整数或枚举操作数执行整数提升。 无符号量的负数是通过减去它的 来自 2^n 的值,其中 n 是提升的操作数中的位数。 结果的类型是提升操作数的类型。
我在草稿中找不到否定的定义。
动机:我正在为一个库编写一个专门的整数解析器(最终可能是开源的),我想知道我是否应该担心"-0"
的可能性在不常见的架构上被解释为负零有符号整数。
注意:我已经知道负零浮点数。
【问题讨论】:
-0 在汇编中不存在,一旦设置了有符号位,x86/x64 中就没有零值。无论如何,好问题。 我不知道zero
是否根据规范被视为“无符号数量”,即使zero
的数据类型是有符号的。
在 C++ 级别可能会定义它,但如何实现呢?您发布的代码将在程序集生成中将 0 和 -0 设置为相同的值。在机器级别没有-0。
任何在底层使用二进制补码的系统都没有内部方法来表示负零,最后我听说二进制补码无处不在,几乎是普遍的。
C 标准指定了一组有限的操作,可能产生负零。一元 -
不在该集合中。 (请参阅n1570 6.2.6.2 第 3 段。)我在 C++11 标准中看不到任何类似的措辞。在 C 中,负零 是一种表示,而不是一个值,它与普通零比较。 (当然它不存在于 2 的补码中。)
【参考方案1】:
该标准不强制要求整数的位模式,因为它旨在适用于尽可能广泛的机器。 C++ 编译器完全可以使用补码,其中零和负零是不同的。
【讨论】:
这将需要重新定义所有的数学,这是不可能的(而且没用的)。 @MichaelChourdakis 我不明白为什么会这样。我使用了一个补码处理器,我向你保证数学不是不可能的。 例如,您会破坏所有 1-1 函数,因为一个 y 会有两个 x。 @MarkRansom 我了解该标准不强制要求位模式,但它可以强制要求算术表达式的结果。我对标准语不够精通,无法知道后者是否属实。 我的理解是C++20 will mandate two's complement signed integers(C2x 也可能如此)。当然,这个问题是专门针对 C++11 的。以上是关于C++11 标准是不是保证零值有符号整数的一元减号为零?的主要内容,如果未能解决你的问题,请参考以下文章
C99 标准是不是保证 unsigned int 的二进制表示?