第 2 章 Java 言語の基本的な文法 I 5
2.17 コンソールへの出力 II
ここまで、コンソールへの出力メソッドとして、次の2つのメソッドを利用してきました。
• System.out.print():改行なし
• System.out.println():改行付き
しかし、いずれもデータを綺麗に並べて出力するなどの機能がないので、「とりあえず出力!」というものでした。
ここでは、フォーマット(出力形式)を定義し、それに沿ってデータを出力するSystem.out.printf()というメソッ ドを紹介します。これはC言語で既によく知られている出力方式です。先の2 つより少々難しくなりますが、使い方 をマスターするとこれしか使わなくなるほど便利です。
2.17.1 System.out.printf()
System.out のprintf()メソッド、とりあえず使用した例で見てみましょう。2.15.1 節で作った三角関数のテー ブルを再度作ってみます。
ソースコード2.70 TrigonometricTable2.java (printfで三角関数表) package section0217;
public class TrigonometricTable2 {
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.printf( "θ=%02dπ/%2d, cosθ=%9.6f, sinθ=%9.6f%n", k, sep, cosTheta, sinTheta );
} } }
printf()はその第1 引数にフォーマットとなる文字列を必ず置きます。この場合は
"θ=%02dπ/%2d, cosθ=%9.6f, sinθ=%9.6f%n"
ですね。このフォーマットには、書式指示子という% から始まる文字列が使われます。上のプログラムでは、
• %kd:整数系の値を出力する。kには桁数を入れます(%2d)。値は右詰めで表示され、桁数の最初に0を付ける と、その表示内の空白を0で埋めます(%02d)。
• %k.mf:実数系の値を固定小数点数表示で出力する。kには全体の文字数、mには小数点以下の桁数を書きます
(%9.6f)。k には符号や小数点も含めます。
• %n:printf()では、自動改行してくれません(print()と一緒です)。そこで、強制改行させるのが%nです。
フォーマットの後に、カンマで区切って対応する変数を並べます。上の例だと、次のような対応になりますね。
%02d %2d %9.6f %9.6f k sep cosTheta sinTheta
代表的な他の書式指示子を以下に並べましょう(表2.17.1参照)。指示子が大文字の場合は表示が大文字になります。
表2.17.1 代表的な書式指示子
書式指示子 内容
%b, %B boolean型
%c, %C char型
%e, %E 浮動小数点数表記での実数
%o 8 進数表示の整数
%s, %S 文字列
%x, %X 16進数表示の整数
数値計算系でよく使う%E表記の例を作ってみましょう。2年生の計算数学で習う「Newton法」という微分可能関 数の実数解を求めるアルゴリズムです。
ソースコード2.71 NewtonMethod.java (浮動小数点数表示:Newton法) package section0217;
public class NewtonMethod {
public static void main(String[] args) {
// f(x) = cos(1/log x) = 0 の x ≧ 1.2 の解を Newton 法で解く // f'(x) = sin(1/log x)/(x(log x)^2)
int count = 0;
double x = 1.6;
String format = "count=%d : x=%10.7f f(x)=%13.5e%n";
while( Math.abs(f(x)) > 1.0e-15 ) {
System.out.printf( format, count, x, f(x) );
x = x - f( x )/df( x );
count++;
}
System.out.printf( format, count, x, f(x) );
}
static double f(double x) {
return Math.cos(1.0/Math.log( x ));
}
static double df(double x) {
return Math.sin(1.0/Math.log( x ))/(x*Math.pow(Math.log( x ),2));
} }
この後で学ぶメソッドが使われていたりで、プログラム全体を読み取ることは難しいでしょうが、8行目のフォーマッ トの文字列と、10,14行目だけ見て、実行結果と見比べて下さい。このようにフォーマットをprintf()メソッドの外 で文字列として定義しておいて使うこともよく行われます。%10.7fが固定小数点数表示で全体 10桁で小数点以下7 桁の表示、%13.5eが浮動小数点数表示で全体13桁(符号や小数点も1文字として含む)で仮数部の小数点以下5 桁 の表示、となります。
ちなみに、Mathematicaでこの問題を解いてみると(楽だねぇ! (^^;))。 f[x_] := Cos[1/Log[x]];
Print["f(x)=", f[x]]
Print["f'(x)=", D[f[x], x]]
Plot[f[x], {x, 1, 3}]
NSolve[{f[x] == 0, x >= 1.2}, x]
f(x)=Cos 1 Log[x]
f'(x)=Sin Log[x]1 x Log[x]2
1.5 2.0 2.5 3.0
-1.0 -0.5 0.5 1.0
{{x 1.2364},{x 1.89008}}
図2.19 Mathematicaの計算結果