入門じゃないJava(3)

こんばんは。

ちょっとこの記事を書くのには時間が遅いので、今日中に書ききれるか不安ですが、今回も楽しくJavaを見ていきましょう。

 

ちなみに、前回は浮動小数点数などを見ていきましたね。

creators.hateblo.jp

 

今回は整数型、浮動小数点型を見てきたので、キャスト演算子などを通して型変換を見ていきましょう。

 

キャスト演算子

キャスト演算子のフォーマットは次の通りです。

(  型  )  式

そのため、たとえばint型のintValueをdouble型に変換しdouble型のdblValueに代入するときは、

dblValue = (double) intValue;

となります。

お分かりかとは思いますが、ここで使われる( )は区切り子ではなく、キャスト演算子です。なお、このような型変換はキャストと呼ばれます。

このキャスト演算子は変数だけでなく、数値リテラルを指定することもできます。

dblValue = (double) 12;

とすれば結果は12.0になります。

また、

dblValue = (double) (a + b);

で、aを7、bを8とし、得られた結果が15の時、このキャスト式を評価すると15.0になります。

基本型の縮小変換

 縮小変換は原則としてキャストが必須。

変換に伴い、数値の大きさ(指数部)、数値の精度(仮数部)の情報が欠損する場合があります。

キャストを伴わない縮小変換

基本型の縮小変換では原則的にキャストが必須ですが、一部例外があります。

byte a = 2;

a = 12;

short b = 53;

 

以前学習した整数接尾語L(または"l"小文字のエル)のつかない整数リテラルはint型です。

したがって、byte型やshort型に対して、int型である2,12,53の値を入れる際にはキャストが必要なはずです。が、キャストをしなくてもエラーにならないのは以下のような規則があるからです。

 

代入の右辺の式や書式指定子がbyte、short、char、int型の定数式で、代入先あるいは初期化先の変数の型がbyte、short、charであって、定数式の値が変数の型で表現できる場合は、基本型の縮小変換が自動的に行われる。

 キャストせずに入れることができるのは、定数式と定数式の値が変数の型で表現できる場合に限られます。

short a = 12;      //Pass

byte  b = a;        //Error

byte  c = 128;    //Error

 

なお、浮動小数点型にはこのような規則はありません。したがって、float型の変数に対して、キャストすることなく、double型の定数値を入れることはできません。

float a = 3.14;            //Error

float b = (float)3.14;  //Pass

float c = 3.14f;          //Pass

 

基本型の拡大変換

前項の「基本型の縮小変換」の逆がこれ、「基本型の拡大変換」です。

例は柴田 望洋 (2016) .『新・明解Java入門』p166でご確認ください。

この変換は代入あるいは初期化の際に自動的に行われます。例を以下に示します。

int a     = '5'

long b  = a;

double = 3.14f;

 基本型の拡大変換では、数値の大きさに関する情報は原則として失われないことになっています。ただし、以下に示す例については精度を失うことがあります。

int あるいは long 型の値からの floatへの変換

long の値からdoubleへの変換。

 この場合、浮動小数点の変換結果は最も近い値に丸められた整数値になります。

以下の拡大変換の例では精度を失います。

class IntegralToFloat {
    public static void main(String[] args) {
        int  a = 123456789;
        long b = 1234567890123456789L;

        System.out.println("         a = " +         a);
        System.out.println(" (float) a = " +  (float)a);

        System.out.println("         b = " +         b);
        System.out.println("(double) b = " + (double)b);
    }
}

 

実行結果

             a = 123456789
   (float) a = 1.23456792E8
             b = 1234567890123456789
(double) b = 1.23456789012345677E18
C:\Java\03>_

 intからfloatに変換する過程と、longからdoubleに変換する過程で精度に関する情報が欠損したことがわかります。

 

今日はここまで!

 

参考文献

柴田 望洋 (2016) .『新・明解Java入門』162-166