std::abs()
函数是否为 C++11 中的所有算术类型定义良好,并且将返回 |x|
而没有近似问题?
奇怪的是,对于 g++4.7,std::abs(char)
, std::abs(short int)
, std: :abs(int)
, std::abs(long int)
和 std::abs(long long int)
似乎返回一个 double (在相反:http://en.cppreference.com/w/cpp/numeric/math/abs)。如果将数字转换为 double ,对于非常大的数字(如 -9223372036854775806LL = 2^63-3
),我们可能会有一些近似误差。
那么我是否保证 std::abs(x)
将始终为所有算术类型返回 |x|
?
编辑:这是一个进行一些测试的示例程序
#include <iostream>
#include <iomanip>
#include <cmath>
#include <typeinfo>
template<typename T>
void abstest(T x)
{
static const unsigned int width = 16;
const T val = x;
if (sizeof(val) == 1) {
std::cout<<std::setw(width)<<static_cast<int>(val)<<" ";
std::cout<<std::setw(width)<<static_cast<int>(std::abs(val))<<" ";
} else {
std::cout<<std::setw(width)<<val<<" ";
std::cout<<std::setw(width)<<static_cast<T>(std::abs(val))<<" ";
}
std::cout<<std::setw(width)<<sizeof(val)<<" ";
std::cout<<std::setw(width)<<sizeof(std::abs(val))<<" ";
std::cout<<std::setw(width)<<typeid(val).name()<<" ";
std::cout<<std::setw(width)<<typeid(std::abs(val)).name()<<std::endl;
}
int main()
{
double ref = -100000000000;
abstest<char>(ref);
abstest<short int>(ref);
abstest<int>(ref);
abstest<long int>(ref);
abstest<long long int>(ref);
abstest<signed char>(ref);
abstest<signed short int>(ref);
abstest<signed int>(ref);
abstest<signed long int>(ref);
abstest<signed long long int>(ref);
abstest<unsigned char>(ref);
abstest<unsigned short int>(ref);
abstest<unsigned int>(ref);
abstest<unsigned long int>(ref);
abstest<unsigned long long int>(ref);
abstest<float>(ref);
abstest<double>(ref);
abstest<long double>(ref);
return 0;
}
最佳答案
保证<cmath>
中存在正确的重载/<cstdlib>
:
C++11,[c.math]:
In addition to the
int
versions of certain math functions in<cstdlib>
, C++ addslong
andlong long
overloaded versions of these functions, with the same semantics.The added signatures are:
long abs(long); // labs() long long abs(long long); // llabs()
[...]
In addition to the
double
versions of the math functions in<cmath>
, overloaded versions of these functions, with the same semantics. C++ addsfloat
andlong double
overloaded versions of these functions, with the same semantics.float abs(float); long double abs(long double);
所以你应该确保正确地包含 <cstdlib>
( int
, long
, long long
过载)/<cmath>
(double
、float
、long double
过载)。
关于c++ - 在 std::abs 函数上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13460750/