入門じゃない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

 

 

 

 

 

前をむいて

こんばんは。

失意のかぼすです。

 

今は(いくらスマホがHard brickしようが)前を向いて進むしかない時で、立ち止まってはいけないのです。

というわけで、自分の目に入らないところに該当のスマホを隠して、今正気を保っています。

 

明日も忙しいので、今日はここらでお暇します。

では!

今日のこと

こんばんは。

もやもやのかぼすです。

 

久しぶりに「今日のこと」というエントリーですが、激動の一日でした(?)

朝はバイナリとの格闘、昼はAntirollback versionとの格闘、そして、現在hard brickに至る。

と、一喜一憂していました。

おそらく、大半の方は「何のこっちゃ」という感じだと思います。

僕も今そんな感じです。

朝から、ファクトリーイメージを書き換えて、昼は、焼いたファームウェアがそれ以外に書き換わらなくなって、夜(現在)、ダメもとで焼いたらhard brickしてしまった。

という具合です。

 

実におまぬけな一日です。

今日は気持ちよく寝れるはずだったのですが。。。

 

では!

ROM焼きというかDD

こんばんは。

いつもながらのかぼすです。

 

今日はJavaではなくほとんどROM焼きをしていました。

ロム焼きというか結局ddコマンドとpull、fastbootにしたり、bootloopに陥ったのでROMを書き戻したり、を繰り返していました。

 

いつかそんな話もしたいんですけどね。。。

 

では!

入門じゃないJava(2)

こんにちは。

今日も楽しくJavaを見ていきましょう。

前回は整数など(10進数、8進数、16進数とint型、long型)を見ていきました。

creators.hateblo.jp

 

ということは、今日は「浮動小数点数?!」とピンときた方、鋭いですね。

浮動小数点数をちょこっとやった後、もう少し進んでみたいと思います。

でもまずは2の補数表現から見ていきましょう。

 

整数の内部と2の補数表現

前回のどのリテラルも値はビットの並びとして表現されます。

かと言って、それらは好き勝手に並んでいるわけでなく、すべてきちんと規則があります。

整数リテラルはint型long型ですが、それぞれ、表現できる最大と最小があります。

その為、表現できる数は有限という訳です。

int型よりもlong型の方が表せる数の幅は広くなっています。

なぜ、int型とlong型にはそのような差があるかというと、構成ビットが違うからです。

具体的には、int型が32ビットに対して、long型は64ビットです。

ということは、int型のオブジェクトを一つ表す為には0と1が32個用意されていることになります。

そのうち先頭のビットは「符号ビット」として使われます。

もしも先頭のビットが0であれば、その値は0か正の数になるはずで、1であれば負の数になります。

具体的に見てみると、

int型の12という数は、 00000000000000000000000000001100と表現されます。

int型の-12という数は、11111111111111111111111111110010と表現される訳です。

ちなみに、先頭の0が太文字になっていると思いますが、これが符号ビットです。

ここで、↑の12と-12を表しているビットに注目していただきたいのですが、まずは12の方は、10進数の12は2進数では1100になりますので、先頭から1100までの上位ビットは0で埋めたものになります。対して、-12は12の補数(ビットの反転)になっている・・・と言いたいところですが、末尾がおかしいですね。

2の補数表現

負の数は正の数の全ビットを反転させたものに1を加えたビット構成になります。

この作業の名前が「2の補数表現」になります。なお、正の数の全ビットを反転させた(もの)のことを「1の補数」と言います。

浮動小数点数

小数点以下の部分を持つ実数を表すのが浮動小数点型です。

これには、floatとdoubleの2種類があります。

ただし、浮動小数点数の場合、整数型よりも厄介な問題があります。

class DispFloatingLiterals {
    public static void main(String[] args) {
        float  a = 123456789;
        double b = 1234567890123456789L;
        System.out.println("a = " + a);
        System.out.println("b = " + b);
    }
}

実行結果

 a = 1.23456782E8
 b = 1.23456789012345677E18

C:\Users\Onwer\Documents>_

 のようになると思います。

※表示されているEは10のべき乗を表す数学的表記。aの1.23456782E8は1.23456782 * 10^8であることを示しています。

なお、1.23456782 * 10^8の1.23456782は仮数、10^8の8を指数と呼び、仮数の桁数が精度を、指数の値が大きさに相当します。

 

見ての通り、変数に入れた値は正確には表現させれていないことがわかります。

これは、浮動小数点型の表現範囲が大きさと精度の両面から制約を受けているためです。

 

浮動小数点接尾語

整数リテラルにはfloat型とdouble型があると書きましたが、基本的にdouble型になります。

しかし、浮動小数点接尾語であるFまたはf(小文字のエフ)をつけるとその浮動小数リテラルはfloat型になります。

double型と明示したいときなどにはDまたはdを指定します。

たとえば、12.0、12.0Dはdouble型ですが、12.0Fはfloat型と解釈されます。

 

数学的表記と省略

 実は指数を付けた数学的表記や整数部、小数部の省略が可能です。

ただし、いくつかの規則等もありますので、確認しながら見ていきましょう。

class DispSomeFloating {
    public static void main(String[] args) {
        
        System.out.println("1.23E4   =   " + 1.23E4); //1.23 * 10^4
        System.out.println("80.0E-5  =   " + 80.0E-5);//80.0 * 10^-5

        System.out.println(".5       =   " + .5);     //0.5
        System.out.println("5.       =   " + 5.);     //10.0
        System.out.println(".5f      =   " + .5f);    //floatの0.5
        System.out.println("5D       =   " + 5D);     //5.0
    }
}

実行結果

1.23E4   = 12300.0
1.23E4 = 12300.0
80.0E-5 = 8.0E-4
.5 = 0.5
5. = 5.0
.5f = 0.5
5D = 5.0
C:\Users\Onwer\Documents>_

 今日はここまでにしましょう。

次回はもう少し踏み込んだ内容にしていきたいと思います。

では次回もお楽しみに!

参考文献

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