función funcion fabs example abs c++ visual-studio-2013 cmath

c++ - funcion - ¿Cuál es la diferencia entre abs y fabs?



función abs c++ (3)

Con C ++ 11, usar abs() solo es muy peligroso:

#include <iostream> #include <cmath> int main() { std::cout << abs(-2.5) << std::endl; return 0; }

Este programa produce 2 como resultado. ( Verlo en vivo )

Siempre use std::abs() :

#include <iostream> #include <cmath> int main() { std::cout << std::abs(-2.5) << std::endl; return 0; }

Este programa produce 2.5 .

Puede evitar el resultado inesperado con el using namespace std; pero me gustaría desaconsejarlo, porque se considera una mala práctica en general y porque hay que buscar la directiva using para saber si abs() significa la sobrecarga int o la sobrecarga double .

He comprobado la diferencia entre abs y fabs en python here

Según tengo entendido, hay algunas diferencias con respecto a la velocidad y los tipos pasados, pero mi pregunta relacionada con c ++ nativo en VS

Con respecto a los VS, probé lo siguiente en Visual Studio 2013 (v120) :

float f1= abs(-9.2); // f = 9.2 float f2= fabs(-9); // Compile error [*]

Así que fabs(-9) me dará un error de compilación, pero cuando intenté hacer lo siguiente:

double i = -9; float f2= fabs(i); // This will work fine

Lo que entiendo del primer código es que no se compilará porque fabs(-9) necesita un doble, y el compilador no pudo convertir -9 a -9.0, pero en el segundo código el compilador convertirá i=-9 a i=-9.0 en tiempo de compilación, por lo que fabs(i) funcionará bien.

¿Alguna explicación mejor?

Otra cosa, ¿por qué el compilador no puede aceptar fabs(-9) y convertir el valor int al doble automáticamente como lo que tenemos en c #?

[*]: Error: more than one instance of overloaded function "fabs" matches the argument list: function "fabs(double _X)" function "fabs(float _X)" function "fabs(long double _X)" argument types are: (int)


En C ++, std::abs está sobrecargado para los tipos de punto flotante y enteros con signo. std::fabs solo trata con tipos de punto flotante (antes de C ++ 11). Tenga en cuenta que std:: es importante, la función C ::abs que está comúnmente disponible por razones heredadas solo manejará int .

El problema con

float f2= fabs(-9);

no es que no haya conversión de int (el tipo de -9 ) a double , sino que el compilador no sabe qué conversión elegir ( int -> float , double , long double ) ya que hay una std::fabs para cada uno de esos tres. Su solución le dice explícitamente al compilador que use la conversión int -> double , por lo que la ambigüedad desaparece.

C ++ 11 resuelve esto agregando double fabs( Integral arg ); que devolverá el abs de cualquier tipo de entero convertido al double . Aparentemente, esta sobrecarga también está disponible en modo C ++ 98 con libstdc ++ y libc ++.

En general, solo use std::abs , hará lo correcto. ( Interfaz interesante señalada por @Shafik Yaghmour . Los tipos de enteros sin signo hacen cosas graciosas en C ++).


My Visual C ++ 2008 no sabía cuál elegir entre long double fabs(long double) , float fabs(float) o double fabs(double) .

En la declaración double i = -9; , el compilador sabrá que -9 debe convertirse al double porque el tipo de i es double .

abs() se declara en stdlib.h y tratará con el valor int .

fabs() se declara en math.h y tratará con el valor double .