¿Cuándo uso fabs y cuándo es suficiente usar std::abs?


Asumo que abs y fabs se comportan de manera diferente cuando se usa math.h. Pero cuando uso solo cmath y std::abs, ¿tengo que usar std::fabs o fabs? ¿O no está esto definido?

Author: Vivit, 2010-06-25

4 answers

En C++, siempre es suficiente usar std::abs; está sobrecargado para todos los tipos numéricos.

En C, abs solo funciona en enteros, y necesita fabs para valores de coma flotante. Estos están disponibles en C++ (junto con toda la biblioteca de C), pero no hay necesidad de usarlos.

 112
Author: Mike Seymour,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-25 13:06:30

Todavía está bien usar fabs para double y float argumentos. Prefiero esto porque asegura que si accidentalmente quito el std:: del abs, el comportamiento sigue siendo el mismo para las entradas de coma flotante.

Acabo de pasar 10 minutos depurando este mismo problema, debido a mi propio error de usar abs en lugar de std::abs. Asumí que el using namespace std; inferiría std::abs pero no lo hizo, y en su lugar estaba usando la versión C.

De todos modos, creo que es bueno usar fabs en lugar de abs para entradas de punto flotante como una forma de documentar su intención claramente.

 22
Author: Alan Turing,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-09 22:44:46

Hay una razón más para recomendar std::fabs para entradas de coma flotante explícitamente.

Si olvida incluir , su std::abs(my_float_num) puede ser std::abs(int) en lugar de std::abs(float). Es difícil de notar.

 8
Author: Kenichi Hidai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-14 07:19:25

"abs" y "fabs" solo son idénticos para los tipos flotantes de C++, cuando se pueden traducir sin mensajes de sobrecarga ambiguos.

Estoy usando g++ (g++-7). Junto con el uso de plantillas y especialmente cuando se usa mpreal, hay casos con mensajes duros de "sobrecarga ambigua" - abs(static_cast<T>(x)) no siempre está resolviendo eso. Cuando abs es ambiguo, hay posibilidades de que fabs esté funcionando como se esperaba. Para sqrt no encontré un escape tan simple.

Desde hace semanas estoy luchando duro en C++ " no existe problema". Estoy actualizando un viejo programa de C++ a C++14 para más y mejor uso de plantillas que antes. A menudo, el mismo parámetro de plantilla puede ser real cualquier tipo flotante o complejo estándar o un tipo de clase. Por qué siempre, long double actuó algo más sensato que otros tipos. Todo estaba funcionando, y había incluido a mpreal antes. Luego estaba configurando mi tipo flotante predeterminado a mpreal y tuve un diluvio de errores de sintaxis. Eso dio miles de sobrecargas ambiguas, por ejemplo, para abs y sqrt, llorando por diferentes soluciones. Algunos necesitaban funciones de ayuda sobrecargadas, pero fuera de una plantilla. Tuvo que reemplazar individualmente mil usos de 0.0 L y 1.0 L con el tipo constante exacta usando Cero o Uno o un type_cast-definición de conversión automática imposible debido a ambigüedades.

Hasta mayo me pareció muy agradable la existencia de conversiones implícitas. Pero mucho más simple sería sin ninguna, y tener constantes de typesave con type_casts explícitos seguros a cualquier otra constante estándar tipo.

 1
Author: BS3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-14 17:09:22