私はこのようなコードを持っています:
int a = 629339;
int b = 4096;
long res = a*b;
結果はです-1717194752
が、longに手動キャストを1つ追加するlong res = ((long)a)*b;
かlong res = (long) a*b;
、結果が正しい場合、2577772544
誰がそれがどのように機能するかを説明できます。
何が行われているのかを理解するには、代入ステートメントをその部分に分割する必要があります。
long res = a*b;
ステップ1は、との値を取得することa
ですb
。
ステップ2はを評価することa * b
です。a
とb
は両方ともint
sなので、これは乗算int
です。したがって、これを掛けると629339
、629339
はになります2577772544
。残念ながら、2577772544
は可能な最大のJava値よりも大きいint
ため、乗算演算はサイレントにオーバーフローします...代わりに取得-1717194752
します。
ステップ3RHSの値をLHSに割り当てます。RHSはint
であり、LHSはfloat
であるため、JLSは、プリミティブな拡大変換を実行すると言います...これは単純に-1717194752
同じlong
値のになります。次に、拡大された値がに割り当てられres
ます。
あなたが期待している答えを得るには、long
算術を使用して乗算を強制的に実行する必要があります。例えば:
long res = ((long) a) * b;
この場合、aとaの乗算がありlong
、これは、をaint
に拡張し、乗算を実行することによって処理されます。これはオーバーフローしなくなりました(最大値を大幅に下回っているため)。したがって、最終的に値をに割り当てると、予想していた数値になります。int
long
long
2577772544
long
res
a*b
は整数であり、長さではありません。
これは整数にすぎないため、すでに32ビットの制限を回避しています。
この整数をlongにキャストし直しても、そのデータは魔法のように回復されません。
long res = a*b;
a*b
キャストの最後(または)に「l」を追加しない限り、整数として扱われます。
Javaチュートリアルによる
intデータ型は、32ビットの符号付き2の補数整数です。最小値は-2,147,483,648、最大値は2,147,483,647(両端を含む)です。整数値の場合、他の何かを選択する理由(上記のような)がない限り、通常、このデータ型がデフォルトの選択です。