解答例(河野佐代子さん) |
class Shinhou6 { // 2進数と10進数
public static void main(String[] args) {
String binaryNumber = "1101"; // 文字列で表した2進法
int numberOfDigits = binaryNumber.length(); //ビット数
int index; //現在注目している桁数をしまう変数
int decimalNumber = 0;//10進数の値
int base = 8; //基数
for (index = 3; -1 < index ; index = index - 1) {
int bit =binaryNumber.charAt(3-index) - '0';//index桁目のビット
System.out.println("第"+index+"桁目は"+bit+"です");
decimalNumber = decimalNumber + base*bit; //10進数に変換する。
base = base/2 ;
}
System.out.println("10進数では"+decimalNumber+"です");
}
}
上位の桁から表示されるのは、なんとなく気持が悪いので、
先生からのアドバイスも借りつつ、上のようなプログラムをつくりました。
実行結果は
第3桁目は1です
第2桁目は1です
第1桁目は0です
第0桁目は1です
10進数では13です
となりました。
|
練習3-2
for文を使って一定回数の繰り返しを行う場合、
条件を大小関係で書くのが普通である。これを例えば
下のように、「等しくない」ことを条件にして実行するとどうなるか?
またその理由は?
double year; // 現在の年数
for (year = 1; year != 10; year = year + 0.1) // 10分の1年刻みごとの繰返し
System.out.println("現在の年数は"+year+"です。");
解答例(佐々木俊也さん) |
class year { //数値誤差
public static void main(String[] args){
double year; //現在の年数
for (year=1; year!=10; year=year+0.1) //10分の1年ごとの繰り返し
System.out.println("現在の年数は"+year+"です。");
}
}
コメント
この場合、yearが10になった時点でfor文から抜けると思われるが、
実際には永遠に繰り返す。
(止めるときはControlキーとCを押す)
これは、表示結果を見れば分かるが、
わずかな誤差のためにyearが10になることはない。
10の前後では、現在の年数は9.999999999999982です。
現在の年数は10.099999999999982です。
と表示される。
|
練習3-3
金利が 0.1%, 0.2%, ..., 1.0% の場合について、
それぞれ10万円を10年間預けたときの残高を計算して表示させよ。
(ヒント: for文の中にfor文を書く。)
解答例(蒋 弥能(ショウ ミノウ)さん) |
class interest //10年後の残高を計算する
{
public static void main(String[] args){
double interest; //利率
int currentyear; //何年後かを数える変数
double base=100000; // currentyear年目の残高
for(interest=0.001;interest<=0.01;interest=interest+0.001){
//利率1.001から1.01までを順に実行
double balance=base;
for(currentyear=1;currentyear<=10;currentyear=currentyear+1){
//1年後から10年後までを順に実行
balance=balance*(1+interest); //残高を増やす
}
System.out.println("金利は"+interest+"のとき十年後残高は"+balance+"です");
//10年後の残高
}
}
}
実行結果は
金利は0.0010のとき十年後残高は101004.51202102509です
金利は0.0020のとき十年後残高は102018.09633680772です
金利は0.0030のとき十年後残高は103040.82570713882です
金利は0.0040のとき十年後残高は104072.773401891です
金利は0.0050のとき十年後残高は105114.01320407893です
金利は0.0060のとき十年後残高は106164.61941293835です
金利は0.0070のとき十年後残高は107224.66684701681です
金利は0.0080のとき十年後残高は108294.23084728388です
金利は0.009000000000000001のとき十年後残高は109373.38728025254です
|
練習3-4
for文は、while文に「繰り返しの最初に行う計算」と
「繰り返しを続ける際に行う計算」が書けるようにしたものと見なせる。
いま、
for (A; B; C) { D; E; ... Z; }
というfor文があったとき、
これと同じ計算をするwhile文はどうなるかを示せ。
また、図1をwhile文を使って書き直せ。
解答例(佐々木俊也さん) |
for(A;B;C){D;E:…Z;}
は、以下のように書き直せる。
A;
while(B){
D;
E;
:
Z;
C;
}
したがって、図1は以下のように書き直せる。
class Saving_while{
public static void main(String[] arg){
double interest = 1.0045; //利率
int years =10; //計算する期間
int currentYear; //何年後かを数える変数
double balance =100000; //currentYear年目の残高
currentYear=1;
while(currentYear<=years){
balance=balance*interest;
currentYear=currentYear+1;
}
System.out.println(balance); //years年後の残高
}
}
for文を使った方がすっきりと書ける。
|
練習3-5
テキストのdo-while文の説明を読み、
上の練習にならってwhile文への書き換えを考えよ。
TAによる解答例 |
A;
while(B){
は、基本的には以下のように書き直せる。
A;
do {
D;E;...;Z;
C;
} while(B);
ただし、while文と異なり、
do文では{}の中(D;E;...;Z;)が無条件に一度実行される
ので注意が必要。
|
練習3-6
10年後に元金が2倍になる最低の金利を求めたい。
金利を 0.1%, 0.2%, ... と 0.1% 刻みで変化させ、
10年後の残高が 2 倍未満の間繰り返すことで求めよ。
(ヒント: do〜while 文を使った方がすっきりと書ける
かも知れない。)
解答例(佐々木俊也さん) |
class nest2{ //二重の繰り返し(2)
public static void main(String[] arg){
double interest; //金利
double principal = 100000; //元金
double balance=principal; //残高
double targetrate=2; //目標とする倍率
double targetbalance=principal*targetrate; //目標とする金額
int term=10; //預ける期間
int year; //現在の年数
interest=0; //金利の初期設定
while(balance<targetbalance){
// 残高が目標金額を下回っている間以下を繰り返す
interest=interest+0.1;
balance=principal;
for(year=1;year<=term;year=year+1){
balance=balance+balance*(interest/100); //year年後の残高の計算
}
System.out.println("元金"+principal+"円で金利"+interest+"%の時の"+
term+"年後の残高は");
System.out.println(balance+"円です。");
//長くなったので2行に表示を分けました。
}
System.out.println("よって、"+term+"年後の残高が"+targetrate+
"倍になる最低の金利は"+interest+"%です。");
}
}
実行結果
(略)
元金100000.0円で金利7.099999999999991%の時の10年後の残高は
198561.3460801142円です。
元金100000.0円で金利7.19999999999999%の時の10年後の残高は
200423.1361654335円です。
よって、10年後の残高が2.0倍になる最低の金利は7.19999999999999%です。
コメント
while文にはいる前にinterestを0.1にする方法もあります。
その場合、
interest=interest+0.1;
を、while文で繰り返すブロックの最後に置くことになりますが、
そうすると、最後の表示で金利が0.1ずれます。
|
練習3-7
練習3-1で作ったプログラム中の繰り返しの不変量は何かを考え、
正しいことを確認せよ。
練習3-8
上のプログラムを拡張して、
金利が、10年以上のとき 0.45%, 7年以上のとき 0.4%, 5年以上のとき
0.3%, 4年以上のとき 0.25%, 3年以上のとき 0.23%, それ未満のとき 0.2%
で計算するようにプログラムを直し、1年間〜10年間預けた後の残高を
計算してみよ。
解答例(佐々木俊也さん) |
class multiInterest { //複雑な条件
public static void main(String[] arg){
double interest1=1.002; //3年未満の金利
double interest2=1.0023; //3年以上4年未満の金利
double interest3=1.0025; //4年以上5年未満の金利
double interest4=1.003; //5年以上7年未満の金利
double interest5=1.004; //7年以上10年未満の金利
double interest6=1.0045; //10年以上の金利
int years=10; //預ける期間の最大値
int year; //預ける期間
double interest; //預ける期間に対応した金利
int currentyear; //何年目かを数える変数
double principal=100000; //元金
double balance; //残高
for(year=1;year<=years;year=year+1){
if (year >=10){
interest=interest6;
}
else if(year>=7){
interest=interest5;
}
else if(year>=5){
interest=interest4;
}
else if(year>=4){
interest=interest3;
}
else if(year>=3){
interest=interest2;
}
else{
interest=interest1;
}
balance=principal;
// ここまでがそれぞれのyearにおける初期化処理
for(currentyear=1;currentyear<=year; currentyear=currentyear+1){
balance=balance*interest;
}
System.out.println(year+"年後の残高は"+balance+"円です。");
}
}
}
実行結果
1年後の残高は100200.0円です。
2年後の残高は100400.4円です。
3年後の残高は100691.5882167円です。
4年後の残高は101003.75625390623円です。
5年後の残高は101509.02704052425円です。
6年後の残高は101813.55412164581円です。
7年後の残高は102833.82489815327円です。
8年後の残高は103245.16019774588円です。
9年後の残高は103658.14083853686円です。
10年後の残高は104592.22715798837円です。
コメント
これは、預ける期間があらかじめ分かっている場合です。
これとは逆に、3年未満の時はその後10年預けても、
そのときの利子を0.2%で計算する場合は以下のようになります。
class multiInterest2 { //複雑な条件
public static void main(String[] arg){
double interest1=1.002; //3年未満の金利
double interest2=1.0023; //3年以上4年未満の金利
double interest3=1.0025; //4年以上5年未満の金利
double interest4=1.003; //5年以上7年未満の金利
double interest5=1.004; //7年以上10年未満の金利
double interest6=1.0045; //10年以上の金利
int years=10; //預ける期間の最大値
int year; //預ける期間
double interest; //預ける期間に対応した金利
int currentyear; //何年目かを数える変数
double principal=100000; //元金
double balance; //残高
for(year=1;year<=years;year=year+1){
balance=principal;
// ここまでがそれぞれのyearにおける初期化処理
for(currentyear=1;currentyear<=year; currentyear=currentyear+1){
if (currentyear >=10){
interest=interest6;
}
else if(currentyear>=7){
interest=interest5;
}
else if(currentyear>=5){
interest=interest4;
}
else if(currentyear>=4){
interest=interest3;
}
else if(currentyear>=3){
interest=interest2;
}
else{
interest=interest1;
}
balance=balance*interest;
}
System.out.println(year+"年後の残高は"+balance+"円です。");
}
}
}
実行結果
1年後の残高は100200.0円です。
2年後の残高は100400.4円です。
3年後の残高は100631.32092円です。
4年後の残高は100882.8992223円です。
5年後の残高は101185.54791996688円です。
6年後の残高は101489.10456372677円です。
7年後の残高は101895.06098198167円です。
8年後の残高は102302.6412259096円です。
9年後の残高は102711.85179081323円です。
10年後の残高は103174.05512387189円です。
|
練習3-9
ある年yearが閏年かどうかのメッセージを表示するプログラムを
(1)1つのif文の条件式を
&& (かつ) / || または / ! (否定)の
組み合わせによって、(2)値の比較だけをする条件式を持つif文の
組み合わせでそれぞれ作れ。
ただし、西暦年が4の倍数でない年、または
西暦年が100の倍数かつ400の倍数でない年は
平年であり、それ以外の年は閏年である。
解答例(佐々木俊也さん) |
class leapyear{ //条件の組み合わせ(1)
public static void main(String[] args){
int year=2000; //閏年かどうか判定すべき年
if(year%4!=0||year%100==0&&year%400!=0){
System.out.println(year+"年は閏年ではありません。");
}
else{
System.out.println(year+"年は閏年です。");
}
}
}
class leapyear2{ //条件の組み合わせ(2)
public static void main(String[] args){
int year=2000; //閏年かどうか判定すべき年
boolean leap; //閏年であればtrue そうでなければfalse
if(year%4==0){
if(year%100==0){
if(year%400==0){
leap=true; //400の倍数なら閏年
}
else {
leap=false; //100の倍数だが400の倍数でなければ閏年でない
}
}
else{
leap=true; //4の倍数だが100の倍数でなければ閏年
}
}
else{
leap=false; //4の倍数でなければ閏年
}
if(leap==true){
System.out.println(year+"年は閏年です。");
}
else{
System.out.println(year+"年は閏年ではありません。");
}
}
}
実行結果(両方とも)
2000年は閏年です。
コメント
if文での条件判断は、「等しい」の場合==を使わないと、
正確に実行されません。
もし=を使った場合、代入とみなされ、
条件は常に成立ということになってしまいます。
また、両者を比較すると短いのは前者ですが、
条件が分かりやすいのは後者だと思います。
|
|