La funzione std::abs()
è ben definita per TUTTI i tipi aritmetici in C++ 11 e restituirà |x|
senza alcun problema di approssimazione?Sulla funzione std :: abs
Una cosa strana è che con g ++ 4.7, std::abs(char)
, std::abs(short int)
, std::abs(int)
, std::abs(long int)
e std::abs(long long int)
sembrano restituire un doppio (al contrario di: http://en.cppreference.com/w/cpp/numeric/math/abs). E se il numero è castato a un doppio, potremmo avere un errore di approssimazione per un numero molto grande (come -9223372036854775806LL = 2^63-3
).
Così ho la garanzia che restituirà sempre |x|
per tutti i tipi di aritmetica?
EDIT: qui è un programma di esempio per fare delle prove
#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;
}
cosa ti fa pensare il g ++ implementazione sta tornando un doppio? Forse potresti fornire un esempio di ciò che stai facendo che indica che viene restituito un doppio? –
Si noti che ci sono diversi 'std :: abs' in diverse intestazioni, come' 'e' '. –
Ovviamente 'std :: abs (x)' restituisce '| x |'. Forse ti starai chiedendo se 'decltype (std :: abs (x))' corrisponderà a decltype (x) '? Sono solo un po 'confuso da cosa intendi esattamente per "sarà std :: abs (x) restituire sempre | x |?" – Cornstalks