Maison  >  Article  >  développement back-end  >  Pourquoi les fonctions cos() et sin() de C/C produisent-elles des résultats inattendus pour des angles courants comme 180 degrés ?

Pourquoi les fonctions cos() et sin() de C/C produisent-elles des résultats inattendus pour des angles courants comme 180 degrés ?

Patricia Arquette
Patricia Arquetteoriginal
2024-11-27 12:00:16713parcourir

Why Do C/C  's cos() and sin() Functions Produce Unexpected Results for Common Angles Like 180 Degrees?

Résultats inattendus des cos() et sin() de C/C pour les angles familiers

Lors de l'application d'un angle de 180 degrés au cos de C/C () et sin(), un résultat incorrect peut survenir. Cela pourrait être surprenant puisque nous prévoyons que les résultats seront :

  • sin de 0,0547
  • cos de 0,99

Cependant, les résultats réels diffèrent souvent :

  • péché de 3.5897934739308216e-009
  • cos de -1.00000

Cet écart vient du fait que cos(a), sin(a) et tan(a) fonctionnent dans C/C attendez-vous à des radians comme argument, pas à des degrés. La conversion de 180 degrés en radians peut parfois introduire une approximation.

Même avec le calcul correct des radians, les résultats peuvent encore s'écarter en raison de la précision finie du double et d'une éventuelle fausse représentation de PI.

Pour résoudre ce problème, il est préférable de réduire l'argument en degrés avant d'invoquer la fonction trigonométrique. En limitant l'angle entre -45° et 45°, nous garantissons l'exactitude du résultat.

Par exemple, considérons le code suivant, qui calcule sin() en degrés en utilisant la réduction d'argument :

#include <math.h>
#include <stdio.h>

static double d2r(double d) {
  return (d / 180.0) * ((double) M_PI);
}

double sind(double x) {
  if (!isfinite(x)) {
    return sin(x);
  }
  if (x < 0.0) {
    return -sind(-x);
  }
  int quo;
  double x90 = remquo(fabs(x), 90.0, &quo);
  switch (quo % 4) {
    case 0:
      // Use * 1.0 to avoid -0.0
      return sin(d2r(x90)* 1.0);
    case 1:
      return cos(d2r(x90));
    case 2:
      return sin(d2r(-x90) * 1.0);
    case 3:
      return -cos(d2r(x90));
  }
  return 0.0;
}

int main(void) {
  int i;
  for (i = -360; i <= 360; i += 15) {
    printf("sin()  of %.1f degrees is  % .*e\n", 1.0 * i, DBL_DECIMAL_DIG - 1,
        sin(d2r(i)));
    printf("sind() of %.1f degrees is  % .*e\n", 1.0 * i, DBL_DECIMAL_DIG - 1,
        sind(i));
  }
  return 0;
}

Ce code génère un résultat plus précis que l'approche originale, en particulier pour les valeurs sous plusieurs angles, car il effectue une réduction des arguments avant d'appeler la fonction trigonométrique.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn