Presumo que abs
e fabs
estão se comportando de forma diferente ao usar math.h
. Mas quando uso apenas cmath
e std::abs
, devo usar std::fabs
ou fabs
? Ou isso não está definido?
100
Em C ++, é sempre suficiente usar std::abs
; ele está sobrecarregado para todos os tipos numéricos.
Em C, abs
só funciona com inteiros e você precisa fabs
de valores de ponto flutuante. Eles estão disponíveis em C ++ (junto com toda a biblioteca C), mas não há necessidade de usá-los.
int
versão da biblioteca C, há sobrecargas paralong
,float
,double
elong double
. A cláusula 26.2.7 também define uma sobrecarga paracomplex
.std::
e apenas usarabs
, seu código funcionará como esperado no windows, mas usará aint
versão no linux, o que pode ser incrivelmente difícil de depurar.Ainda não há problema em usar
fabs
paradouble
efloat
argumentos. Eu prefiro isso porque garante que, se eu acidentalmente removerstd::
oabs
, que o comportamento permanecerá o mesmo para entradas de ponto flutuante.Acabei de passar 10 minutos depurando esse problema, devido ao meu próprio erro de usar em
abs
vez destd::abs
. Presumi que ousing namespace std;
iria inferir,std::abs
mas isso não aconteceu e, em vez disso, estava usando a versão C.De qualquer forma, acredito que seja bom usar em
fabs
vez deabs
entradas de ponto flutuante como uma forma de documentar claramente sua intenção.fonte
std::abs
sempre parece ser invocado (e não a versão C deabs
) ao chamarabs
, desde queusing namespace std;
esteja explicado no começando. Não sei se isso é específico do compilador.Há mais um motivo para recomendar
std::fabs
explicitamente entradas de ponto flutuante.Se você esquecer de incluir <cmath>, seu
std::abs(my_float_num)
pode ser emstd::abs(int)
vez destd::abs(float)
. É difícil perceber.fonte
"abs" e "fabs" são idênticos apenas para tipos de float C ++, quando podem ser traduzidos sem mensagens de sobrecarga ambíguas.
Estou usando o g ++ (g ++ - 7). Junto com o uso do template e especialmente ao usar o mpreal, há casos com mensagens de "sobrecarga ambígua" -
abs(static_cast<T>(x))
nem sempre resolvendo isso. Quando o abdômen é ambíguo, há chances de que os fabs estejam funcionando conforme o esperado. Para sqrt, não encontrei um escape tão simples.Há semanas estou lutando arduamente em C ++ "problemas não existentes". Estou atualizando um programa C ++ antigo para C ++ 14 para obter mais e melhor uso de modelos do que antes. Freqüentemente, o mesmo parâmetro de modelo pode ser real qualquer tipo float padrão ou complexo ou um tipo de classe. Por que razão, long double agiu de forma um pouco mais sensata do que outros tipos. Tudo estava funcionando, e eu havia incluído a refeição antes. Então, eu estava configurando meu tipo de float padrão para mpreal e recebi um dilúvio de erros de sintaxe. Isso gerou milhares de sobrecargas ambíguas, por exemplo, para abdominais e sqrt, clamando por soluções diferentes. Alguns precisavam de funções de ajuda sobrecarregadas, mas fora de um modelo. Tive que substituir individualmente mil utilizações de 0,0L e 1,0L pelo tipo de constante exata usando Zero ou Um ou um type_cast - definição de conversão automática impossível devido às ambigüidades.
Até maio achei muito legal a existência de conversões implícitas. Mas muito mais simples seria sem nenhum, e ter constantes typesave com type_casts explícitos seguros para qualquer outro tipo de constante padrão.
fonte