ナローイング変換
日本語 | 縮小変換 |
英語 | narrowing conversion |
ふりがな | なろーいんぐへんかん |
フリガナ | ナローイングヘンカン |
プリミティブ型の値をサイズの大きい方から小さい方へと変換すること。
明示的キャストによって行われる。
たとえばlong型からbyte型へ代入する場合のように、サイズの小さいプリミティブ型変数からサイズの大きいプリミティブ型変数へ値を代入する際には、データの変換が行われる。これは、サイズが異なるためそのままでは代入できないからである。
大きい方から小さい方への変換のため「入りきらない」可能性があり、そのため通常はキャストが必要である。
整数型同士の場合、基本的に変換は行われず、ビットデータがそのままコピーされる。その際、右端のビット(小さい桁の方のビット)の側はそのままコピーされ、左端のビット(大きい桁の方のビット)の方が切り捨てられる。
左端のビットは符号ビットだが、これすらも斬り落とされるため、符号も含めて全く異なる値になる場合がある。そのため、できるだけ避けた方が良い。
浮動小数点型から整数型へ変換する場合もこれに当たる。
この場合、データの形式が全く異なるため、同じ値の整数型に完全に変換される。
この際、小数点以下の値は切り落とされるため、浮動小数点の特定の小数点以下を切り捨てる際に「必要な桁数分の10の累乗を求め、整数型にナローイング変換してから、再び浮動小数点型にワイドニング変換して戻す」といったテクニックが使用されることがある。
参照型変数の場合でも、一応「ダウンキャスト」をナローイング変換と呼ぶ。ただし、ダウンキャストの方が一般的であるため、あまりこの用法では使用されない。
ダウンキャストでは参照値やインスタンスに「全く変化が起きない」ことを考えると、プリミティブ型のナローイング変換とは別物と考えた方がいいだろう。
実際の所、ダウンキャストの例を挙げるまでもなく、あまり使用されない用語である。
ちなみに、逆に大きい型から小さい型へと変換することを「ワイドニング変換」と呼ぶ。
明示的キャストによって行われる。
たとえばlong型からbyte型へ代入する場合のように、サイズの小さいプリミティブ型変数からサイズの大きいプリミティブ型変数へ値を代入する際には、データの変換が行われる。これは、サイズが異なるためそのままでは代入できないからである。
大きい方から小さい方への変換のため「入りきらない」可能性があり、そのため通常はキャストが必要である。
整数型同士の場合、基本的に変換は行われず、ビットデータがそのままコピーされる。その際、右端のビット(小さい桁の方のビット)の側はそのままコピーされ、左端のビット(大きい桁の方のビット)の方が切り捨てられる。
左端のビットは符号ビットだが、これすらも斬り落とされるため、符号も含めて全く異なる値になる場合がある。そのため、できるだけ避けた方が良い。
浮動小数点型から整数型へ変換する場合もこれに当たる。
この場合、データの形式が全く異なるため、同じ値の整数型に完全に変換される。
この際、小数点以下の値は切り落とされるため、浮動小数点の特定の小数点以下を切り捨てる際に「必要な桁数分の10の累乗を求め、整数型にナローイング変換してから、再び浮動小数点型にワイドニング変換して戻す」といったテクニックが使用されることがある。
参照型変数の場合でも、一応「ダウンキャスト」をナローイング変換と呼ぶ。ただし、ダウンキャストの方が一般的であるため、あまりこの用法では使用されない。
ダウンキャストでは参照値やインスタンスに「全く変化が起きない」ことを考えると、プリミティブ型のナローイング変換とは別物と考えた方がいいだろう。
実際の所、ダウンキャストの例を挙げるまでもなく、あまり使用されない用語である。
ちなみに、逆に大きい型から小さい型へと変換することを「ワイドニング変換」と呼ぶ。
参考サイト
- (参考サイトはありません)
// Sample.java
public class Sample
{
public static void main( String[] args )
{
// サイズの大きい型からから小さい型へと
// 「ナローイング」します。
// 通常はキャストが必要です。
long l = 10;
byte b = (byte)l;
System.out.println( b );
// 10
// キャストしないとコンパイルエラーが発生します。
// b = l;
// コンパイルエラー:
// 型の不一致: long から byte には変換できません。
// 入りきらない場合には無理矢理左のビットから斬り落とされます。
b = (byte)Long.MAX_VALUE;
System.out.println( b );
// -1
// 左端の「符号ビット」も斬り落とされてそのまま格納されてしまうため、
// 符号も滅茶苦茶になります。
// 浮動小数点型から整数型への変換も
// 「ナローイング変換」です。
double d = 12.5;
l = (long)d;
System.out.println( l );
// 12
// このように、小数点は切り落とされます。
// ダウンキャストも一応「ナローイング変換」になります。
// 実際には変換されていませんが。
String string = new String( "あいうえお" );
Object object = string;
string = (String)object;
System.out.println( string );
// あいうえお
}
}
public class Sample
{
public static void main( String[] args )
{
// サイズの大きい型からから小さい型へと
// 「ナローイング」します。
// 通常はキャストが必要です。
long l = 10;
byte b = (byte)l;
System.out.println( b );
// 10
// キャストしないとコンパイルエラーが発生します。
// b = l;
// コンパイルエラー:
// 型の不一致: long から byte には変換できません。
// 入りきらない場合には無理矢理左のビットから斬り落とされます。
b = (byte)Long.MAX_VALUE;
System.out.println( b );
// -1
// 左端の「符号ビット」も斬り落とされてそのまま格納されてしまうため、
// 符号も滅茶苦茶になります。
// 浮動小数点型から整数型への変換も
// 「ナローイング変換」です。
double d = 12.5;
l = (long)d;
System.out.println( l );
// 12
// このように、小数点は切り落とされます。
// ダウンキャストも一応「ナローイング変換」になります。
// 実際には変換されていませんが。
String string = new String( "あいうえお" );
Object object = string;
string = (String)object;
System.out.println( string );
// あいうえお
}
}
// Sample.java public class Sample { public static void main( String[] args ) { // サイズの大きい型からから小さい型へと // 「ナローイング」します。 // 通常はキャストが必要です。 long l = 10; byte b = (byte)l; System.out.println( b ); // 10 // キャストしないとコンパイルエラーが発生します。 // b = l; // コンパイルエラー: // 型の不一致: long から byte には変換できません。 // 入りきらない場合には無理矢理左のビットから斬り落とされます。 b = (byte)Long.MAX_VALUE; System.out.println( b ); // -1 // 左端の「符号ビット」も斬り落とされてそのまま格納されてしまうため、 // 符号も滅茶苦茶になります。 // 浮動小数点型から整数型への変換も // 「ナローイング変換」です。 double d = 12.5; l = (long)d; System.out.println( l ); // 12 // このように、小数点は切り落とされます。 // ダウンキャストも一応「ナローイング変換」になります。 // 実際には変換されていませんが。 String string = new String( "あいうえお" ); Object object = string; string = (String)object; System.out.println( string ); // あいうえお } }