C ++ 11 abs()of numeric_limits <long> :: min();

时间:2015-04-22 21:50:31

标签: c++ c++11 numeric-limits

我正在运行以下

TEST.CPP

#include <iostream>
#include <limits>
#include <cstdlib>
using namespace std;

int main(int argc, char** argv) {
    long value = numeric_limits<long>::min();
    value = abs(value);
    cout << value << endl;
}

根据我编译和运行程序的计算机,我得到的结果不同。

我要么:

abs(numeric_limits<long>::min())

或者我得到:

numeric_limits<long>::min()

在后一种情况下,似乎没有执行abs()。我想知道这个差异的原因以及我应该如何适应它。我应该以不同的方式计算abs()吗?

3 个答案:

答案 0 :(得分:2)

在2的补码(大多数现代芯片使用的整数表示)中,总有1个负值而不是正值 - 例如大多数实现的signed char从-128到127运行。如果你给出了-((signed char)-128),你期望获得什么?127是签名字符可以代表的最大正数?

你的(已签名)长期存在类似问题 - (大多数负长)无法表示并且发生溢出。 签名的整数的溢出是未定义的,所以你不会惊讶于你得到一个奇怪的结果

答案 1 :(得分:1)

你从中获得负数的原因是因为计算机读取有符号数字的方式,两个补码。如果数字类型保持4位,则此类型的边界数可以是0111 = 7和1000 = -8。当你使用abs()函数时,它会翻转这些位然后将一个加到负数中以使它们成为正数。当你这样做到最小数量时,你得到1000 =&gt;翻转位=&gt; 0111 =&gt;添加一个=&gt; 1000是相同的数字。

答案 2 :(得分:1)

查看std::abs的参考资料会告诉我们出了什么问题:

  

计算整数的绝对值。 如果结果无法由返回类型表示,则行为未定义。

所以任何事情都可能发生。它甚至解释了对于使用2对有符号整数的补码的系统的情况如何:

  

备注

     

在2的补体系统中,最负值的绝对值超出范围,例如对于32位2的补码类型int,INT_MIN是-2147483648,但是可能的结果2147483648大于INT_MAX,即2147483647。

如果您对实际标准感兴趣,请分别参考7.20.6 / 7.22.6中的C99/C11 standard,因为C ++仅引用了C标准中的函数。 <cstdlib>(有一些额外的重载)。