ホームページ  >  記事  >  バックエンド開発  >  C/C の cos() 関数と sin() 関数が 180 度などの一般的な角度に対して予期しない結果を生成するのはなぜですか?

C/C の cos() 関数と sin() 関数が 180 度などの一般的な角度に対して予期しない結果を生成するのはなぜですか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-11-27 12:00:16714ブラウズ

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

よく知られた角度に対する C/C の cos() と sin() からの予期しない結果

C/C の cos に 180 度の角度を適用すると() および sin() 関数を使用すると、誤った結果が生じる可能性があります。

  • sin of 0.0547
  • cos of 0.99

ただし、実際の結果は異なることがよくあります。

  • の罪3.5897934739308216e-009
  • cos of -1.00000

この矛盾は、cos(a)、sin(a)、tan(a) が C/C で機能するという事実に起因します。引数として度ではなくラジアンを期待します。 180 度からラジアンへの変換では、近似が生じる場合があります。

ラジアンの計算が正しくても、double の精度が有限であり、PI が誤って表示される可能性があるため、結果が異なる場合があります。

これに対処するには、trig 関数を呼び出す前に引数を度単位で減らすことが最善です。角度を -45° ~ 45° の間に制限することで、結果の精度が保証されます。

たとえば、引数削減を使用して sin() を度単位で計算する次のコードを考えてみましょう。

#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;
}

このコードは、三角関数を呼び出す前に引数の削減を実行するため、特に複数の角度の値について、元のアプローチよりも正確な結果を生成します。

以上がC/C の cos() 関数と sin() 関数が 180 度などの一般的な角度に対して予期しない結果を生成するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。