私が気にする100の事象

気にしなければ始まらない。

sin関数

概要

C言語でサイン値を計算する関数です。 <math.h>#includeすることによって使うことができます。

定義

定義は次の通りになります。

double sin(double)
機能 内容
第1引数 double 任意のラジアンx
返り値 double 正弦値 sin(x)

仕様

ISO/IEC 9899:1999 における仕様を示します。

7.12.4.6 The sin functions
Synopsis
1 #include <math.h> double sin(double x);
float sinf(float x);
long double sinl(long double x);
Description
2 The sin functions compute the sine of x (measured in radians). Returns
3 The sin functions return sin x.

また、JIS X 3010:2003 における仕様を示します。

7.12.4.6 sin 関数群
形式 #include <math.h>
double sin(double x);
float sinf(float x);
long double sinl(long double x);
機能 sin 関数群は,x(ラジアン値)の正弦を計算する。
返却値 sin 関数群は,正弦値を返す。

使用例

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

#define PI 3.14159265358979323846

int main() {
    printf("%lf\n", sin(0.0));
    printf("%lf\n", sin(PI / 6.0));
    printf("%lf\n", sin(PI / 4.0));
    printf("%lf\n", sin(PI / 3.0));
    printf("%lf\n", sin(PI / 2.0));
    printf("%lf\n", sin(PI));
    return 0;
}

結果は以下のようになります。
コンパイラgcc (GCC) 5.4.0

$ ./a.exe
0.000000
0.500000
0.707107
0.866025
1.000000
0.000000

実装例

#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

double sin(double x) {
    double sum, k;
    int i;
    sum = k = x -= (int)(x / (2 * M_PI)) * 2 * M_PI;
    for (i = 2;; i += 2) {
        k *= -(x * x) / (i * (i + 1));
        if (sum == sum + k) return sum;
        else sum += k;
    }
}
最悪計算時間 最良計算時間 平均計算時間 最悪空間計算量
 O(1)
 O(1)
 O(1)
 O(1)
 \sin x={\displaystyle\sum_{k=0}^{\infty}}(-1)^k\dfrac{x^{2k+1}}{(2k+1)!}

上のマクローリン展開を用いて実装することができるはずです。多分。 以下の図は0.000244140625ごとにxの値を変えたときのfor文の中身の実行回数です。
なお、for文の繰り返し回数は24回以内に収まるようです。

f:id:skytomo:20180513192938p:plain
sin関数における収束回数
sin関数のマクローリン展開は以下の記事を参考にするといいです。

最終更新日: 2018-05-21

提供・協力
Illust: たーぼえんじん
(Twitter: @rakugaki_tabo)
Writer: SKYともちゃん
(Twitter: @skytomo221)