HOWTO · C++

Funciones trigonométricas en C++

Este artículo demuestra cómo utilizar funciones trigonométricas de STL en C++

En esta página

C++ ofrece funciones de seno, coseno, tangente, trigonométricas inversas e hiperbólicas en la cabecera estándar <cmath>. Las funciones trigonométricas ordinarias reciben ángulos en radianes y devuelven valores de punto flotante. Usa los nombres con el prefijo std:: para dejar claro que el código se refiere a la biblioteca estándar.

Usa std::sin, std::cos y std::tan con ángulos en radianes

Llama a std::sin(angle), std::cos(angle) y std::tan(angle) para calcular el seno, el coseno y la tangente de un ángulo. Incluye <cmath> para obtener sus declaraciones. Estas funciones tienen sobrecargas para tipos de punto flotante; el resultado utiliza el tipo de punto flotante correspondiente (los argumentos enteros se convierten para usar una sobrecarga de punto flotante).

Ejecuta este ejemplo:

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

#include <cmath>
#include <iomanip>
#include <iostream>

int main() {
  const double angle = 1.0; // radians
  std::cout << std::fixed << std::setprecision(6)
            << "sin(" << angle << ") = " << std::sin(angle) << '\n'
            << "cos(" << angle << ") = " << std::cos(angle) << '\n'
            << "tan(" << angle << ") = " << std::tan(angle) << '\n';
}

La salida observada en esta ejecución es:

sin(1.000000) = 0.841471
cos(1.000000) = 0.540302
tan(1.000000) = 1.557408

El argumento es un radián. std::fixed y std::setprecision(6) dan formato a cada valor devuelto con seis dígitos después del separador decimal.

Usa funciones trigonométricas inversas para recuperar ángulos

Usa std::asin(x) para recuperar un ángulo a partir de un valor de seno, std::acos(x) a partir de un valor de coseno y std::atan(x) a partir de un valor de tangente. Sus resultados se expresan en radianes. asin acepta valores entre -1 y 1 y devuelve un ángulo en [-π/2, π/2]; acos acepta el mismo intervalo de entrada y devuelve un ángulo en [0, π]. atan acepta cualquier valor real finito y devuelve un ángulo en (-π/2, π/2).

Si una dirección se describe mediante ambas coordenadas, usa std::atan2(y, x). A diferencia de atan(y / x), esta función usa los signos de los dos argumentos para elegir el cuadrante y no exige dividir primero las coordenadas. Su resultado es un ángulo en radianes, normalmente en [-π, π] (la representación exacta del extremo puede depender de si la entrada es cero con signo).

Las funciones inversas devuelven un ángulo principal, no todos los ángulos que podrían haber producido el valor original. Por ejemplo, varios ángulos comparten el mismo valor de seno, por lo que asin por sí sola no puede recuperar el ángulo original si está fuera de su intervalo principal. Al elegir el ángulo final, ten en cuenta la geometría del problema y la información sobre el cuadrante.

Usa funciones hiperbólicas para valores hiperbólicos

Las funciones std::sinh, std::cosh y std::tanh calculan el seno, el coseno y la tangente hiperbólicos. Se definen a partir de funciones exponenciales y no sustituyen a std::sin, std::cos y std::tan: reciben valores reales, no ángulos de una circunferencia, y sus rangos son distintos. Por ejemplo, cosh(x) es como mínimo 1, mientras que el coseno ordinario se mantiene entre -1 y 1.

Las funciones hiperbólicas inversas son std::asinh, std::acosh y std::atanh. Sus dominios en los números reales son distintos: asinh acepta cualquier entrada real, acosh requiere una entrada igual o superior a 1, y atanh requiere una entrada estrictamente entre -1 y 1. Elige estas funciones para relaciones hiperbólicas; no basta con añadir una a al nombre de una función trigonométrica ordinaria.

Controla las unidades de los ángulos, los dominios y los resultados de punto flotante

Las funciones trigonométricas de <cmath> en C++ esperan radianes. Convierte los grados con radians = degrees * π / 180; por ejemplo, 90 grados equivalen a π/2 radianes. En C++ portable, obtén π con std::acos(-1.0) o define la constante que necesites, ya que M_PI no es un nombre estándar de C++.

Los argumentos de las funciones inversas deben estar dentro de sus dominios reales. Comprueba o limita un valor solo cuando eso sea coherente con las matemáticas de tu aplicación: limitar un valor que apenas supera [-1, 1] puede compensar errores de redondeo acumulados, pero no debe ocultar una entrada realmente fuera de rango. Los errores de dominio se gestionan según el comportamiento de la biblioteca matemática de C++ y su implementación; no constituyen comportamiento indefinido. Si tu aplicación necesita distinguir un resultado válido de un error matemático, consulta math_errhandling y comprueba los indicadores de error pertinentes que admita la implementación.

std::tan aumenta mucho cerca de los múltiplos impares de π/2 y no tiene un valor real finito en esos polos matemáticos. Una aproximación de punto flotante a un polo puede producir un resultado finito muy grande, en vez de una señal de error clara. Si importa el comportamiento cerca de un polo, comprueba la entrada según las necesidades y la tolerancia de tu aplicación.

Los cálculos de punto flotante son aproximaciones. Valores como std::sin(std::acos(-1.0)) pueden estar cerca de cero sin ser exactamente cero. Compara los valores calculados con una tolerancia adecuada para tu aplicación en lugar de exigir igualdad exacta. Usa double para cálculos habituales y elige un tipo de mayor precisión solo si necesitas esa precisión y la implementación lo admite. Da preferencia a la biblioteca estándar frente a las aproximaciones escritas a mano y guarda un valor calculado si vas a reutilizarlo.