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

投稿者: Anonymous
int a = -2147483648;
int b = a * -1; // -2147483648

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

-2,147,483,648 ~ 2,147,483,647

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

a = (a * -1) * -1

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

解決

数学的な意味ではなく、結果が桁あふれを起こしていて、それを下位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 になるわけです。

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *