Is the std::abs()
为 C++11 中的所有算术类型明确定义的函数,并将返回|x|
没有近似问题吗?
奇怪的是,对于 g++4.7,std::abs(char)
, std::abs(short int)
, std::abs(int)
, std::abs(long int)
and std::abs(long long int)
似乎返回一个双精度(与以下相反:http://en.cppreference.com/w/cpp/numeric/math/abs http://en.cppreference.com/w/cpp/numeric/math/abs)。如果数字被转换为双精度数,对于非常大的数字,我们可能会出现一些近似误差(例如-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]:
除了int
某些数学函数的版本<cstdlib>
, C++ 添加long
and long long
这些函数的重载版本,具有相同的语义。
添加的签名是:
long abs(long); // labs()
long long abs(long long); // llabs()
[...]
除了double
数学函数的版本<cmath>
,这些函数的重载版本,具有相同的语义。
C++ 添加float
and long double
这些函数的重载版本,具有相同的语义。
float abs(float);
long double abs(long double);
所以你应该确保正确包含<cstdlib>
(int
, long
, long long
过载)/<cmath>
(double
, float
, long double
过载)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)