第 2 章 Java 言語の基本的な文法 I 5
2.15 Math クラス
ここまで、計算と言ったら五則計算のみでしたが、それでは小学生レベルの計算しかできません。平方根とか三角関 数とか、レベルを中学生に上げましょう。
2.15.1 Math クラスのクラスメソッド
平方根や三角関数は、「Mathクラスのクラスメソッド」という形で与えられています。代表的な関数を表にしてみ ましょう(表2.15.1参照)。他にもいろいろな数学関数があるので、調べてみて下さい (B.6.3 節 参照)。その中から、
まずは三角関数のテーブルを作ってみましょう。
ソースコード2.65 TrigonometricTable.java (三角関数表) package section0215;
public class TrigonometricTable {
public static void main(String[] args) { int sep = 12;
for(int k = 0; k<=sep; k++) {
double theta = Math.PI * k / sep;
double cosTheta = Math.cos(theta);
double sinTheta = Math.sin(theta);
System.out.println( "θ=" + k + "π/" + sep +
", cosθ=" + cosTheta + ", sinθ=" + sinTheta );
} } }
ここで、Math.PIは円周率πの値です。Javaでは、3.14なんて数値で円周率を与えたりしません。この名前を覚え て下さい。Math クラスには、もう 1つ数学定数があります。ネイピア数(自然対数の底に使う e= 2.71828) です。
これは Math.Eと書きます。これも覚えておきましょう。
このプログラム、出力される実数値の桁数が不揃いで読みにくいですが、ここでも実数値の計算誤差について感じるこ とができますね。(^^;)
次は、色々取りまとめて。
ソースコード2.66 MathMethods.java (基本関数の例) package section0215;
public class MathMethods {
public static void main(String[] args) { double a = -12.34;
System.out.println( a + " の絶対値は、" + Math.abs(a) );
double x = 100;
System.out.println( "log_e(" + x + ") は、" + Math.log(x) );
System.out.println( "log_10(" + x + ") は、" + Math.log10(x) );
int p = 3;
System.out.println( "e^" + p + " は、" + Math.pow(Math.E,p) );
System.out.println( "√" + p + " は、" + Math.sqrt(p) );
int m = 5;
int n = 3;
System.out.println( "max(" + m + "," + n + ") は、" + Math.max(m,n) );
System.out.println( "min(" + m + "," + n + ") は、" + Math.min(m,n) );
表2.15.1 Mathクラスのクラスメソッド 戻り値 メソッド名(引数) 内容 int abs(int)
絶対値を返す double abs(double)
double cos(double) radianに対するcos関数
double sin(double) radianに対するsin関数
double tan(double) radianに対するtan関数
double log(double) 自然対数(底がe)
double log10(double) 対数(底が10) double pow(double, double) べき乗 xy:pow(x, y) int max(int, int)
2 数の大きな方 double max(double, double)
int min(int, int)
2 数の小さな方 double min(double, double)
double sqrt(double) 平方根
double random() [0,1)間の乱数
long round(double)
小数点以下を四捨五入 int round(float)
System.out.println( "[0,1) 間の乱数2つ:" + Math.random() + "," + Math.random());
System.out.println( a + " の小数点以下を四捨五入すると、" + (int)(Math.round(a)));
} }
問題 2.15.1. 次の命令を正しい順序に並び替え、かつ幾つかのミスを修正して正しいプログラムとして完成させな
さい。
} }
static void mein(String args)
System.out.Println( '半径' + r + 'の円の面積は、' + area );
pakage section0215;
double r = 1.5;
pablic class CircleArea { double area = r * r * Math.PAI;
問題2.15.2. 三角形 ABC の2辺ABとACの長さをそれぞれ a, bとし、その 2辺の間の角度θとしたとき、三角 形ABC の面積は、(1/2)absinθ で表されます。それを計算するようにプログラムを作りなさい。なお、角度theta は度数で与えるので(以下のプログラムでは30度としている)、ラジアンに変換してMath.sin(double)に代入しな いと正しい値が求まりません。
ソースコード2.67 TriangulumArea.java (三角形の面積) package section0215;
public class TriangulumArea {
public static void main(String[] args) { double a = 1.0;
double b = 1.0;
double theta = 30.0;
// 面積の計算は必ずしも1行で書かなくても良い double area =
System.out.println( "三角形の面積は、" + area );
} }
問題 2.15.3. 乱数を作成するメソッドMath.random()を利用して、サイコロの目(1 から6 の整数の目が等確率で デタラメに出る)を出力するプログラムDice.javaを作りなさい。
4 の目が出ました 。
問題 2.15.4. 上のプログラムを改良して10回サイコロが振られるプログラムDice2.javaを作りなさい。
1 回目のサイコロの目は、4 でした 。 2 回目のサイコロの目は、6 でした 。
:
9 回目のサイコロの目は、1 でした 。 10 回目のサイコロの目は、5 でした 。
Math.random()による乱数について、一言。
コンピュータで生成する乱数は、(規則性や再現性が無い)真の乱数では無く「擬似乱数」と言って確定的な計算によっ て求められています。例えば、サイコロの目は、それまでに出た目から次の目が予測が不可能ですが、確定的な乱数は 生成法と内部状態が既知なら、予測が可能となります。そこで、真の乱数列と見分けが付かないほどに乱数ぽいか?を 統計的な処理「検定」で判断するのですが、Math.random()はあまり成績はよくありません。従って、学術的な結論 をJava で出したい場合は、検定をクリアした別の擬似乱数発生アルゴリズムを使うべきと言われています。例えば、
日本の研究者が発明した、メルセンヌ・ツイスタ (Mersenne twister)やそれを改良した SFMTという擬似乱数列生
成器は Math.random()より高速で乱数の品質もちゃんと検定を通るものとして使われています。まあ、ちょっとした
ゲームなどで乱数を使いたいなんてときは、Math.random()で十分ですがね。