Chức năng std::abs()
có được xác định rõ ràng cho TẤT CẢ các loại số học trong C++ 11 và sẽ trả về |x|
mà không có vấn đề về xấp xỉ?Trên std :: abs function
Một điều kỳ lạ là với g ++ 4.7, std::abs(char)
, std::abs(short int)
, std::abs(int)
, std::abs(long int)
và std::abs(long long int)
dường như trở lại một đôi (trên trái của: http://en.cppreference.com/w/cpp/numeric/math/abs). Và nếu số được đúc thành một đôi, chúng tôi có thể có một số lỗi xấp xỉ cho số lượng rất lớn (như -9223372036854775806LL = 2^63-3
).
Vì vậy, tôi có đảm bảo rằng std::abs(x)
sẽ luôn trả lại |x|
cho tất cả các loại số học không?
EDIT: đây là một chương trình ví dụ để làm một số xét nghiệm
#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;
}
làm cho bạn nghĩ gì thi g ++ được trả lại một đôi? Có lẽ bạn có thể cung cấp một mẫu của những gì bạn đang làm cho thấy một đôi đang được trả lại? –
Lưu ý rằng có một số 'std :: abs' trong các tiêu đề khác nhau, như' 'và' '. –
Tất nhiên 'std :: abs (x)' trả về '| x |'. Có lẽ bạn đang tự hỏi nếu 'decltype (std :: abs (x))' sẽ khớp 'decltype (x)'? Tôi chỉ là một chút bối rối bởi chính xác những gì bạn có nghĩa là bởi "sẽ std :: abs (x) luôn luôn trở lại | x |?" – Cornstalks