17.4.12 式の整理

二次方程式の解の1つを求める関数quadratic1を定義したら,もう1つの解,つまり (-b-√b*b-4ac)/2aを求めるquadratic2も定義してみましょう.

やり方としては,quadratic1の定義の中の+.を1ヶ所-.に書き換えるだけですから簡単そうです.しかしここでは,もう少し式を整理してから定義をし直すことを考えます.まず,quadratic1の定義をもう一度見てみましょう.

let quadratic1 (a,b,c) = 
(-.b +. sqrt(b *. b -. 4.0 *. a *. c)) /. (2.0 *. a) ;;

まず,b *. bという部分は b の自乗を計算しています.自乗を計算していることが読みとれるように,square という関数を定義して,それで置き換えてみましょう.

# let square(x) = x *. x;; return2 val square : float -> float = <fun> # let quadratic1 (a,b,c) = return2 (-.b +. sqrt(square(b) -. 4.0 *. a *. c)) /. (2.0 *. a) ;; return2 val quadratic1 : float * float * float -> float = <fun> #

このように,自分が定義した関数 square を,別の関数 quadratic1 の定義に使うことができます.Ocamlの場合,quadratic1 の中で square を使うのであれば,square は quadratic1 より先に定義しておかなければいけません.

さらに,sqrt の内側,square(b) -. 4.0 *. a *. cという部分は判別式と呼ばれています.ここも別に定義してみましょう.

# let discriminant (a,b,c) = return2 square(b) -. 4.0 *. a *. c;; return2 val discriminant : float * float * float -> float = <fun> # let quadratic1 (a,b,c) = return2 (-.b +. sqrt(discriminant(a,b,c))) /. (2.0 *. a) ;; return2 val quadratic1 : float * float * float -> float = <fun> #

discriminant は二次方程式の各項の係数 (a,b,c) が与えられたら,その判別式 b*b-4ac を求める関数です.これを使ったquadratic1の定義は,前と比べてずいぶん簡単になりました.この定義でも,複雑な定義と同じ計算ができます.

# quadratic1(1.0,2.0,1.0) ;; return2 - : float = -1 #

さて,二次方程式のもう一つの解の計算でした.判別式がすでにあるので次のように定義できます.

# let quadratic2 (a,b,c) = return2 (-.b -. sqrt(discriminant(a,b,c))) /. (2.0*.a) ;; return2 val quadratic2 : float * float * float -> float = <fun> # quadratic2 (1.0,2.0,1.0) ;; return2 - : float = -1 #

二次方程式 x^2 + 2x + 1 = 0 の解は2つとも -1 なので,ちょっとつまらない結果でしたね.