ゲームなんでも屋&プログラミングなんでも屋

ゲーム情報やプログラミングに関してのブログ

自作関数シリーズ第2回 sin関数 (C言語、Java、Python、Ruby)

このシリーズは普段ライブラリを利用して求めているような計算を自作するとしたらどのようなコードになるのかを紹介するシリーズです。といってもOpenCVやBeautiful Soupのような大規模なライブラリの関数を自作するわけではありません。大規模なライブラリは眺めてこんな感じ何だなって理解するに留めて、素直に作ってくれた人に感謝して利用しましょう。さて第2回ではsinを求める関数を自作したいと思います。ちなみに普通にsinを求めるには

C言語: include<math.h>をしてからsin関数を使う

Java: Mathクラスのsinメソッドを使う

Python: import mathをしてsin関数を使う 

Ruby: Math.sinを使う

 

自作関数シリーズ第1回(ルートを求める関数)

https://koro-game-programming.hatenablog.com/entry/2019/12/31/205914

 

さて、ます今回sinを求めるにあたって使う数学的な知識から入ります。今回sinを求めるのにはマクローリン展開という方法を使います。

これは下のような式で表される展開です。大学で理系の方なら少なくとも一度は聞いたことあると思います。

f:id:koro_game_and_programming:20200111001746p:plain

そしてf(x) = sin(x)として上の式に代入した結果が下のようになります。

 

f:id:koro_game_and_programming:20200111002301p:plain

この式を元に実際にsinを求めるプログラムを書いてみると下のようになります。ちなみにコンピューターに無限回計算させるわけにもいかないので、今回はxの19乗の項までの近似計算としています(この程度のループでもかなり良い精度となる)。ちなみに今回は変数sumを第n項までの合計を保存するための変数、tを各項を求める変数としています。そしてまずtとsumにxを代入、次にtに

-(x*x)/( (i*2)*(i*2+1) )をかけることで-x^3/3!を求め、それをsumに加えます。さらにこの操作を第10項目まで繰り返しています。

 

C言語

double my_sin(double x){
 double sum = x;
 double t = x;
 int i;
 for(i=1;i<10;i++){
  t *= -(x*x)/( (i*2)*(i*2+1) );
  sum += t;
 }
 return sum;
}

 

Java

public static double my_sin(double x){
 double sum = x;
 double t = x;
 for(int i=1;i<10;i++){
  t *= -(x*x)/( (i*2)*(i*2+1) );
  sum += t;
 }
 return sum;
}

 

Python

def my_sin(x):
 sum = x
 t = x
 for i in range(1,10):
  t *= -(x*x)/( (i*2)*(i*2+1) )
  sum += t
 return sum

 

Ruby

def my_sin(x)
 sum = x
 t = x
 for i in 1..10 do
  t *= -(x*x)/( (i.to_f*2)*(i.to_f*2+1) )
  sum += t
 end
 return sum
end

 

ちなみにマクローリン展開を使うことでcos,tan,log(1-x),exp(x)なども近似的に簡単に求めることができるので気になったら作ってみてください。