このページは プリミティブ型と型変換 の補足資料です。整数の内部表現・リテラルの書き方・C# キーワードと .NET 型の関係など、知っておくと理解が深まるトピックをまとめています。
int などの C# キーワードが .NET 型の別名であることを説明できるL・f・m など)の意味を説明できるint・double・string などの C# キーワードは、.NET の型に対して C# が用意した別名(エイリアス) です。どちらで書いても完全に同じ意味になります。
1
2
3
4
5
int x = 42;
System.Int32 y = 42; // まったく同じ型
Console.WriteLine(x.GetType()); // System.Int32
Console.WriteLine(y.GetType()); // System.Int32
主な対応表:
| C# キーワード | .NET 型 | ビット数 |
|---|---|---|
sbyte |
System.SByte |
8 |
byte |
System.Byte |
8 |
short |
System.Int16 |
16 |
ushort |
System.UInt16 |
16 |
int |
System.Int32 |
32 |
uint |
System.UInt32 |
32 |
long |
System.Int64 |
64 |
ulong |
System.UInt64 |
64 |
float |
System.Single |
32 |
double |
System.Double |
64 |
decimal |
System.Decimal |
128 |
bool |
System.Boolean |
— |
char |
System.Char |
16 |
string |
System.String |
— |
💡 どちらを使うべきか: C# コードでは
int・stringなどの C# キーワードを使うのが一般的なスタイルです。System.Int32のような .NET 型名は、リフレクションや他言語との相互運用の文脈でよく目にします。
整数リテラルは 10進数のほかに、16進数(0x プレフィックス)と 2進数(0b プレフィックス)でも書けます。
| プレフィックス | 基数 | 例 | 値 |
|---|---|---|---|
| なし | 10進数 | 255 |
255 |
0x |
16進数 | 0xFF |
255 |
0b |
2進数 | 0b_1111_1111 |
255 |
1
2
3
4
5
6
7
8
int dec = 255; // 10進数
int hex = 0xFF; // 16進数: F = 15、FF = 15×16 + 15 = 255
int bin = 0b_1111_1111; // 2進数
// すべて同じ値
Console.WriteLine(dec); // 255
Console.WriteLine(hex); // 255
Console.WriteLine(bin); // 255
16進数は色の RGB 値(0xFF0000 = 赤)やビットフラグを扱う場面でよく使います。2進数はビットの並びを目で確認したいときに便利です。
_長い数値リテラルはアンダースコアで桁を区切ると読みやすくなります。値には影響しません。
1
2
3
4
int million = 1_000_000;
long bigScore = 9_223_372_036_854_775_807L;
int color = 0xFF_80_00; // 16進数でも使える
int flags = 0b_1010_0011; // 2進数でも使える
数値リテラルにサフィックス(接尾辞) を付けると、型を明示的に指定できます。
| サフィックス | 型 | 例 |
|---|---|---|
| なし(整数) | int |
42 |
L または l |
long |
42L |
U または u |
uint |
42U |
UL または ul |
ulong |
42UL |
| なし(小数) | double |
3.14 |
f または F |
float |
3.14f |
m または M |
decimal |
3.14m |
d または D |
double(明示) |
3.14d |
1
2
3
4
5
6
7
8
var a = 42; // int
var b = 42L; // long
var c = 42U; // uint
var d = 42UL; // ulong
var e = 3.14; // double
var f = 3.14f; // float
var g = 3.14m; // decimal
💡 小文字の
lはフォントによって数字の1と見分けにくいため、Lの大文字を使う習慣があります。
サフィックスの省略時、整数リテラルは既定で int(範囲を超える場合は long)、小数リテラルは既定で double として扱われます。
コンピューターは内部では 0 と 1 だけしか扱えません。符号あり整数型がどうやって負の数を表現しているかを、8ビットの byte / sbyte を例に見てみましょう。
8桁の2進数で 0000 0000(0)から 1111 1111(255)まで素直に割り当てます。
| 10進数 | 2進数 |
|---|---|
0 |
0000 0000 |
1 |
0000 0001 |
127 |
0111 1111 |
128 |
1000 0000 |
255 |
1111 1111 |
符号あり型では最も左のビット(最上位ビット / MSB: Most Significant Bit)を符号ビットとして使います。MSB が 0 なら正(0 を含む)、1 なら負の数を表します。残り7ビットで値を表現するため、正の最大値が 0111 1111 = 127 になります。
| 10進数 | 2進数 | 備考 |
|---|---|---|
127 |
0111 1111 |
MSB=0 → 正の最大値 |
1 |
0000 0001 |
|
0 |
0000 0000 |
|
-1 |
1111 1111 |
MSB=1 → 負 |
-127 |
1000 0001 |
|
-128 |
1000 0000 |
MSB=1 → 負の最小値 |
負の数のビットパターンは2の補数(two’s complement) という方式で決まります。「元の数のビットをすべて反転して 1 を足す」という手順で求められます。
例: -5 のビットパターンを求める
1
2
3
① 5 のビット表現: 0000 0101
② すべてのビットを反転: 1111 1010
③ 1 を加算: 1111 1011 ← これが -5 の2進数表現
検算: 1111 1011 に同じ手順を適用すると 0000 0101(5)に戻ります。
💡 なぜ2の補数を使うのか: この方式を使うと、加算回路を1つ用意するだけで正の数・負の数のどちらも正しく計算できます。ハードウェアが符号を条件分岐で処理する必要がなくなり、設計がシンプルになります。この方式は .NET に限らず、現代のほぼすべてのコンピューターで使われています。
2の補数の仕組みを踏まえると、オーバーフロー時に最大値の次が最小値になる理由が分かります。sbyte の最大値 127(0111 1111)に 1 を足すと:
1
2
3
4
0111 1111 (127)
+ 0000 0001 ( 1)
-----------
1000 0000 → 2の補数で解釈すると -128
繰り上がりで MSB が 1 になり、符号ありとして解釈されるため -128 になります。int でも同じことが起きています。
1
2
3
int maxInt = int.MaxValue;
Console.WriteLine(maxInt); // 2147483647
Console.WriteLine(maxInt + 1); // -2147483648
C# では 2進数リテラルでビットの並びを直接書いて確認することもできます。
1
2
3
4
5
6
7
8
9
byte b = 0b_0111_1111;
Console.WriteLine(b); // 127
// 同じビットパターンを sbyte として解釈すると
sbyte s = unchecked((sbyte)0b_0111_1111);
Console.WriteLine(s); // 127
sbyte overflow = unchecked((sbyte)0b_1000_0000);
Console.WriteLine(overflow); // -128
int は System.Int32 の別名。C# キーワードと .NET 型名はどちらを使っても同じ255)・16進(0xFF)・2進(0b_1111_1111)で書ける_ で桁を区切ると読みやすくなる(値には影響しない)L・U・UL・f・m でリテラルの型を指定できるint.MaxValue を System. を使って書き直してください。
次の3つはすべて同じ値を表しますか?
1
2
3
int a = 255;
int b = 0xFF;
int c = 0b_1111_1111;
次の変数の型を答えてください。
1
2
3
var x = 100L;
var y = 3.14f;
var z = 100;
-1 を8ビットの2の補数で表すと何になりますか?(手順を示して答えてください)
System.Int32.MaxValue
すべて同じ値(255)。10進数・16進数・2進数の表記が違うだけで、コンパイル後のバイナリは同一。
x は long(L サフィックス)、y は float(f サフィックス)、z は int(整数リテラルのデフォルト)。
1
2
3
① 1 のビット表現: 0000 0001
② すべてのビットを反転: 1111 1110
③ 1 を加算: 1111 1111
よって -1 = 1111 1111。