• 検索結果がありません。

CompoundAssign.java ( 複合代入文での隠れキャスト )

ドキュメント内 i I Java Java Java (ページ 49-53)

第 2 章 Java 言語の基本的な文法 I 5

2.22 CompoundAssign.java ( 複合代入文での隠れキャスト )

package section0211;

public class CompoundAssign {

public static void main(String[] arge) { int x = 0;

x += 2.5;

System.out.println( "x = " + x );

} }

ちなみに、x += 2.5;の部分を x = x + 2.5; と書き換えるとコンパイルエラーとなります。つまり、この2つの 処理に違いがあるということです。実は複合代入文では、裏でキャストが行われているのです。この場合は、x =

(int)( x + 2.5 );と左辺の変数の型にキャストする処理が隠れているのです。和田も、ちょっと前までこのことに

気づいていませんでした (まだまだ知らないことがあるんだなぁ)。しっかりマニュアルを読まずにプログラミング言 語を使うと、思わぬミスが隠れているかもしれないということですね。ちなみに、こんなプログラムは書かないで。読 む人を混乱させるだけです。

問題 2.11.4. 以下の代入文で変数aの値はそれぞれ幾つになりますか。

1. double a = 4 + 3 / 2 + 2; 2. double a = 4 + 3.0 / 2 + 2;

3. double a = (4 + 3) / 2 + 2; 4. double a = (double) 4 + 3 / 2 + 2;

5. double a = (double)(4 + 3) / 2 + 2; 6. double a = 4 + 3 / (2 + 2.0);

表2.12.1 比較演算子

A == B AとBは等しい 1 == 1 A != B AとBは等しくない 1 != 2 A > B AはBよりも大きい 2 > 1 A >= B AはB以上である 2 >= 1

A < B AはBより小さい 1 < 2 A <= B AはB以下である 1 <= 2

問題 2.12.1. 以下の比較式の値がtrue とfalse のいずれかを述べなさい。

1. 10 + 10 == 20 2. 2 <= 3 3. 1.5 - 0.6 > 1 4. 10 % 3 != 0 5. 0.1 == 1 / 10 6. 'B' == 'A' + 1 7. (2 <= 3) != true

2.12.2 論理演算子

式の値がboolean型、つまりtrueもしくはfalseの値になる式を論理式と呼びます。よって、関係式は論理式の 一つです。論理式を複数組み合わせるときに使う演算子を論理演算子と言い、複雑な条件を作るときに使います。論理 演算子には次の6種類があります。

表2.12.2 論理演算子 A && B

論理積 2つの論理式A とB共にtrueのときtrue になる A & B

A || B

論理和 AとBいずれかがtrue のときtrue になる A | B

!A 否定 Aがfalseのときtrue になる

A ^ B 排他的論理和 AとBの論理値が異なるとき trueになる

A B A && B A || B !A A ^ B true true true true false false true false false true false true false true false true true true false false false false true false

問題 2.12.2. int型変数 xの値を 1としたとき、次の論理式はtrueとfalseのいずれになるかを述べなさい。

1. x <= 0 2. 0 < x && x <=5 3. (x % 2 == 0)||(x % 2 == 1) 4. !(x > 2) 5. (x - 0.1) / 7 == 0.1 6. (x % 2 == 0)^(x % 2 == 1)

上の設問 2の解答を 0 < x <= 5とまとめて書いてはダメですよ(これも先輩たちの誤答から)。こう書くと、コン パイラは (0 < x) <= 5と解釈し、true <= 5これは無茶だ!とエラーメッセージを出します。

ところで、論理積と論理和にはそれぞれ2 通りの書き方、例えばA && BA & B、がありますがこの違いは何で しょう。これは、論理式の「短絡評価」(short-circuit evalution)をするかしないか、という違いです。長い関係式の 真偽値を求めているとき、それ以降を調べなくともその式の真偽値がわかる場合があります。例えば、論理積 A && B において、もし論理式Aの値がfalseと確定した場合、Bの値がtrueであろうとfalseであろうと、その論理積は false であることがわかりますよね(表2.12.2参照)。そんなときに、Bのチェックを省略するのが短絡評価です。同 様に、論理和A || Bにおいて、もし論理式 Aの値がtrue と確定した場合、Bの値がtrueであろうと falseであ ろうと、その論理積はtrue であることがわかります。この場合もBのチェックを省略するわけです。

一方、A & B やA | Bにおいては、短絡評価はせずに、Aと Bのチェックを必ず行って論理積・和の値を求めます。

特別な理由がなければ、短絡評価のA && BとA || Bを使う事になりますが、以下の例を見ると、両方の必要性も見 えます。

• 短絡評価する場合:A && B

A の処理時間に対し、Bの処理時間が大幅に大きい時、少しでも全体の処理時間を短縮したい場合

Bの処理中に実行時のエラーが起こるか否かを Aでチェックする場合。A がfalseなら、Bは実行して はならない場合(例:a != 0 && b / a > c)

• 短絡評価しない場合:A & B

AとB、いずれもその内部で補助的な処理(コンソールへの出力など)を行っている場合には真偽に関わらず、

両方をチェックしないといけない場合(例:methodA() & methodB())

問題 2.12.3. 次の論理式を Javaの式として書きなさい。なお、数直線上で ○はその点を含まず、●はその点を含む

とする。

1. 変数xの値が、5 以上の偶数であるときtrueになる式

2. 変数xの値が、以下の数直線の区間に入っているときtrueになる式

‒2 0 2 4

3. 変数xの値が、以下の数直線の区間に入っているときtrueになる式

‒2 0 2 4

4. ある2次元平面上の点の座標を表す変数をxとyとするとき、その点が原点から距離5 以内にあるときtrue になる式

問題 2.12.4. 西暦がint型変数 yearに代入されているとして、この年がうるう年ならtrue を返す式を書きなさい。

ただし、うるう年は、西暦の値が 4で割り切れる年で、例外として100で割り切れるが400 では割り切れない年は平 年とする。というルールです。

論理演算子の中で特殊なのが「排他的論理和」(Exclusive OR)です(排他的論理積というのはありません)。2 つの 命題の真偽値が異なるとtrue になる、こんな論理演算子どんな場合に利用するのでしょうか?実は、コンピュータ内 の2進数の計算でも利用しているのですが、このテキストでは解説しません。各自、排他的論理和を使う例を調べてみ て下さい。

問題 2.12.5. ちょっとJavaと離れてしまいますが。

排他的論理和は、論理積と論理和と否定を用いて表現する事ができます。次の式を真偽値表を作って確かめなさい。

(なお、式の中の=は数学の意味での等号です)

A ^ B = (A && !B) || (!A && B) = (A || B) && (!A || !B)

また、論理和と論理積は否定を用いて、互いに表現する事ができます。次の式も確かめなさい。

A && B = !(!A || !B), A || B = !(!A && !B) 以上の全ての結果から、何が言えますか?

2.12.3 if

条件分岐(brunch)とは、論理式で表されたある条件がtrueの場合に処理Aを、falseの場合に処理Bを行うと

いった処理の分岐のことで、Javaではif文を使用します。例えば、変数xの値が0 以上なら変数yに1加え、0未 満なら yから1減じる、というプログラムは、以下のようになります。

ソースコード2.23 IfElse.java (if else文)

ドキュメント内 i I Java Java Java (ページ 49-53)