変数の扱える最大値の周辺

扱える限界になるとどうなるのか

補充問題1

次の文はエラーになるか。型の問題とそれぞれの型が扱える最大値も含めて考える必要がある。2147483647 は int の最大値、9223372036854775807 は long の最大値である。

(1)  int    p =  2147483647;
(2)  int    q =  2147483648;
(3)  long   r =  2147483648;
(4)  float  s =  9223372036854775807f;

補充問題2

問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 );
         }
    }

補充問題2 の解答

問1

問1(1)

System.out.println ( 3.40282347e38 * 10 );
3.40282347E39

デフォルトでdoubleとして扱われるので10倍しても問題ない

問1(2)

float t = 3.40282347e38;
System.out.println ( t * 10 );
Test2.java:3: 精度が落ちている可能性
検出値  : double
期待値  : float
        float t = 3.40282347e38;
                  ^
エラー 1 個

このリテラルはdoubleと判断されるので、floatにそのまま代入しようとするとエラーになる。

問1(3)

float u = 3.40282347e38f;
System.out.println ( u * 10 );
Infinity

fをつけると、floatとして扱われる。これをfloatの変数に代入するのは問題なくできる。しかし、これを10倍するとfloatの範囲を超えるので Infinity (無限大)になってしまう。

問1(4)

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 (無限大)にならない。

問2

問2(1)

System.out.println ( 1.40239846e-45 / 10 );
1.4023984600000001E-46

デフォルトでdoubleとして扱われるので10でわっても問題ない

問2(2)

float w = 1.40239846e-45;
System.out.println ( w / 10 );
Test6.java:3: 精度が落ちている可能性
検出値  : double
期待値  : float
      float w = 1.40239846e-45;
                ^
エラー 1 個

このリテラルはdoubleと判断されるので、floatにそのまま代入しようとするとエラーになる。

問2(3)

float u = 3.40282347e38f;
System.out.println ( u * 10 );
0.0

fをつけると、floatとして扱われる。これをfloatの変数に代入するのは問題なくできる。しかし、これを10で割るとfloatの範囲を超えるので 0(扱える0に最も近い数値が1.40239846e-45 なのでこれ以下は0としたということ)になってしまう。

問2(4)

double y = 1.40239846e-45;
System.out.println ( y / 10 );
1.4023984600000001E-46

doubleの変数を使うとdoubleで計算するので同じく10で割っても正しい答えになる。

問2(5)

float z = 1.40239846e-45f;
System.out.println ( z - 2 );
-2.0

z が float で、 2 は int なので、float にあわせて計算しようとしている。計算結果は -2 よりすこし大きいが、float の範囲に丸めると -2 になってしまう。

もくじ

聖愛高等学校
http://www.seiai.ed.jp/
Last Modified