abs c++ c++11 c++-standard-library

abs - sqrt c++



¿Por qué se eliminó std:: pow(double, int) de C++ 11? (1)

double pow(double, int);

no ha sido eliminado de la especificación. Simplemente ha sido reformulado. Ahora vive en [c.math] / p11. Cómo se calcula es un detalle de implementación. La única firma C ++ 03 que ha cambiado es:

float pow(float, int);

Esto ahora vuelve doble:

double pow(float, int);

Y este cambio se realizó para la compatibilidad con C.

Aclaración :

26.8 [cmath] / p11 dice:

Además, habrá sobrecargas adicionales suficientes para garantizar:

  1. Si cualquier argumento correspondiente a un parámetro doble tiene un tipo double long, entonces todos los argumentos correspondientes a los parámetros dobles se convierten efectivamente en double long.

  2. De lo contrario, si cualquier argumento correspondiente a un parámetro doble tiene un tipo double o un entero, todos los argumentos correspondientes a los parámetros dobles se convierten efectivamente en dobles.

  3. De lo contrario, todos los argumentos correspondientes a los parámetros dobles se emiten efectivamente para flotar.

Este párrafo implica una gran cantidad de sobrecargas, que incluyen:

double pow(double, int); double pow(double, unsigned); double pow(double, unsigned long long);

etc.

Estas pueden ser sobrecargas reales o pueden implementarse con plantillas restringidas. Lo he implementado personalmente en ambos sentidos y estoy a favor de la implementación de plantillas restringidas.

Segunda actualización para abordar problemas de optimización:

La implementación está permitida para optimizar cualquier sobrecarga. Pero recuerda que una optimización debería ser solo eso. La versión optimizada debería devolver la misma respuesta. La experiencia de los implementadores de funciones como pow es que cuando se toma la molestia de asegurarse de que su implementación tomando un exponente integral da la misma respuesta que la implementación que toma un exponente de punto flotante, la "optimización" suele ser más lenta.

Como demostración, el siguiente programa imprime pow(.1, 20) dos veces, una vez con std :: pow y la segunda vez con un algoritmo "optimizado" aprovechando el exponente integral:

#include <cmath> #include <iostream> #include <iomanip> int main() { std::cout << std::setprecision(17) << std::pow(.1, 20) << ''/n''; double x = .1; double x2 = x * x; double x4 = x2 * x2; double x8 = x4 * x4; double x16 = x8 * x8; double x20 = x16 * x4; std::cout << x20 << ''/n''; }

En mi sistema esto se imprime:

1.0000000000000011e-20 1.0000000000000022e-20

O en notación hexagonal:

0x1.79ca10c92422bp-67 0x1.79ca10c924232p-67

Y sí, los implementadores de pow realmente se preocupan por todos esos bits en el extremo inferior.

Entonces, mientras la libertad está ahí para mezclar pow(double, int) con un algoritmo separado, la mayoría de los implementadores de los que tengo conocimiento han renunciado a esa estrategia, con la posible excepción de buscar exponentes integrales muy pequeños. Y en ese caso, generalmente es ventajoso poner ese control en la implementación con el exponente de punto flotante para obtener el máximo rendimiento de su inversión de optimización.

Mientras buscaba una forma eficiente de calcular p ^ q (exponenciación), donde q es un número entero y revisaba los estándares C ++ 98 y C ++ 11 noté que aparentemente la sobrecarga std::pow(double, int) se eliminó en C ++ 11.

En C ++ 98 26.5 / 6 tiene el double pow(double, int); firma.

En C ++ 11 26.8 todo lo que pude encontrar fueron sobrecargas tomando un par de double float , double o long double , y una nota explícita que en el caso de una mezcla de tipos de parámetros integral y doble, que la sobrecarga pow(double, double) debería ser escogido.

¿Es solo una aclaración de la intención previa, se agregaron incorrectamente en C ++ 98, se eliminaron realmente en C ++ 11 o algo más?

Obviamente, la versión pow(double, int) ofrece una buena oportunidad para la optimización, por lo que parece extraño que se eliminen. ¿Un compilador seguiría cumpliendo los estándares para proporcionar una sobrecarga tan optimizada?