libreria ejemplos c++ cmath

c++ - ejemplos - abs vs std:: abs, ¿qué dice la referencia?



sqrt c++ (1)

Las referencias oficiales dicen ... es un desastre. Pre-C ++ 11 y C11:

  • Oficialmente, incluyendo <cmath> no introdujo nada en :: ; todas las funciones estaban en std:: . En la práctica, solo la export era menos respetada y los compiladores diferentes hacían cosas muy diferentes. Si incluyó <cmath> , usó std:: everywhere, o lo que obtuvo varió de compilador a compilador.

  • C no proporcionó ninguna sobrecarga: abs tomó un int , y se declaró en <stdlib.h> , fabs tomó el double y se declaró en <math.h> .

  • Si incluyó <math.h> en C ++, no está claro lo que obtuvo, pero dado que a ninguno de los implementadores parecía importarle el estándar de todos modos (vea el primer punto arriba) ...

En términos generales, incluyó <cmath> y prefijó todos los usos con std:: , o incluyó <math.h> , y usó fabs si quería soporte para punto flotante (y los diversos sufijos para tipos distintos de int o double ).

C ++ 11 y C11 añadieron algunos nuevos cambios:

  • <cmath> ahora está permitido (pero no es obligatorio) para introducir los símbolos en :: también. Una cosa más que puede variar dependiendo de la implementación. (El objetivo aquí era hacer que las implementaciones existentes sean conformes).

  • C tiene un nuevo encabezado, <tgmath.h> , que utiliza la magia del compilador para hacer que las funciones en <math.h> comporten como si estuvieran sobrecargadas como en C ++. (Por lo tanto, no se aplica a los abs , sino solo a fabs .) Este encabezado no se agregó a C ++, por la razón obvia de que C ++ no necesita ninguna magia de compilación para esto.

Con todo, la situación ha empeorado un poco, y mis recomendaciones anteriores siguen siendo válidas. Incluya <math.h> y <stdlib.h> , y use abs / fabs y sus derivados (por ejemplo, labs , fabsf , etc.) exclusivamente, o incluya <cmath> , y use std::abs exclusivamente. Cualquier otra cosa, y se encontrará con problemas de portabiity.

Cuidado, estoy hablando de ::abs() , no std::abs()

De acuerdo con el sitio web cplusplus.com , se supone que los abs se comportan de manera diferente para el stdlib. h versión C, si incluye <cmath>

Aquí hay un extracto de esta página (que trata de ::abs , no std::abs ):

double abs (double x); float abs (float x); long double abs (long double x); Compute absolute value /* Returns the absolute value of x: |x|. These convenience abs overloads are exclusive of C++. In C, abs is only declared in <cstdlib> (and operates on int values). The additional overloads are provided in this header (<cmath>) for the integral types: These overloads effectively cast x to a double before calculations (defined for T being any integral type). */

¿¿¿De Verdad???

Esto me ha mordido al trasladar un programa a una nueva plataforma, ya que los compiladores diferentes y la implementación de bibliotecas estándar difieren aquí.

Aquí está mi programa de muestra:

#include <iostream> //#include <stdlib.h>//Necessary inclusion compil under linux //You can include either cmath or math.h, the result is the same //#include <cmath> #include <math.h> int main(int argc, const char * argv[]) { double x = -1.5; double ax = std::abs(x); std::cout << "x=" << x << " ax=" << ax << std::endl; return 0; }

Y aquí está el resultado bajo MSVC 2010:

  • No se emiten advertencias de compilación bajo MSVC 2010, y el programa se compilará incluso si no incluye math.h ni stdlib.h : parece que math.h stdlib.h siempre se incluyen en lo que sea que haga
  • La salida del programa es: x=-1.5 ax=1.5 (aparentemente correcta de acuerdo con la referencia)

Ahora aquí está el resultado bajo OSX:

  • No se emiten avisos de compilación, incluso con la -Wall (el doble al int cast no está señalado). El resultado es el mismo si reemplaza g++ por llvm-g++ . La inclusión de math.h o cmath no es necesaria para la compilación.
  • La salida del programa es: x=-1.5 ax=1

Y finalmente el resultado bajo Linux:

  • El programa no se compilará si no se incluye stdlib.h (por último, un compilador que no incluye automáticamente stdlib ). No se emite ninguna advertencia de compilación para el doble -> int cast.
  • La salida del programa es: x=-1.5 ax=1

No hay ganador claro aquí. Sé que una respuesta obvia es "prefiero std::abs a ::abs ", pero me pregunto:

  • ¿Está el sitio web cplusplus.com aquí cuando dice que los abs deberían proporcionar automáticamente una versión doble fuera del std nombres std ?
  • ¿Todos los compiladores y sus bibliotecas estándar están equivocados aquí excepto MSVC (aunque incluye math.h silencio)?