解答例(10月17日分)



練習2-1
半径15の円と半径3.14の円があったとする。
このとき、それぞれの円の面積と円周を計算するプログラムを書け。
ただし、円周率は3.14とする。

解答例(g050155さん)
class Circle {//円の面積と円周
  public static void main(String[] args) {
    //半径15の円の面積と円周
    System.out.println(15*15*3.14); //面積
    System.out.println(15*2*3.14); //円周
    //半径3.14の円の面積と円周
    System.out.println(3.14*3.14*3.14); //面積
    System.out.println(3.14*2*3.14); //円周
  }
}


練習2-2
練習2-1で作ったプログラムを変数を使って書き直し、
円周率を3.1415926535としてみよ。

解答例(g050155さん)
class circle {//円の面積と演習
  public static void main(String[] args) {
    //半径15の円の面積と円周
    double principal = 15; //半径
    double interest = 3.1415926535; //円周率
    double square = principal*principal*interest;
    System.out.println(square); //表示
    double length = principal*2*interest;
    System.out.println(length); //表示
    //半径3.14の円の面積と円周
   double principal2 = 3.14; //半径
   double interest2 = 3.1415926535; //円周率
   double square2 = principal2*principal2*interest2;
   System.out.println(square2); //表示
   double length2 = principal2*2*interest;
   System.out.println(length2); //表示
  }
}


練習2-3
Java言語では、整数の計算は32ビット(int型)で、行われるのが普通である。
(例外:long型を使った計算。)
計算結果が32ビットを超える値になったとき、何が起きるかを調べよ。

解答例(佐々木俊也さん)
class Overflow { //桁あふれ
  public static void main(String[] args) {
    int i=2000000000; //整数1
    int j=2000000000; //整数2
    int k=i+j; //kにi+jを代入する(32ビットを越えている)
    System.out.println(k);
  }
}
実行結果
-294967296

コメント
2の32乗は4294967296。
すなわち、
2000000000+2000000000=4294967296-294967296
である。
つまり、32ビットを越えると、
(正しい値)−4294967296
が表示される。

応用
class Overflow2 { //桁あふれその2
  public static void main(String[] args) {
    int i=2000000000; //整数1
    int j=2000000000; //整数2
    int k=(i+j)*2; //kに(i+j)*2を代入する(32ビットを越えている)
    System.out.println(k);
  }
}
実行結果
-589934592

コメント
8000000000+589934592=4294967296*2
であるから、
4294967296の2倍を越えると、
(正しい値)−4294967296*2
(正しい値)−4294967296*2
が表示される。
おそらくその先も同様に続いていくのだろう。


練習2-4
int型の変数にdouble型の値を入れてもエラーになるが、その逆はエラーにならない。
このようなエラーにならない組み合わせはどのようなものがあるかを調べよ。

解答例(佐々木俊也さん)
代入する変数の型<-代入する値の型
byte<-short NG
byte<-int NG
byte<-long NG
byte<-float NG
byte<-double NG
byte<-boolean NG
short<-byte OK
short<-int NG
short<-long NG
short<-float NG
short<-double NG
short<-boolean NG
int<-byte OK
int<-short OK
int<-long NG
int<-float NG
int<-double NG
int<-boolean NG
long<-byte OK
long<-short OK
long<-int OK
long<-float NG
long<-double NG
long<-float NG
long<-double NG
long<-boolean NG
float<-byte OK
float<-short OK
float<-int OK
float<-long OK
float<-double NG
flaot<-boolean NG
double<-byte OK
double<-short OK
double<-int OK
double<-long OK
double<-float OK
double<-boolean NG
boolean<-byte NG
boolean<-short NG
boolean<-int NG
boolean<-long NG
boolean<-float NG
boolean<-double NG

NGのところでは
この型は = には不適合です。* から # への変換には明示的なキャストが必要です。
というエラーメッセージが表示されます。
(*:代入する値の型;#:代入する変数の型)
ただ、boolean型を代入しようとすると、
この型は = には不適合です。boolean から # への変換はできません。
と表示されます。
逆の場合も、
この型は = には不適合です。* から boolean への変換はできません。
と表示されます。
結論として、
byte⊂short⊂int⊂long⊂float⊂double
booleanは特殊のようです。


練習2-5
n桁目の2進数を変換する場合、最初のプログラムと改良後のプログラムでは、掛け算が何回行われるか?

解答例(佐々木俊也さん)
改良前:
baseiの計算には掛け算がi+1回、
demicialiの計算には掛け算が1回ずつ、
(i=0,1,2,…,n-1)
合計(1/2)*n*(n+3)回
改良後:
baseiの計算にはi>1の時、掛け算が1回、
i=0の時、掛け算は0回、
demicialiの計算には掛け算が1回ずつ、
(i=0,1,2,…,n-1)
合計2n-1回
改良により、(n*n-n+2)/2回分掛け算が減ったことになる。


練習2-6
10進数の値をn桁の2進数に変換する方法を考え、プログラムを作れ。
ただし、もとの数はint deciminalNumber= 123 ; //10進数の値
のようにして与えられるものとする。

解答例(佐々木俊也さん)
練習2-6
class DecimalToBits {
  public static void main(String[] args){
    //10進数から2進数に
    byte decimalNumber=123; //与えられた10進数の値
    /* この処理方法では127までしか扱えないのでbyte型で宣言しています。 */
    int bit0=decimalNumber % 2; //0桁目(最後の桁)を求める
    /*元の数を2で割った余りが最後の桁*/
   int rest0=(decimalNumber-bit0)/2; //商を求める
    int bit1=rest0 % 2; //1桁目を求める
    int rest1=(rest0-bit1)/2;
    int bit2=rest1 % 2; //2桁目を求める
    int rest2=(rest1-bit2)/2;
    int bit3=rest2 % 2; //3桁目を求める
    int rest3=(rest2-bit3)/2;
    int bit4=rest3 % 2; //4桁目を求める
    int rest4=(rest3-bit4)/2;
    int bit5=rest4 % 2; //5桁目を求める
    int rest5=(rest4-bit5)/2;
    int bit6=rest5 % 2; //6桁目(先頭桁)を求める

    //表示
    System.out.println("10進数"+decimalNumber+"を2進数で表すと"+
                       bit6+bit5+bit4+bit3+bit2+bit1+bit0+"です。");
  }
}
実行結果
10進数123を2進数で表すと1111011です。

コメント
10進数を2進数にするときに筆算でやるやり方を元にしています。
この方法の欠点は、
127までしか適用できない
ということです。
計算回数を増やせば対応はできますが、
与えられる10進数の値が分からないときはこの方法では不可能です。
別の方法を考えなければいけません。
また、与えられる値が分かっていても、
例えばint decimalNumber=2000000000;
などだったりすると、
30回も繰り返さなければならないので大変めんどうです。

また、余りを与える演算子%の答えはint型のようです。