我知道整数值0
和-0
基本相同。
但是,我想知道是否有可能区分它们。
例如,我如何知道变量是否已分配-0
?
bool IsNegative(int num)
{
// How ?
}
int num = -0;
int additinon = 5;
num += (IsNegative(num)) ? -addition : addition;
内容中保存的值-0
与0
完全相同吗?
答案 0 :(得分:111)
这取决于您定位的机器。
在使用2's complement representation整数的计算机上,0
和-0
之间的在位级之间没有差异(他们有相同的表示)
如果你的机器使用one's complement,你绝对可以
0000 0000 -> signed 0
1111 1111 -> signed −0
显然我们正在谈论使用本机支持,x86系列处理器本身支持已签名号码的两个补码表示。使用其他表示肯定是可能的,但可能效率较低,需要更多指令。
(正如JerryCoffin所指出的那样:即使出于历史原因考虑过补充,signed magnitude representations仍然相当普遍,并且确实有一个单独的负数和正数零表示<) /子>
答案 1 :(得分:14)
对于int
(在几乎通用的“2的补码”表示中),0
和-0
的表示是相同的。 (对于其他数字表示,它们可以不同,例如IEEE 754浮点。)
答案 2 :(得分:12)
让我们从2的补码中表示0开始(当然存在许多其他系统和表示,这里我指的是这个特定的),假设8位,零是:
0000 0000
现在让我们翻转所有位并加1以获得2的补码:
1111 1111 (flip)
0000 0001 (add one)
---------
0000 0000
我们得到0000 0000
,这也是-0的表示。
但请注意,在1的补码中,带符号0为0000 0000,但-0为1111 1111。
答案 3 :(得分:9)
我决定放弃这个答案,因为C和C ++实现通常密切相关,但事实上它并不像我想的那样遵循C标准。关键在于C ++标准没有规定像这样的情况会发生什么。同样重要的是,在现实世界中,非二重补充表示非常罕见,即使它们确实存在,它们通常会在许多情况下隐藏差异,而不是将其暴露为某人可能容易发现的东西。
在C ++标准中,C标准中没有像在C标准中那样严格定义负零的行为。但是,它确实引用了C标准(ISO / IEC 9899:1999)作为顶级[1.2]的规范性参考。
在C标准[6.2.6.2]中,负零只能是按位运算的结果,或者已经存在负零的运算(例如,将负零乘以或除以一个值,或者添加一个负零到零) - 将一元减号运算符应用于正常零值,如在您的示例中,因此保证产生正常零。
即使在可以产生负零的情况下,也无法保证它们即使在支持负零的系统上也是如此:
未指明这些情况是否实际产生负零或正常零,以及当存储在对象中时负零是否变为正常零。
因此,我们可以得出结论:不,没有可靠的方法来检测这种情况。即使不是因为非二进制补码表示在现代计算机系统中非常罕见。< / p>
就其本身而言,C ++标准没有提及“负零”这一术语,除了注意到[3.9.1第7段]它们之外,很少讨论有条件的幅度和一个补码表示的细节。是允许的。
答案 4 :(得分:8)
如果您的计算机具有-0
和+0
的不同表示,则memcmp
将能够区分它们。
如果存在填充位,则实际上可能存在多个除零以外的值的表示。
答案 5 :(得分:2)
为了简化我发现它更容易可视化。
类型 int (_ 32)与 32位一起存储。 32位表示2 ^ 32 = 4294967296 唯一值。因此:
unsigned int 数据范围 0到4,294,967,295
如果是负值,则取决于它们的存储方式。如果
如果一个补码值-0存在。