在std :: abs函数上 [英] On the std::abs function

查看:116
本文介绍了在std :: abs函数上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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++ adds long and long 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆