目次

概要

本項では、組み込み型の補足として、整数型浮動小数点数型など、いわゆる「数値」がらみの少し細かい話をします。

int型とdouble型

C#の数値型には、使用する記憶領域サイズ違いのものがいくつかあります。その中で代表的な位置づけにあるのは、整数ではint型(4バイト)、浮動小数点数ではdouble型(8バイト)です。

どう「代表的」かというと以下のような感じです。

  • int型より小さいサイズの整数は、計算時にいったんint扱いされる
  • 浮動小数点数は、計算時にいったんdouble扱いされる
  • リテラルも、数字だけを書くと基本的にintdouble扱い

例えば、下図のように、short型(2バイト)同士の計算をすると、結果がint型になります。

整数型同士の計算結果はintに

これは、大体必要とされる桁数がint型かdouble型で十分まかなえるため、これらの計算が一番高速になるようなCPUが多いという理由があります。 (実際にはいろんな要員がからんで、int型かdouble型を使っておけば安泰というわけでもなく、何が最適かは状況によります。 流行りのCPU構造などによって、時代による差もあったりします。最近だとdouble型(8バイト)よりもfloat型の方が有利になる場面も多いです。)

10進数以外の数値

普通に整数リテラルを書くと10進数なわけですが、その他に、16進数と2進数で書くことができます。

16進数や2進数については「コンピューターでよく使う数字」を参照してください。

16進数リテラル

普通に数字を並べると10進数扱いされますが、先頭に0xを付けると16進数で数値を書けるようになります(hexadecimal literals)。

var x = 0xFF;       // 16進数のFF = 15×16 + 15 = 10進数だと 255
var y = 0XabcdABCD; // 0X や、A~F の記号は大文字・小文字どちらでもOK

2進数リテラル

Ver. 7

C# 7で、2進数でもリテラルを書けるようになりました(binary literals)。 先頭に0bを付けると2進数リテラルになります。

var x = 0b10010101; // 2進数の10010101 = 128 + 16 + 4 + 1 = 10進数だと 149
var y = 0B1111;     // b は大文字・小文字どちらでもOK

よくある用途としては、「フラグ」があります。 以下のように、ビットごとに意味があって、ビットの組み合わせを表したい場合です。

enum ColorFlags
{
    Black = 0,

    Red = 1,
    Green = 0b10,
    Blue = 0b100,

    Yellow = Red | Green,
    Cyan = Green | Blue,
    Magenta = Blue | Red,

    White = Red | Green | Blue,
}

この例では、1ビット目が赤(red)、2ビット目が緑(green)、3ビット目が青(blue)を表していて、 「赤と緑の組み合わせが黄色(yellow)」というのを、1ビット目と2ビット目が1なので、2進数で11(つまり、10進数で3)という数値で表しています。 こういう表し方を、特定の場所に旗(flag)を立てて目印にするのに例えて、「フラグ」と呼びます。

数値リテラルの先頭は 0~9

16進数リテラルも2進数リテラルも、どちらも0から始まります(それぞれ、0x0b始まり)。 10進数リテラルも数字(0~9のいずれか)から始まるわけで、数値リテラルは常に数字始まりです。

一方で、C#では識別子(変数名などに使える名前)に数字始まりを認めていません。例えば0から始まる名前の変数は作れません。 最初の1文字だけを見て、それが識別子なのか数値リテラルなのかを判別できます。

C#で書かれたソースコードの解釈を高速に行うためにこういう仕様になっています。

数字区切り文字

Ver. 7

C# 7では、数値リテラルの数字と数字の間に、_で区切りを入れれるようになりました。 リテラルの桁数が大きい時に便利です。

var million = 1_000_000;
var abcd = 0b1010_1011_1100_1101; // 特に2進数リテラルで有用
var abcd2 = 0xab_cd;              // 16進数リテラルにも使える
var x = 1.123_456_789;            // 浮動小数点数リテラルにも使える

特に2進数リテラルを使うと桁が大きくなりがちなので、2進数リテラルとの組み合わせが便利でしょう。

ちなみに、末尾や先頭、小数点の前後に _ を書くことはできません。以下のコードは全行でコンパイル エラーになります。

var a = _10;
var b = 10_;
var c = 1._0;
var d = 1_.0;
var e = 0x_10;
var f = 0b_10;

他、書く予定

(書きかけ)

  • 科学表記リテラルについて多少詳しめに
  • 浮動小数点数リテラルは . から始めてもOK
  • 整数サフィックスのL, Uは大文字小文字、順序自由: U u L l UL Ul uL ul LU Lu lU lu どれでもOK
    • 数字の1と紛らわしいので小文字のlはあんまり使わないけども
  • 浮動小数点数に触れておく
    • 無限大とNaN
  • IEEE 754規格
    • float, doubleはIEEE 754規格
    • decimalは規格に沿ってない(decimal向けのIEEE規格は、C#ができた当時にはなかった)

更新履歴

ブログ