numeric_limits<long>::min() 的 C++11 abs();
C++11 abs() of numeric_limits<long>::min();
我运行关注以下
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() 吗?
在 2 的补码(大多数现代芯片使用的整数表示法)中,负值总是比正值多 1 - 例如signed char
在大多数实现中从 -128 运行到 127。如果你这样做,你期望得到什么 -((signed char)-128)
给定 127 是一个有符号字符可以表示的最大正数?
您的 (signed) long 也有类似的问题,即 -(most negative long) 不可表示并且会发生溢出。 signed 整数的溢出是未定义的,所以你得到一个奇怪的结果也就不足为奇了
你会得到负数的原因是计算机读取有符号数的方式,即二进制补码。如果数字类型包含 4 位,则此类型的边界数字可能是 0111 = 7 和 1000 = -8。当您使用 abs() 函数时,它会翻转位,然后将负数加一以使它们变为正数。当你这样做到最小数量时,你会得到 1000 => 翻转位 => 0111 => 添加一个 => 1000 这是相同的数字。
查看 std::abs
的参考资料告诉我们出了什么问题:
Computes the absolute value of an integer number. The behavior is undefined if the result cannot be represented by the return type.
所以任何事情都有可能发生。它甚至在下面解释了对有符号整数使用 2 的补码的系统的情况:
Notes
In 2's complement systems, the absolute value of the most-negative value is out of range, e.g. for 32-bit 2's complement type int, INT_MIN is -2147483648, but the would-be result 2147483648 is greater than INT_MAX, which is 2147483647.
如果您对 C99/C11 standard 的实际标准引用感兴趣,请参见第 7.20.6/7.22.6 节,因为 C++ 仅引用 [=11= 中函数的 C 标准](有一些额外的重载)。
我运行关注以下
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() 吗?
在 2 的补码(大多数现代芯片使用的整数表示法)中,负值总是比正值多 1 - 例如signed char
在大多数实现中从 -128 运行到 127。如果你这样做,你期望得到什么 -((signed char)-128)
给定 127 是一个有符号字符可以表示的最大正数?
您的 (signed) long 也有类似的问题,即 -(most negative long) 不可表示并且会发生溢出。 signed 整数的溢出是未定义的,所以你得到一个奇怪的结果也就不足为奇了
你会得到负数的原因是计算机读取有符号数的方式,即二进制补码。如果数字类型包含 4 位,则此类型的边界数字可能是 0111 = 7 和 1000 = -8。当您使用 abs() 函数时,它会翻转位,然后将负数加一以使它们变为正数。当你这样做到最小数量时,你会得到 1000 => 翻转位 => 0111 => 添加一个 => 1000 这是相同的数字。
查看 std::abs
的参考资料告诉我们出了什么问题:
Computes the absolute value of an integer number. The behavior is undefined if the result cannot be represented by the return type.
所以任何事情都有可能发生。它甚至在下面解释了对有符号整数使用 2 的补码的系统的情况:
Notes
In 2's complement systems, the absolute value of the most-negative value is out of range, e.g. for 32-bit 2's complement type int, INT_MIN is -2147483648, but the would-be result 2147483648 is greater than INT_MAX, which is 2147483647.
如果您对 C99/C11 standard 的实际标准引用感兴趣,请参见第 7.20.6/7.22.6 节,因为 C++ 仅引用 [=11= 中函数的 C 标准](有一些额外的重载)。