次の文はエラーになるか。型の問題とそれぞれの型が扱える最大値も含めて考える必要がある。2147483647 は int の最大値、9223372036854775807 は long の最大値である。
(1) int p = 2147483647; (2) int q = 2147483648; (3) long r = 2147483648; (4) float s = 9223372036854775807f;
問1 3.40282347×1038=3.40282347e38 が float の最大値である。次の答えはいくらになるか。
(1) public class Test1 { public static void main( String[] args ) { System.out.println ( 3.40282347e38 * 10 ); } } (2) public class Test2 { public static void main( String[] args ) { float t = 3.40282347e38; System.out.println ( t * 10 ); } } (3) public class Test3 { public static void main( String[] args ) { float u = 3.40282347e38f; System.out.println ( u * 10 ); } } (4)double は float より大きな数を扱うことができる。 public class Test4 { public static void main( String[] args ) { double v = 3.40282347e38; System.out.println ( v * 10 ); } }
問2 1.40239846×10-45=1.40239846e-45 が float の最小値である。次の答えはいくらになるか。
(1) public class Test5 { public static void main( String[] args ) { System.out.println ( 1.40239846e-45 / 10 ); } } (2) public class Test6 { public static void main( String[] args ) { float w = 1.40239846e-45; System.out.println ( w / 10 ); } } (3) public class Test7 { public static void main( String[] args ) { float x = 1.40239846e-45f; System.out.println ( x / 10 ); } } (4)double は float より0に近い数を扱うことができる。 public class Test8 { public static void main( String[] args ) { double y = 1.40239846e-45; System.out.println ( y / 10 ); } } (5) (3)と比較します。 public class Test9 { public static void main( String[] args ) { float z = 1.40239846e-45f; System.out.println ( z - 2 ); } }
System.out.println ( 3.40282347e38 * 10 );
3.40282347E39
デフォルトでdoubleとして扱われるので10倍しても問題ない
float t = 3.40282347e38; System.out.println ( t * 10 );
Test2.java:3: 精度が落ちている可能性 検出値 : double 期待値 : float float t = 3.40282347e38; ^ エラー 1 個
このリテラルはdoubleと判断されるので、floatにそのまま代入しようとするとエラーになる。
float u = 3.40282347e38f; System.out.println ( u * 10 );
Infinity
fをつけると、floatとして扱われる。これをfloatの変数に代入するのは問題なくできる。しかし、これを10倍するとfloatの範囲を超えるので Infinity (無限大)になってしまう。
double v = 3.40282347e38; System.out.println ( v * 10 );
3.40282347E39
doubleの変数を使うとdoubleで計算するので同じく10倍するのであっても正しい答えになる。
float u = 3.40282347e38f; System.out.println ( u * 10.0 ); }
3.4028234663852886E39
u が float なのだが、10.0 は double となる。double にあわせて計算するので Infinity (無限大)にならない。
System.out.println ( 1.40239846e-45 / 10 );
1.4023984600000001E-46
デフォルトでdoubleとして扱われるので10でわっても問題ない
float w = 1.40239846e-45; System.out.println ( w / 10 );
Test6.java:3: 精度が落ちている可能性 検出値 : double 期待値 : float float w = 1.40239846e-45; ^ エラー 1 個
このリテラルはdoubleと判断されるので、floatにそのまま代入しようとするとエラーになる。
float u = 3.40282347e38f; System.out.println ( u * 10 );
0.0
fをつけると、floatとして扱われる。これをfloatの変数に代入するのは問題なくできる。しかし、これを10で割るとfloatの範囲を超えるので 0(扱える0に最も近い数値が1.40239846e-45 なのでこれ以下は0としたということ)になってしまう。
double y = 1.40239846e-45; System.out.println ( y / 10 );
1.4023984600000001E-46
doubleの変数を使うとdoubleで計算するので同じく10で割っても正しい答えになる。
float z = 1.40239846e-45f; System.out.println ( z - 2 );
-2.0
z が float で、 2 は int なので、float にあわせて計算しようとしている。計算結果は -2 よりすこし大きいが、float の範囲に丸めると -2 になってしまう。