前回は、変数にデータを格納できること、および、変数に再びデータを格納すれば変数の値を変えられることを説明しました。 例えば、変数 x の値を1増加させるには、
x = x + 1;
という代入文を書けばよいです。 変数の値を1増加させることはよく行われるので、省略形が用意されています。 この場合なら、
x++;
と書けます。 変数 y の値を1減少させる、
y = y - 1;
という代入文も、
y--;
と省略できます。
1増加や1減少させるのでなく、いくらか増加やいくらか減少させるための省略形もあります。 以下の表を参照してください。
代入文 | 省略形 |
---|---|
変数 = 変数 + 式; |
変数 += 式; |
変数 = 変数 - 式; |
変数 -= 式; |
変数 = 変数 * 式; |
変数 *= 式; |
変数 = 変数 / 式; |
変数 /= 式; |
変数 = 変数 % 式; |
変数 %= 式; |
以下のプログラムでは、変数 x の値を10増加させて、1増加させています。
/* 1*/ class AssignmentTest { // 代入文のテスト /* 2*/ public static void main (String[] args) { /* 3*/ int x = 100; /* 4*/ System.out.println(x); /* 5*/ x += 10; // 10増加 /* 6*/ System.out.println(x); /* 7*/ x++; // 1増加 /* 8*/ System.out.println(x); /* 9*/ } /* 10*/ }
asiaa1:~/comp2b b08a001$ java AssignmentTest 100 110 111 asiaa1:~/comp2b b08a001$
Javaでは、整数だけでなく、実数も扱えます。 ここで言う実数は、数学で言う実数と多少異なります。 例えば、数学の円周率は、小数点の後に無限に数字を並べます。 それに対して、Javaの円周率は、小数点の後に15桁しか数字を並べません。 つまり、Javaの実数はわずかに誤差を含んでいるのです。
Javaでは、整数と実数は厳格に区別されます。
実数を書くべき所に整数を書くと、計算結果が変わる場合があります。
確実に実数を表記するには、小数点を用いるのが簡単です。
つまり、実数 0, 1, 2, ... を、
0.0
,
1.0
,
2.0
, ... と書くのです。
もちろん、実数 1.23 なら、そのまま
1.23
と書きます。
実数を書き表すもう一つの方法は、
指数表記
(
exponential notation
)です。
これは、例えば 12300000.0 を 1.23×10
7
と考えて、
1.23E7
と表記する方法です。
つまり、実数の小数点をずらして x.xxx または -x.xxx にし、
E
の後にずらした桁数を書くということです。
指数表記は、非常に大きな数や非常に小さな数を書き表す時に便利です。
以下の表を見て理解してください。
実数 | 指数表記 |
---|---|
12300000.0 | 1.23E7 |
1230000.0 | 1.23E6 |
123000.0 | 1.23E5 |
12300.0 | 1.23E4 |
1230.0 | 1.23E3 |
123.0 | 1.23E2 |
12.3 | 1.23E1 |
1.23 | 1.23E0 |
0.123 | 1.23E-1 |
0.0123 | 1.23E-2 |
0.00123 | 1.23E-3 |
0.000123 | 1.23E-4 |
以下のプログラムは、この表の実数を指数表記で書いています。 Javaでは、数が大きすぎたり小さすぎたりすると指数表記に切り替わります。
/* 1*/ class ExponentTest { // 指数表記のテスト /* 2*/ public static void main (String[] args) { /* 3*/ System.out.println(1.23E7); // 12300000.0 /* 4*/ System.out.println(1.23E6); // 1230000.0 /* 5*/ System.out.println(1.23E5); // 123000.0 /* 6*/ System.out.println(1.23E4); // 12300.0 /* 7*/ System.out.println(1.23E3); // 1230.0 /* 8*/ System.out.println(1.23E2); // 123.0 /* 9*/ System.out.println(1.23E1); // 12.3 /* 10*/ System.out.println(1.23E0); // 1.23 /* 11*/ System.out.println(1.23E-1); // 0.123 /* 12*/ System.out.println(1.23E-2); // 0.0123 /* 13*/ System.out.println(1.23E-3); // 0.00123 /* 14*/ System.out.println(1.23E-4); // 0.000123 /* 15*/ } /* 16*/ }
asiaa1:~/comp2b b08a001$ java ExponentTest 1.23E7 1230000.0 123000.0 12300.0 1230.0 123.0 12.3 1.23 0.123 0.0123 0.00123 1.23E-4 asiaa1:~/comp2b b08a001$
整数と同様に、実数でも四則演算が行えます。 特に、割り算については意味が変わります。 整数のときは、7÷2 = 3 余り 1 でしたが、実数のときは、7.0÷2.0 = 3.5 です。
以下のプログラムは、実数の四則演算の例です。
/* 1*/ class OperationTest { // 四則演算のテスト /* 2*/ public static void main (String[] args) { /* 3*/ System.out.println(2.5 + 0.1); /* 4*/ System.out.println(2.5 - 0.1); /* 5*/ System.out.println(2.5 * 0.1); /* 6*/ System.out.println(2.5 / 0.1); /* 7*/ } /* 8*/ }
asiaa1:~/comp2b b08a001$ java OperationTest 2.6 2.4 0.25 25.0 asiaa1:~/comp2b b08a001$
ここで、実数の四則演算の結果は実数であることに注意してください。 この例なら、2.5÷0.1 は整数 25 ではなく実数 25.0 です。
注意: 実数 + 整数 の場合は、整数を実数に変換してから足し算をします。 他の演算についても同様です。
Javaの実数がわずかに誤差を含むことは、すでに説明しました。 この誤差は、普通の計算を行う場合は、ほとんど問題になりません。 問題があるとすれば、数学では A = B となる関係が、Javaでは A ≒ B (ほとんど等しい)になりうる点です。
次のプログラムでは、1.0÷32.0×32.0 と 1.0÷49.0×49.0 を計算しています。 数学では両方とも 1.0 と等しいはずですが、Java では「ほとんど等しい」場合があります。
/* 1*/ class PrecisionTest { // 精度のテスト /* 2*/ public static void main (String[] args) { /* 3*/ System.out.println(1.0 / 32.0 * 32.0); // 数学的には1.0 /* 4*/ System.out.println(1.0 / 49.0 * 49.0); // 数学的には1.0 /* 5*/ } /* 6*/ }
asiaa1:~/comp2b b08a001$ java PrecisionTest 1.0 0.9999999999999999 asiaa1:~/comp2b b08a001$
前回は、変数に整数を格納しました。 変数に実数を格納することもできます。 整数と同様、変数を利用する前に、変数の宣言が必要です。 整数を格納すると宣言した変数を、 整数型 ( integer type )の変数と言い、実数を格納すると宣言した変数を、 実数型 ( real type )の変数と言います。 なお、実数型の変数に整数は格納できませんし、整数型の変数に実数は格納できません。
Javaでは、実数型の変数の宣言は、
int
の代わりに
double
を書きます。
なお、実数型という言葉はJavaにはありません。
Javaでは、
浮動小数点数型
(
floating point number type
)と言います。
次のプログラムは、変数を宣言し、実数を格納し、それを取り出しています。
/* 1*/ class DoubleTest { // 実数型の変数のテスト /* 2*/ public static void main (String[] args) { /* 3*/ double d; // 宣言文 /* 4*/ d = 1.23; // 代入文 /* 5*/ System.out.println(d); /* 6*/ } /* 7*/ }
asiaa1:~/comp2b b08a001$ java DoubleTest 1.23 asiaa1:~/comp2b b08a001$
実数型の変数に整数を格納するには、整数を実数に変換してから格納します。
実数に変換するには、
(double)
を左側に書きます。
式の場合は、混乱しないように適宜括弧を書いてください。
このような変換を、
キャスト
(
cast
)と言います。
次のプログラムでは、整数を実数にキャストして割り算を行っています。
/* 1*/ class CastTest { // キャストのテスト /* 2*/ public static void main (String[] args) { /* 3*/ int x = 7, y = 2; /* 4*/ double d, e; /* 5*/ System.out.println(x / y); // 7/2=3余り1 /* 6*/ d = (double) x; // 7を7.0に変換 /* 7*/ e = (double) y; // 2を2.0に変換 /* 8*/ System.out.println(d / e); // 7.0/2.0=3.5 /* 9*/ System.out.println(((double) x) / ((double) y)); // その場で変換 /* 10*/ } /* 11*/ }
asiaa1:~/comp2b b08a001$ java CastTest 3 3.5 3.5 asiaa1:~/comp2b b08a001$
整数型の変数に実数を格納するときも、実数を整数に変換します。
整数に変換するには、
(int)
を左側に書きます。
整数に変換する際に、小数点以下は切り捨てられます。
次のプログラムでは、実数を整数にキャストして割り算を行っています。
/* 1*/ class CastTest2 { // キャストのテスト2 /* 2*/ public static void main (String[] args) { /* 3*/ double d = 7.0, e = 2.0; /* 4*/ int x, y; /* 5*/ System.out.println(d / e); // 7.0/2.0=3.5 /* 6*/ x = (int) d; // 7.0を7に変換 /* 7*/ y = (int) e; // 2.0を2に変換 /* 8*/ System.out.println(x / y); // 7/2=3余り1 /* 9*/ System.out.println(((int) d) / ((int) e)); // その場で変換 /* 10*/ } /* 11*/ }
asiaa1:~/comp2b b08a001$ java CastTest2 3.5 3 3 asiaa1:~/comp2b b08a001$
注意: 実数から整数へのキャストを忘れると、大抵エラーになりますが、整数から実数へのキャストを忘れても、自動的に変換される場合が多いです。
Javaには、数学的な定数と関数が用意されています。
これらには、
Math.
から始まる名前が付いています。
数学的な定数については、いくつかありますが、基本的なものは以下の通りです。
定数名 | 意味 |
---|---|
Math.PI |
円周率 |
数学的な関数については、色々用意されていますが、基本的なものは以下の通りです。
関数名 | 意味 |
---|---|
Math.abs |
絶対値 |
Math.floor |
床関数(それ以下の最大の整数) |
Math.ceil |
天井関数(それ以上の最小の整数) |
Math.rint |
丸め関数(最も近い整数。2つあるなら偶数のほう。) |
Math.sqrt |
平方根 |
以下のプログラムでは、数学的な定数と関数を用いています。
/* 1*/ class MathematicsTest { // 数学的なテスト /* 2*/ public static void main (String[] args) { /* 3*/ System.out.println(Math.PI); // π /* 4*/ System.out.println(Math.abs(-0.1)); // -0.1の絶対値は0.1 /* 5*/ System.out.println(Math.floor(2.5)); // 2.5の床は2.0 /* 6*/ System.out.println(Math.ceil(2.5)); // 2.5の天井は3.0 /* 7*/ System.out.println(Math.rint(2.5)); // 2.5を丸めると2.0 /* 8*/ System.out.println(Math.sqrt(3.0)); // √3.0 /* 9*/ } /* 10*/ }
asiaa1:~/comp2b b08a001$ java MathematicsTest 3.141592653589793 0.1 2.0 3.0 2.0 1.7320508075688772 asiaa1:~/comp2b b08a001$
実数の使用例として、次の問題を考えます。
半径(radius)が 10.0 の円(circle)の面積(area)を求めなさい。
この問題を解決するには、式 10.0×10.0×3.14 を計算するのが簡単です。
/* 1*/ class CircleArea { // 円の面積 /* 2*/ public static void main (String[] args) { /* 3*/ System.out.println(10.0 * 10.0 * 3.14); /* 4*/ } /* 5*/ }
asiaa1:~/comp2b b08a001$ java CircleArea 314.0 asiaa1:~/comp2b b08a001$
しかし、これでは、何の計算をするプログラムなのか、分からなくなりそうです。
変数を適切に利用すると、後でプログラムを見ても大丈夫です。
また、円周率は、3.14 でなく
Math.PI
を使っています。
/* 1*/ class CircleArea2 { // 円の面積2 /* 2*/ public static void main (String[] args) { /* 3*/ double radius = 10.0; /* 4*/ double area; /* 5*/ area = radius * radius * Math.PI; /* 6*/ System.out.println(area); /* 7*/ } /* 8*/ }
asiaa1:~/comp2b b08a001$ java CircleArea2 314.1592653589793 asiaa1:~/comp2b b08a001$
次の問題を考えます。
上底(top base)が 3.5 で下底(bottom base)が 4.5 で高さ(height)が 2.5 の台形(trapezoid)の面積(area)を求めなさい。
この問題を解決するアルゴリズムを考え、プログラムを作成してください。 プログラムでは、変数を適切に利用してください。
asiaa1:~/comp2b b08a001$ java TrapezoidArea 10.0 asiaa1:~/comp2b b08a001$
余力のある人は、小学校、中学校で習った算数、数学、理科の公式を思い出し、同じような問題を自分で考え、答えを求めるプログラムを作成してください。 プログラムは、何を計算したかが分かるようにしてください。
今日の演習4の答案(Javaプログラム)をメールで提出してください。 差出人は学内のメール・アドレス(b08a001@cis.twcu.ac.jpなど)とし、宛先はkonishi@cis.twcu.ac.jpとします。 メールの本文には、学生番号、氏名、科目名、授業日(5月20日)を明記してください。