sixty-life

還暦を迎えた今、独学でプログラミング学習をする日々の記録

いろいろなデータ型⑤誤差・異なるデータ型の数値演算

基礎からのJava 改訂版

Part 02 Chapter 06(P.91)

誤差

型変換や算術演算によりデータの一部分が失われる場合があります。

public class Renshu_ori_4 {
public static void main(String args) {
int num = 3/2;
System.out.println(num);
}
}

  datatype java Renshu_ori_4      

1

桁落ち

この結果は1.5だが、int=整数なので切り捨てられて”1”となった。

 

public class Renshu_ori_4 {
public static void main(String args) {
//int num = 3/2;
int num = (int)1.5;
System.out.println(num);
}
}

  datatype java Renshu_ori_4      

1

少数から整数へのキャストも同様。

 

public class Renshu_ori_4 {
public static void main(String args) {
//int num = 3/2;
//int num = (int)1.5;
int num = 10000 * 10000 * 10000;
System.out.println(num);
}
}

  datatype java Renshu_ori_4

-727379968

桁あふれ

intの最大値(-231 〜231-1)を超える。

 

浮動小数は10進数ではなく2進数の計算のため、10進数ではっきり書ける数も内部的には微妙な誤差が出る。

public class Renshu_ori_5 {
public static void main(String args) {

double d = 1 - 2 * 0.4;
System.out.println(d);
}
}

  datatype java Renshu_ori_5

0.19999999999999996

丸め誤差

結果はきっちり0.2にはならない。

意図して切り捨てている場合は問題ないが、意図しないところで精度が落ちたり、値の一部が切り捨てられていると目的の結果が得られなかったり、バグの原因になる。

なお、丸め誤差について、金額計算などで1円の誤差も許されないような場合には、BigDecimalというクラスを利用して計算する。(誤差自体は無くならないが、10進数にするとおかしいというようなことはなくなる)

 

異なるデータ型の変数を算術計算する場合は、自動的にデータ型が変換される場合がある。2つの数値の演算(2項演算)の場合、データは基本的に大きい方のデータ型に合わせられる。

たとえば、int型とlong型の足し算を行った場合、結果はlong型になる。

int a = 10;
long b = 100;
long c = a + b;

 

結果はlong型なのでint型の変数に代入したい時はキャストが必要になる。

(ただし、intのデータ範囲を超えた値の場合、結果はおかしくなる)

int a = 10;
long b = 100;
int c = a + b;

  datatype javac Renshu_ori_6.java

Renshu_ori_6.java:5: エラー: 不適合な型: 精度が失われる可能性があるlongからintへの変換

        int c = a + b;

                  ^

エラー1個

int a = 10;
long b = 100;
int c = (int)(a + b);

  datatype java Renshu_ori_6      

110

 

整数(int型)と少数(double型)の足し算を行った場合、演算結果は少数(double型)になる。

int a = 1;
double b = 1.5;
double c = a + b;

  datatype java Renshu_ori_6      

2.5

 

もし、結果を(int型)の変数に代入したい場合は、キャストが必要になる。

ただし、少数部分は切り捨てられる

int a = 1;
double b = 1.5;
int c = (int)(a + b);

  datatype java Renshu_ori_6

2

 

異なるデータ型の演算では「基本的に大きい方のデータ型」になるという理解でかまわないが、細かく言うと以下のルールに従う。これは足し算だけでなく、各種数値演算のときに共通のルールです。ルール4で、charとcharの足し算もintになるのが少し豆知識ですが、普通charなどは足し算することはないので、知らなくても困らないルールです。

二項演算のときの昇格ルール

1.一方のオペランドがdoubleの場合は他方もdoubleにする

2.一方のオペランドがfloatの場合は他方もfloatにする

3.一方のオペランドがlongならば他方もlongにする

4.両オペランドをintにする

 

 

参照型

基本データ型以外のデータ型は参照型と呼ばれる。

参照型には後述のクラスや配列などがある

文字列を表すStringはクラスの一種で参照型

変数に代入を行う場合、基本データ型の場合は、変数の中にはデータそのものが入るが、参照型の場合は参照が入る

 

「参照」とは「値を指し示すもの」でプログラム用語では一般に「ポインタ」などとも呼ばれる。(アドレス値、番地情報のようなもの)

参照型ではnullというリテラルが利用できる。nullは「何も参照していない」と言うことを示すリテラル

 

 

しばらく学習が空いてしまいました...。

学習テキスト

基礎からのJava 改訂版