2016.01.20
変数
数値型変数の最小値と最大値
変数型 | 最小値 | 最大値 |
---|---|---|
byte | Byte.MIN_VALUE | Byte.MAX_VALUE |
short | Short.MIN_VALUE | Short.MAX_VALUE |
int | Integer.MIN_VALUE | Integer.MAX_VALUE |
float | Float.MIN_VALUE | Float.MAX_VALUE |
double | Double.MIN_VALUE | Double.MAX_VALUE |
Javaソースコード その1
MinMaxValue.java
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021
public class MinMaxValue { public static void main( String[] args ) { System.out.println( "byteの最小値=" + Byte.MIN_VALUE ); System.out.println( "byteの最大値=" + Byte.MAX_VALUE ); System.out.println(); System.out.println( "shortの最小値=" + Short.MIN_VALUE ); System.out.println( "shortの最大値=" + Short.MAX_VALUE ); System.out.println(); System.out.println( "intの最小値=" + Integer.MIN_VALUE ); System.out.println( "intの最大値=" + Integer.MAX_VALUE ); System.out.println(); System.out.println( "longの最小値=" + Long.MIN_VALUE ); System.out.println( "longの最大値=" + Long.MAX_VALUE ); System.out.println(); System.out.println( "floatの最小値=" + Float.MIN_VALUE ); System.out.println( "floatの最大値=" + Float.MAX_VALUE ); System.out.println(); System.out.println( "doubleの最小値=" + Double.MIN_VALUE ); System.out.println( "doubleの最大値=" + Double.MAX_VALUE ); } }
実行結果
MinMaxValue.javaの出力結果
byteの最小値=-128 byteの最大値=127 shortの最小値=-32768 shortの最大値=32767 intの最小値=-2147483648 intの最大値=2147483647 longの最小値=-9223372036854775808 longの最大値=9223372036854775807 floatの最小値=1.4E-45 floatの最大値=3.4028235E38 doubleの最小値=4.9E-324 doubleの最大値=1.7976931348623157E308
この結果から、floatとdoubleの最小値は、0.0(ゼロ)として扱わない数値の最小値であることがわかります。変数に格納できる範囲の最小は、それぞれの先頭にマイナスを付けた-Float.MAX_VALUEと-Double.MAX_VALUEと考えて良いです。Float.MIN_VALUEとDouble.MIN_VALUEを使うときには、これらのことに気を付けてください。
次に、これらの使い方を紹介します。
数値が扱えるJavaの変数には、byte型/short型/int型/long型/float型/double型があり、それぞれ格納できる数値の範囲が違います。変数への値の代入や計算のオーバーフロー・アンダーフローを避けるために変数が持てる値の範囲をプログラム中で取得し、数値が変数値の範囲内かどうかを判定します。これは、まず情報量の多い変数に値を代入・計算し、その結果が格納したい変数型の範囲内であれば、その変数に値を格納する方法で行われます。
具体的には、int型の変数に計算結果を代入する場合、int型より情報量の多いlong型で計算を行い、その結果の範囲がint型の範囲に入っているかを判定し、範囲内であればlong型の値をint型の変数に型キャストして代入します。範囲外であれば、処理の中断/エラーメッセー表示などを行うようにします。ただし、int型どうしの計算でオーバーフローしないことが明らかであれば、このような処理は不要です。float型の計算も同様に、double型で計算した結果で判定します。
Javaソースコード その2
MinMaxValue2.java
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028
public class MinMaxValue2 { public static void main( String[] args ) { int a, b; // オーバーフローした結果をそのまま表示 a = 100000; b = 100000; int ans = a * b; System.out.println( "オーバーフロー有 : " + a + "x" + b + "=" + ans ); // long型でオーバーフローを防ぐ long ansl = (long)a * (long)b; System.out.println( "オーバーフロー無 : " + a + "x" + b + "=" + ansl ); // int型の変数に計算結果を代入できるかを判定 if ( ( ansl < (long)Integer.MIN_VALUE ) || ( ansl > (long)Integer.MAX_VALUE ) ) // 代入不可 System.out.println( ansl + "をint型変数に代入できない" ); else { // 代入可 System.out.println( ansl + "をint型変数に代入できる" ); // 型キャストして代入 ans = (int)ansl; } } }
実行結果
MinMaxValue2.javaの出力結果
オーバーフロー有 : 100000x100000=1410065408 オーバーフロー無 : 100000x100000=10000000000 10000000000をint型変数に代入できない
上記の出力結果のように、オーバーフローした計算結果もint型の変数に格納されてしまい、その後の処理で異常が発生する可能性が高くなります。桁数の多い数値どうしの計算を行う処理には、情報量の多い型で計算して範囲の検査をすると安全に動作するプログラムが作成できます。