Java開発ノート(七)強制型変換のリスク

2534 ワード

符号化の過程で、ある変数に数値を割り当てるだけでなく、ある変数を別の変数にも割り当てることができます.たとえば、次のコードは、整数変数changjiangを整数変数longRiverに割り当てます.
//  6397 
int changjiang = 6397;
System.out.println("changjiang="+changjiang);
int longRiver = changjiang; //  
System.out.println("longRiver="+longRiver);

上記のテストコードを実行すると、2つの整数変数の数値が同じであることがわかります.
同じタイプの変数間で互いに値を割り当てるのは全く問題なく、面倒なのは異なるタイプの変数に値を割り当てることです.整数変数をロング整数変数に割り当てると、コンパイラがエラーを直接提示していることがわかります.この場合、元の変数の前に強制変換タイプを表す「(新しいタイプ)」を追加する必要があります.書き換えた変数付与文は、次のようになります.
//  , “( )” 
long longRiver = (long) changjiang; //  

しかしながら、異なるタイプの変数が互いに値を付与することはリスクがあり、特に高精度の数字を低精度の数字に値を付与し、例えば8バイトの長整数を強制的に4バイトの整数に変換した結果、低位の4バイトのみが保持され、高位の4バイトは破棄される.次の実験では、世界人口の74億人を長整数変数で保存し、この長整数変数を整数変数に付与します.具体的なコードは以下の通りです.
//  2018 , 74 
long worldPopulation = 7444443881L;
System.out.println("worldPopulation="+worldPopulation);
//  
int shijierenkou = (int) worldPopulation; //  
System.out.println("shijierenkou="+shijierenkou);

以上の実験コードを実行し、印刷された変数値は以下のログを参照してください.
worldPopulation=7444443881
shijierenkou=-1145490711

長い整数が整数に強制的に回転し,結果として数値全体が失われることが分かった.
整数間強制変換タイプに問題がある以上、小数間のタイプ強制変換も例外ではありません.二重精度数を強制的に浮動小数点数に変換すると、デジタル精度も悪くなります.次に、よく見られる円周率を例にとると、その密率は中国古代の数学者祖沖が発見したもので、その数値は3.1415926で、小数部を含めて8桁の数字がある.doubleタイプのデジタル精度は15〜16ビットに達するため,二重精度変数を用いて円緻密率を保存することは全く問題ない.しかし、この密率の二重精度変数を浮動小数点変数に割り当てると、どうなるのでしょうか.次のコードでは、二重精度数を強制的に浮動小数点数に変換するシーンを示します.
// 3.1415926 , 
double zulv = 3.1415926;
System.out.println("zulv="+zulv);
//  
float pai = (float) zulv; //  
System.out.println("pai="+pai);

上記の実験コードを実行し、ログ印刷の変数値を以下のようにします.
zulv=3.1415926
pai=3.1415925

可視浮動小数点変数に保存された密率値は3.1415925となり,二重精度変数に比べて末尾の6は5となった.密率数値が変化するのは、floatタイプのデジタル精度が6〜7ビットしかないのに対し、前記密率の総桁数が8ビットに達し、floatタイプの精度範囲を明らかに超え、強転後の浮動小数点変数が範囲外の精度を失うためである.
整数間の相互回転、小数間の相互回転のほか、整数が小数と小数で整数を回転する場合もあるが、整数と小数の相互回転には依然として数値損失の問題がある.例えば、1つの二重精度変数が1つの整数変数に付与されると、整数変数は小数部を保存する空間がないため、本来の二重精度変数は小数点の後ろの数字はすべて捨てられる.次のコードは、このようなデジタルタイプ変換の例を示しています.
double jiage = 9.9;
System.out.println("jiage="+jiage);
//  , , 
int price = (int) jiage; //  
System.out.println("price="+price);

以上のテストコードを実行し、ログの印刷結果は以下の通りです.
jiage=9.9
price=9

やはり整数変数は二重精度変数の小数部を失っていることから,異なるタイプ間の変数の相互回転問題が多く,必要でなければ2つの変数のタイプ強制変換操作を行わないのが一般的であることがわかる.
Javaテクノロジーの詳細については、「Java開発ノート(シーケンス)章ディレクトリ」を参照してください.