私はint
変数をlong
変数に割り当てようとして、このintおよびlong変換を試みてきました。コードは次のとおりです。
public static void main(String []args){
int i = 1024;
long j = i;
long k = i*i*i*i;
System.out.println("j= " +j+ ", k= " +k);
}
したがって、j
を出力しているときに、単に1024
。しかし、k
の印刷中に、オーバーフロー(k
= 0)が発生しました。私はこの手法を使用してこの問題を解決しました。ここで、各i
をlong
に明示的にキャストしました。つまり.
public static void main(String []args){
int i = 1024;
long j = i;
long k = ((long)i)*((long)i)*((long)i)*((long)i);
System.out.println("j= " +j+ ", k= " +k);
}
今回、j
とk
の両方の正しい値が表示されました。したがって、2番目のケースではint
をキャストする必要があるが、最初のケースではキャストしない必要がある理由を知りたかったのです。 k
、long
であることは、この重い割り当ての後でこの値を保持できます。しかし、それが正しく割り当てられていないのはなぜですか?
その理由はあなたのライン
long k = i*i*i*i;
と考えることができます
long k = ((i*i)*i)*i;
または...
int k1 = i*i;
int k2 = k1*i;
int k3 = k2*i;
long k = k3;
したがって、kn
のいずれかがオーバーフローすると、エラーが発生します。
キャストすると、常にlong
sを乗算することで、この問題を回避できます。
もちろん、初期プログラムの最も簡単な変更は、i
をlong
ではなくint
としてすぐに定義することです。
long i = 1024L;
この問題は、異なる型が異なる量のメモリを使用するという事実に基づいています。intとlongはどちらも整数であり、違いはintは4バイト、longは8バイトです。
コードを少し変更しましょう:
public class Test {
public static void main(String []args){
int i = 1024;
long j = i;
long k = i*i*i;
System.out.println("My multipliers are of type int:");
System.out.println("j= " +j+ ", k= " +k);
System.out.println("Is k less than Integer.MAX_VALUE: " + (k < Integer.MAX_VALUE? "YES" : "NO"));
k = i*i*i*i;
System.out.println("j= " +j+ ", k= " +k);
//now multiplying with j instead of i
System.out.println("\nNow Im working with a long type:");
k = j*j*j;
System.out.println("j= " +j+ ", k= " +k);
System.out.println("Is k less than Integer.MAX_VALUE: " + (k < Integer.MAX_VALUE? "YES" : "NO"));
k = j*j*j*j;
System.out.println("j= " +j+ ", k= " +k);
System.out.println("Is k less than Integer.MAX_VALUE: " + (k < Integer.MAX_VALUE? "YES" : "NO"));
k = j*j*j*j;
}
}
上記のコードは、iを3倍した場合、結果はInteger.MAX_VALUE(2147483647)よりも小さい値であることを示しています。また、4倍した場合、貧しい人には十分な場所がないため、結果は0です。乗数の4バイト。 :)しかし、乗数(右側、j)がlong型の場合、正しい値が出力され、最後の出力では、ステートメントk <Integer.MAX_VALUEがfalseであることがわかります。これがゼロの理由です。 。 :)
i*i*i*i
は、すべてintの乗算なので、結果は整数のみになります(これは、オーバーフローします)。結果が長い場合は、そのうちの1つをlongに変換するだけで十分なので、これで十分です。
long k = ((long)i)*i*i*i;
最初に、iの値はintであり、整数の乗算が行われ、i*i*i*i
結果は整数なので、 integer overflow.
2番目のケースと同様に、結果をlong
として明示的に伝える/作成します。
乗算の結果である_1099511627776
_は整数乗算なので_>Integer.MAX_VALUE
_なので、_i*i*i
_値の後は_1073741824
_になりますが、_1024
_との乗算後は範囲外になります 整数オーバーフロー が発生し、kは0になります。
i
の1つをlong
にキャストできます1L
_(_1L*i*i*i*i
_)を乗算しますが、_i*i*i*i*1L
_は乗算しませんi*i*i
_をlongに割り当てて、このようにi
と乗算することもできますlong k =(k=i*i*i)*i;