17.4.15 解の個数の判断

二次方程式 ax^2 + bx + c = 0 は,a, b, cの値によって解が2つだったり,1つだったり,1つもなかったりします.

といった具合です.

この解の個数は,判別式が正,負あるいはゼロになることで区別できることはよく知られていますね.例えば,x^2-5x+6=0は判別式 discriminant(1.0,-5.0,6.0)の値が正になるので,解が2個あることが分かります.

プログラムでは判断も計算の一種として扱います.例えば「判別式が正になるか」という判断は,次のようにして調べることができます.

# discriminant(1.0,-5.0,6.0) > 0.000001;; return2 - : bool = true #

この例でdiscriminant(1.0,-5.0,6.0) > 0.000001は,2.0*.3.0などと同様に計算式です.掛け算を表わす*.という記号(演算子)のかわりに,数の大小を比較する>という記号が使われている点だけが違いです.

なお, 0ではなく0.000001という数と比較しているのは,計算誤差に対処するためです.計算機の実数計算では,重解を持つような場合でも判別式がぴったり0にはならず,0に近い非常に小さな値となる場合があります.0.000001と比べれば,そのような場合に解が2個あると判断してしまうことを避けられる訳です.

一方,計算結果は数値ではなく true と出力されています.これは日本語にすると「真」つまり,「discriminant(1.0,-5.0,6.0)0.000001より大きいか」という判断は「正しい」という結果だったことを表わしています.

逆に「正しくない」つまり「偽」を表わす結果は「false」と出力されます.

大小の比較には,いくつかバリエーションがありますので例をいくつか見ておきましょう.

# let eps = 0.000001;; return2 (* 0.00001にepsという名前を付けておきます *) val eps : float = 1e-06 # eps < discriminant(1.0, -5.0, 6.0) ;; return2 (* < は「小さいか」という判断です *) - : bool = true # discriminant(1.0, 2.0, 1.0) = 0.0;; return2 (* = は「等しいか」という判断です *) - : bool = true # discriminant(1.0, 2.0, 1.0) <> 0.0;; return2 (* <> は「等しくないか」という判断です *) - : bool = false # discriminant(1.0, 2.0, 2.0) >= eps;; return2 (* >= は「大きいかあるいは等しいか」という判断です *) - : bool = false # discriminant(1.0, 2.0, 2.0) <= eps;; return2 (* >= は「小さいかあるいは等しいか」という判断です *) - : bool = true #

上で, 判別式と0を = で比較した結果はtrueになっていますが,解析的に0となる場合でも計算結果が0と等しくならない場合もあるので注意が必要です.