int 型の変数 -2147483648 に -1 をかけると -2147483648 になるのはなぜか

[code]

    int a = -2147483648;
    int b = a * -1; // -2147483648
    
[/code]

32ビットの signed int の値の範囲が

> -2,147,483,648 ～ 2,147,483,647

であることから、b の値が +2147483648 になり得ないことは分かります。  
ただ、-2147483648 になる理由が分かりません。  
C# だけでなく Java などでも同様のようです。  
仕様と言ってしまえば、それまでなのでしょうが、何か合理的な理由があるのでしょうか？

[code]

    a = (a * -1) * -1
    
[/code]

という式が成り立つようにするためでしょうか。




数学的な意味ではなく、結果が桁あふれを起こしていて、それを下位32bit signed intとして  
見た場合の値が -2147483648 なのだと考えられます。

Windows10 の電卓ツールでプログラマモードにすると 64bit計算が出来ますので、それで  
確かめてみてください。

32bit signed int を 64bit signed int に拡張すると、-2147483648 は 0xFFFFFFFF80000000 に  
なります。 -1 は 0xFFFFFFFFFFFFFFFF で、掛けると結果は 0x0000000080000000 で、  
64bit演算では正の数の 2147483648 になりますが、答えを格納する領域が 32bit しかない  
ために、-2147483648 に見えるわけです。

あるいは、32bit 同士の演算だったとしても、0x80000000 と 0xFFFFFFFF を掛けると、  
結果は 0x7FFFFFFF80000000 になりますが、下位32bit は上記と同じ 0x80000000 で  
32bit signed int として見れば、-2147483648 になるわけです。




数学的な意味ではなく、結果が桁あふれを起こしていて、それを下位32bit signed intとして  
見た場合の値が -2147483648 なのだと考えられます。

Windows10 の電卓ツールでプログラマモードにすると 64bit計算が出来ますので、それで  
確かめてみてください。

32bit signed int を 64bit signed int に拡張すると、-2147483648 は 0xFFFFFFFF80000000 に  
なります。 -1 は 0xFFFFFFFFFFFFFFFF で、掛けると結果は 0x0000000080000000 で、  
64bit演算では正の数の 2147483648 になりますが、答えを格納する領域が 32bit しかない  
ために、-2147483648 に見えるわけです。

あるいは、32bit 同士の演算だったとしても、0x80000000 と 0xFFFFFFFF を掛けると、  
結果は 0x7FFFFFFF80000000 になりますが、下位32bit は上記と同じ 0x80000000 で  
32bit signed int として見れば、-2147483648 になるわけです。

