お題 §
以下のソースコードは実行するとiと-iは同じになりますが、sと-sは同じになりません。両者の違いはintとshortの型の違いだけですがどちらも符号付き整数です。
- なぜiと-iは同じなのか
- なぜ-sは同じにならないのか
全部説明できたらC#の大ベテランです。
解説は最後に。
ソースコード §
var s = short.MinValue;
Console.WriteLine($"s={s}");
Console.WriteLine($"-s={-s}");
var i = int.MinValue;
Console.WriteLine($"i={i}");
Console.WriteLine($"-i={-i}");
実行結果 §
s=-32768
-s=32768
i=-2147483648
-i=-2147483648
解説 §
解説はテキストを選択すると読めます。
負数を表す2の補数表現は、負数の最大値に対応する正数の最大値を表現できません。2の補数を計算すると元に値に戻ってしまいます。ですから、int.MinValueの値はマイナス演算子で正数にすることはできません。ここまでは、2の補数表現を使用するほとんど全てのプログラミング言語で共通の挙動です。ところが、C#の場合はshort型などint型よりも少ないビット数の型を使うと同じように振る舞いません。C#の数値計算は少なくともint型までbit幅を広げてから行われるので、short.MinValueを負数にする処理はint型に拡大してから行われます。int型では、32768も-32768も楽々表現できるので、特に表現できない数値になることはなく、計算通りの結果となります。