在std :: abs函数上 [英] On the std::abs function
问题描述
std :: abs()
函数是否为C ++ 11中的所有算术类型定义得很好,并将返回 | x |
没有近似问题?
Is the std::abs()
function well defined for ALL arithmetic types in C++11 and will return |x|
with no problem of approximation?
奇怪的是,对于g ++ 4.7, std :: abs(char)
, std :: abs(short int)
, std :: abs(int)
, std :: abs(long int)
和 std :: abs(long long int)
似乎返回一个双精度(与 http://en.cppreference.com/w/cpp/numeric/math/相反abs )。并且,如果将数字强制转换为双精度数,对于非常大的数字,我们可能会有一些近似误差(例如 -9223372036854775806LL = 2 ^ 63-3
)。
A weird thing is that with g++4.7, std::abs(char)
, std::abs(short int)
, std::abs(int)
, std::abs(long int)
and std::abs(long long int)
seem to return a double (on the contrary of : http://en.cppreference.com/w/cpp/numeric/math/abs). And if the number is casted to a double, we could have some approximation error for very large number (like -9223372036854775806LL = 2^63-3
).
所以我能保证 std :: abs(x)
将始终返回 | x |
是否适用于所有算术类型?
So do I have the guarantee that std::abs(x)
will always return |x|
for all arithmetic types ?
编辑:这是一个进行某些测试的示例程序
EDIT : here is an example program to make some tests
#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>
中出现:
The correct overloads are guaranteed to be present in <cmath>
/<cstdlib>
:
C ++ 11,[c.math]:
C++11, [c.math]:
除了
int
< cstdlib>
中某些数学函数的code>版本,C ++添加了long
和long long
这些函数的重载版本,具有相同的语义。
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.
添加的签名为:
long abs(long); // labs()
long long abs(long long); // llabs()
[...]
除了< cmath>
中的 double
版本的数学函数之外,这些函数的重载版本具有相同语义的函数。
C ++使用相同的语义添加了这些函数的 float
和 long double
重载版本。
In addition to the double
versions of the math functions in <cmath>
, overloaded versions of these functions, with the same semantics.
C++ adds float
and long 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
重载)。
So you should just make sure to include correctly <cstdlib>
(int
, long
, long long
overloads)/<cmath>
(double
, float
, long double
overloads).
这篇关于在std :: abs函数上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!