class DoubleLoop{ public static void main(String[] args){ double r; for(r=0.0;r<1.0;r+=0.1){ System.out.println("r="+r); } } }誤差なく計算できれば,ループ内を10回実行すると rは1.0になるので, そこでfor文を抜けるはずだが,実行させてみると,
r=0.0 r=0.1 r=0.2 r=0.30000000000000004 r=0.4 r=0.5 r=0.6 r=0.7 r=0.7999999999999999 r=0.8999999999999999 r=0.9999999999999999となってしまう.誤差によって,0に0.1を10回足しても1にならない.これは, 10進法で小数点10桁以下を捨てた場合に
(1.0/3) * 3 = 0.3333333333 * 3 = 0.999999999 != 1.0となるのと同じ原因による.2進法では1/10は切りのいい数字にはならない.
class RoundTest{ public static void main(String[] args){ int i,ir; double r= -2.0; for(i=0;i<=40;i++){ ir=(int)r; System.out.println(r+"->"+ir); r+=0.1; } } }を実行すると
-2.0->-2 -1.9->-1 -1.7999999999999998->-1 -1.6999999999999997->-1 -1.5999999999999996->-1 -1.4999999999999996->-1 -1.3999999999999995->-1 -1.2999999999999994->-1 -1.1999999999999993->-1 -1.0999999999999992->-1 -0.9999999999999992->0 -0.8999999999999992->0 -0.7999999999999993->0 -0.6999999999999993->0 -0.5999999999999993->0 -0.49999999999999933->0 -0.39999999999999936->0 -0.2999999999999994->0 -0.19999999999999937->0 -0.09999999999999937->0 6.38378239159465E-16->0 0.10000000000000064->0 0.20000000000000065->0 0.30000000000000066->0 0.4000000000000007->0 0.5000000000000007->0 0.6000000000000006->0 0.7000000000000006->0 0.8000000000000006->0 0.9000000000000006->0 1.0000000000000007->1 1.1000000000000008->1 1.2000000000000008->1 1.300000000000001->1 1.400000000000001->1 1.500000000000001->1 1.6000000000000012->1 1.7000000000000013->1 1.8000000000000014->1 1.9000000000000015->1 2.0000000000000013->2のようになる.四捨五入するには,0.5を足し, Math.floor()を 呼び出してからint型に変換すると良い.さきほどのプログラムを変更してみる.
class RoundTest{ public static void main(String[] args){ int i,ir; double r= -2.0; for(i=0;i<=40;i++){ ir=(int)Math.floor(r+0.5); System.out.println(r+"->"+ir); r+=0.1; } } }実行結果は以下のようになる.
-2.0->-2 -1.9->-2 -1.7999999999999998->-2 -1.6999999999999997->-2 -1.5999999999999996->-2 -1.4999999999999996->-1 -1.3999999999999995->-1 -1.2999999999999994->-1 -1.1999999999999993->-1 -1.0999999999999992->-1 -0.9999999999999992->-1 -0.8999999999999992->-1 -0.7999999999999993->-1 -0.6999999999999993->-1 -0.5999999999999993->-1 -0.49999999999999933->0 -0.39999999999999936->0 -0.2999999999999994->0 -0.19999999999999937->0 -0.09999999999999937->0 6.38378239159465E-16->0 0.10000000000000064->0 0.20000000000000065->0 0.30000000000000066->0 0.4000000000000007->0 0.5000000000000007->1 0.6000000000000006->1 0.7000000000000006->1 0.8000000000000006->1 0.9000000000000006->1 1.0000000000000007->1 1.1000000000000008->1 1.2000000000000008->1 1.300000000000001->1 1.400000000000001->1 1.500000000000001->2 1.6000000000000012->2 1.7000000000000013->2 1.8000000000000014->2 1.9000000000000015->2 2.0000000000000013->2
class Test{ public static void main(String[] argv){ int n; double rate=1.01; /* 利率 */ double a=10000.0; /* 借金の額 */ double y=200.0; /* 1年の返済額 */ n=0; while (a>0.0) { a = a*rate- y; n = n+1; System.out.println(n+"年後の借金の残りは"+a+"です"); } System.out.println(n+"年で返済できます"); } }
利率 1% 借金 10000 返済 200 | |
利率 5% 借金 10000 返済 800 | |
利率 10% 借金 10000 返済 1100 | |
利率 20% 借金 10000 返済 2100 |
解答例
import java.io.*; public class Test{ public static void main(String[] argv) throws IOException{ int n; double rate; /* 利率 */ double a; /* 借金の額 */ double y; /* 1年の返済額 */ BufferedReader d=new BufferedReader(new InputStreamReader(System.in)); System.out.println("利率(%)を入力してください."); rate=1.0+(new Double(d.readLine()).doubleValue())*0.01; System.out.println("借金の額を入力してください."); a=new Double(d.readLine()).doubleValue(); System.out.println("1年の返済額を入力してください."); y=new Double(d.readLine()).doubleValue(); n=0; while (a>0.0) { a = a*rate- y; n = n+1; System.out.println(n+"年後の借金の残りは"+a+"です"); } System.out.println(n+"年で返済できます"); } } 利率 1% 借金 10000 返済 200 は 69年後の借金の残りは131.0557584615495です 70年後の借金の残りは-67.633683953835です 70年で返済できます 利率 5% 借金 10000 返済 800 は 20年後の借金の残りは80.21376913348399です 21年後の借金の残りは-715.7755424098418です 21年で返済できます 利率 10% 借金 10000 返済 1100 は 25年後の借金の残りは165.29405661167948です 26年後の借金の残りは-918.1765377271525です 26年で返済できます 利率 20% 借金 10000 返済 2100 は 16年後の借金の残りは1255.7870552481604です 17年後の借金の残りは-593.0555337022076です 17年で返済できます 返済に一番時間がかかるのは,「利率 1% 借金 10000 返済 200」の組み合わせ.
String aString=d.readLine(); a=new Double(aString).doubleValue();のように一度 String 型の変数に取ってから,doubleに変換していいが,一カ 所でしか参照されない変数は
a=new Double(d.readLine()).doubleValue();のように除去することができる.
利率の入力の際,
System.out.println("利率(%)を入力してください."); rate=1.0+(new Double(d.readLine()).doubleValue())*0.01;と,%で入力を求めましたが,
System.out.println("利率(0%の場合は1.00)を入力してください."); rate=new Double(d.readLine()).doubleValue();と,比率を入力するようにしても構わない.