三角関数、双曲線関数、自然対数、指数関数
各関数をマクローリン展開、あるいはテイラー展開で計算するプログラムです。
各展開については、インターネットで検索してください。
三角関数は、分かり易くするため、角度入力です。
tanの計算は、ベルヌーイ数を必要とするので、ここでの計算は、sin/cosとしています。
双曲線関数は、大きな値をいれると、オーバーフローが発生します。
プログラム
unit Main; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls; type TForm1 = class(TForm) LabeledEdit1: TLabeledEdit; BitBtn1: TBitBtn; Memo1: TMemo; LabeledEdit2: TLabeledEdit; BitBtn2: TBitBtn; LabeledEdit3: TLabeledEdit; BitBtn3: TBitBtn; LabeledEdit4: TLabeledEdit; BitBtn4: TBitBtn; procedure BitBtn1Click(Sender: TObject); procedure BitBtn2Click(Sender: TObject); procedure BitBtn3Click(Sender: TObject); procedure BitBtn4Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm} // マクローリン展開(Maclaurin expansion) による 自然関数 計算 // e^x function exponential(x: double): double; var i : integer; d, bu, u: double; begin d := x; i := 2; u := x; repeat bu := u; d := d * x / i; u := u + d; inc(i); until (bu = u) or (i > 500); result := 1 + u; Form1.memo1.Lines.Append(' Loop= ' + inttostr(i - 2)); end; // ln(x) // https://qiita.com/MilkySaitou/items/614fcbb110cae5b9f797 var Loop : integer; // 再帰呼び出しがあるのでループ数外側に宣言 function logarithm(x: double): double; var i, k, j : integer; a, t, bt: double; h : double; begin if x <= 0 then begin result := 0; exit; end; a := 1; t := 0; if x >= 2 then begin t := - logarithm(1 / x); end else begin h := 1 / 2; // h = 0.5 0.5の誤差をなくすため if x < h then begin t := logarithm(h) + logarithm(x / h); end else begin i := 1; k := i; j := 1; repeat bt := t; a := a * (x - 1); t := t + a / k; inc(i); j := -j; k := i * j; until (bt = t) or (i > 1000); Loop := Loop + (i - 1); // ループ数合計 // Form1.memo1.Lines.Append(' Loop= ' + inttostr(i - 1)); end; end; result := t; end; // ln(x) = 2 artanh((x-1)/(x+1)) // artanh(x)はマクローリン展開 function logarithm_A(x: double):double; var i, k : integer; v, t, e, vb: double; begin e := (x - 1) / (x + 1); t := e; v := e; i := 3; k := 0; repeat vb := v; t := t * e * e; v := v + t / i; inc(i, 2); inc(k); until (vb = v) or (k > 100000); Form1.memo1.Lines.Append(' Loop= ' + inttostr(k)); result := v * 2; end; // マクローリン展開(Maclaurin expansion) による 三角関数 双曲線関数 計算 // sin // x (rad) function sin_program(x: double): double; var v, d, sq, u : double; i, k : integer; begin d := x; sq := x * x; u := d; i := 1; repeat v := u; k := i * 2; d := - d * sq / k / (k + 1); u := v + d; inc(i) until (v = u) or (i > 100); result := v; Form1.memo1.Lines.Append('Loop= ' + inttostr(i - 1)); end; // cos // x (rad) function cos_program(x: double): double; var d, s, e : double; i, k : integer; begin e := 1; s := 1; i := 1; k := 0; repeat d := s; e := -e * x * x / (i * (i + 1)); s := s + e; i := i + 2; inc(k); until (s = d) or (i > 100); result := s; Form1.memo1.Lines.Append('Loop= ' + inttostr(k)); end; // sinh // x function sinh_program(x: double): double; var v, d, sq, u : double; i, k : integer; begin d := x; sq := x * x; u := d; i := 1; repeat v := u; k := i * 2; d := d * sq / k / (k + 1); u := v + d; inc(i) until (v = u) or (i > 100); result := v; Form1.memo1.Lines.Append('Loop= ' + inttostr(i - 1)); end; // cosh // x function cosh_program(x: double): double; var d, s, e : double; i, k : integer; begin e := 1; s := 1; i := 1; k := 0; repeat d := s; e := e * x * x / (i * (i + 1)); s := s + e; i := i + 2; inc(k); until (s = d) or (i > 100); result := s; Form1.memo1.Lines.Append('Loop= ' + inttostr(k)); end; // sin cos tan 計算 // 0°90°180° に関しては別計算にしたほうが良いでしょう。 procedure TForm1.BitBtn1Click(Sender: TObject); var x, deg, adeg, s, c, t : double; chc : integer; begin val(Labelededit1.Text, deg, chc); if chc <> 0 then begin application.MessageBox('入力値に誤りがあります。','注意',0); exit; end; memo1.Clear; adeg := abs(deg); // |deg| repeat // -180 ~180°に設定 if adeg > 180 then adeg := adeg - 360; until adeg <= 180; if deg < 0 then adeg := -adeg; // 符号再現 memo1.Lines.Append('x(rad) = ' + floatTostr(deg) + ' / 180 * π'); x := adeg / 180 * pi; memo1.Lines.Append(' x= ' + floattostr(x)); memo1.Lines.Append(' マクローリン展開'); s := sin_program(x); memo1.Lines.Append(' sin(x)= ' + floattostr(s)); c := cos_program(x); memo1.Lines.Append(' cos(x)= ' + floattostr(c)); memo1.Lines.Append('tan = sin / cos'); t := s / c; memo1.Lines.Append(' tan(x)= ' + floattostr(t)); end; // e^x 計算 procedure TForm1.BitBtn2Click(Sender: TObject); var chc: integer; x, ex, exf : double; begin val(Labelededit2.Text, x, chc); if chc <> 0 then begin application.MessageBox('入力値Xに誤りがあります。','注意',0); exit; end; memo1.Clear; memo1.Lines.Append(' マクローリン展開'); ex := exponential(x); memo1.Lines.Append(' e^x= ' + floattostr(ex)); exf := exp(x); memo1.Lines.Append(' Math.exp(x)'); memo1.Lines.Append(' e^x= ' + floattostr(exf)); end; // ln(x) procedure TForm1.BitBtn3Click(Sender: TObject); var chc: integer; x, lnx, lnxf : double; begin val(Labelededit3.Text, x, chc); if chc <> 0 then begin application.MessageBox('入力値Xに誤りがあります。','注意',0); exit; end; memo1.Clear; if x <= 0 then memo1.Lines.Append(' X <= 0 は無効な値です。'); memo1.Lines.Append(' マクローリン展開'); loop := 0; lnx := logarithm(x); Form1.memo1.Lines.Append(' Loop= ' + inttostr(loop)); memo1.Lines.Append(' ln(x)= ' + floattostr(lnx)); memo1.Lines.Append(' ln(x) = 2 * arctanh((x-1)/(x+1))'); lnx := logarithm_A(x); memo1.Lines.Append(' ln(x)= ' + floattostr(lnx)); lnxf := 0; if x > 0 then lnxf := ln(x); memo1.Lines.Append(' Math.ln(x)'); memo1.Lines.Append(' ln(x)= ' + floattostr(lnxf)); end; // sinh, cosh, tanh procedure TForm1.BitBtn4Click(Sender: TObject); var x : double; sh, ch, th : double; chc : integer; begin val(Labelededit4.Text, x, chc); if chc <> 0 then begin application.MessageBox('入力値に誤りがあります。','注意',0); exit; end; memo1.Clear; memo1.Lines.Append(' マクローリン展開'); sh := sinh_program(x); memo1.Lines.Append(' sinh(x)= ' + floattostr(sh)); ch := cosh_program(x); memo1.Lines.Append(' cosh(x)= ' + floattostr(ch)); memo1.Lines.Append('tanh = sinh / cosh'); th := sh / ch; memo1.Lines.Append(' tanh(x)= ' + floattostr(th)); end; end.
trigonometric_function.zip
三角関数、逆三角関数、その他関数 に戻る