Javaデータオーバーフローコードの詳細
javaは比較的安全な言語です。データが溢れ出す時はどう処理しますか?コードの一部を見て、
オーバーフローの問題はどう解決しますか?思いつきやすいプランの一つは、より大きなデータタイプで、long型は8バイトを占めています。
次の例は、別の文章から見たものです。
1000*60*24*30*3; 1000 L*60*60*24*30*3;の計算結果は全部77760000です。この結果こそ必要なものです。
なぜこのような状況が発生したのか?Javaは乗算をする時、確定したデータタイプが表示されていない場合、彼はデフォルトでintデータタイプで計算すると、例えば1000*60*24*30*3のようになります。この数値は計算時にintデータがオーバーフローしてしまい、マイナスの場合があります。
(long)1000*60*60*24*30*3; 1000 L*60*60*24*30*3;この両者は、前者が最初の計算数を強制的にlongにした後、longタイプの演算によって正しい計算結果が得られ、後者は計算時にデータタイプをlongに修正することで直接に正しい計算結果を得ることができます。
この点はやはりとても晦渋で、今後のミスを防ぐために注意します。この間違いはよくないと思います。
もう一つはLの位置です。1000 L*60*24*30*3ちょっとおかしいです。1000*60 L*60*24*30*31000*60*60 L*24*30*31000*60*60*24*30 L*3これらの書き方は正確にlong型に変えられますが、1000*60*24*30*3 Lです。違います。しかも3×60*24*30*1000という書き方の場合は、Lはどの数字の後ろについても大丈夫です。ちょっと意味が分かりません。使う時はデバッグテストを優先してこの列の計算結果を確定します。
締め括りをつける
以上がJavaデータのオーバーフローコードについての詳細な内容のすべてです。このサイトの他のテーマをご覧ください。問題があったらメッセージをください。
public class Overflow
{
/**
* @param args
*/
public static void main(String[] args)
{
int big = 0x7fffffff; //max int value
System.out.println("big = " + big);
int bigger = big * 4;
System.out.println("bigger = " + bigger);
}
}
運転の結果は:
big = 2147483647
bigger = -4
intタイプはjavaでは4バイトでプラスマイナスに分かれていますので、最大int型の数値は0 x 7 fffffffです。変数biggerは明らかにオーバーフローしていますが、コンパイルエラーや運転エラーがありません。よさそうですが、いいこととは限らない場合があります。この例のように、私たちが期待している結果は-4ではなく、プログラムにも間違いがないということです。オーバーフローの問題はどう解決しますか?思いつきやすいプランの一つは、より大きなデータタイプで、long型は8バイトを占めています。
public class Overflow
{
/**
* @param args
*/
public static void main(String[] args)
{
long reallyBig = 0x7fffffffL;
System.out.println("reallyBig = " + reallyBig);
long reallyBigger = reallyBig * 4;
System.out.println("reallyBigger = " + reallyBigger);
}
}
出力、
reallyBig = 2147483647
reallyBigger = 8589934588
一つの問題を続けて考えてみます。一番目の例はなぜオーバーフローしたのですか?第二の例の結果からいくつかのヒントを得ることができます。8589934588の16進数は1 FFFFFCで、4バイトしか残していません。FFFFFCはFFFFFFFCです。これは補数です。最高位が1なので、まだマイナスです。元のコードに変換します。(符号位以外は反プラス1)は100000 4、つまり-4です。次の例は、別の文章から見たものです。
long now = System.currentTimeMillis();
long m1 = now-1000*60*60*24*30*3;
long test = (long)1000*60*60*24*30*3;
long nocast = 1000L*60*60*24*30*3;
long m2 = now-1000L*60*60*24*30*3;
System.out.println(" test:"+test);
System.out.println(nocast);
System.out.println("now:"+now);
System.out.println("m1:"+m1);
System.out.println("m2:"+m2);
出力結果:
test:7776000000
7776000000
now:1359510417546
m1:1360324352138
m2:1351734417546
ちょっとおかしいですね。1000*60*24*30*3の計算値と1000 L*60*24*30*3の計算値は違います。1000*60*60*24*30*3の計算結果は-813934592です。1000*60*24*30*3; 1000 L*60*60*24*30*3;の計算結果は全部77760000です。この結果こそ必要なものです。
なぜこのような状況が発生したのか?Javaは乗算をする時、確定したデータタイプが表示されていない場合、彼はデフォルトでintデータタイプで計算すると、例えば1000*60*24*30*3のようになります。この数値は計算時にintデータがオーバーフローしてしまい、マイナスの場合があります。
(long)1000*60*60*24*30*3; 1000 L*60*60*24*30*3;この両者は、前者が最初の計算数を強制的にlongにした後、longタイプの演算によって正しい計算結果が得られ、後者は計算時にデータタイプをlongに修正することで直接に正しい計算結果を得ることができます。
この点はやはりとても晦渋で、今後のミスを防ぐために注意します。この間違いはよくないと思います。
もう一つはLの位置です。1000 L*60*24*30*3ちょっとおかしいです。1000*60 L*60*24*30*31000*60*60 L*24*30*31000*60*60*24*30 L*3これらの書き方は正確にlong型に変えられますが、1000*60*24*30*3 Lです。違います。しかも3×60*24*30*1000という書き方の場合は、Lはどの数字の後ろについても大丈夫です。ちょっと意味が分かりません。使う時はデバッグテストを優先してこの列の計算結果を確定します。
締め括りをつける
以上がJavaデータのオーバーフローコードについての詳細な内容のすべてです。このサイトの他のテーマをご覧ください。問題があったらメッセージをください。