C# 中的基本數值類型

在以前的文章中(地址:https://www.vinanysoft.com/c-sharp-basics/introducing/),以 HelloWorld 程序爲基礎,介紹 C# 語言、它的結構、基本語法以及如何編寫最簡單的程序有了初步理解。c#

接下來介紹基本的 C# 類型,繼續鞏固 C# 的基礎知識。本系列文章到目前爲止只用過少許的內置數據類型,並且只是一筆帶過。在 C# 中有大量的類型,並且能夠經過合併類型來建立新類型。數組

但 C# 有幾種類型很是簡單,是其餘全部類型的基礎,它們稱爲預約義類型(predefined type)或基元類型( primitive type)。ui

C# 提供了 16 種預約義類型,以下圖所示。其中包括 13 種簡單類型和 3 種非簡單類型。code

全部預約義類型的名稱都由全小寫的字母組成。預約義的簡單類型包括如下 3 種。blog

  • 11 種數值類型。
    • 不一樣長度的有符號和無符號整數類型。
    • 用於科學計算的二進制浮點類型 floatdouble
    • 一種用於金融計算的十進制高精度浮點類型 decimal。與 floatdouble 不一樣,decimal 類型能夠準確地表示分數。decimal 類型經常使用於貨幣的計算。
  • 一種 Unicode 字符類型 char
  • 一種布爾類型 boolbool 類型表示布爾值而且必須爲 truefalse

非簡單類型以下:ci

  • object,它是全部其餘類型的基類。
  • string,它是一個 Unicode 字符數組。
  • dynamic,使用動態語言編寫的程序集時使用。

全部預約義類型都直接映射到底層的 .NET 類型。C# 的類型名稱就是 .NET 類型的別名,因此使用 .NET 的類型名稱也能很好地符合 C# 語法,不過並不鼓勵這樣作。在 C# 程序中,應該儘可能使用 C# 類型名稱而不是 .NET類型名稱。資源

整數類型

C# 有八種整數類型,可選擇最恰當的一種來存儲數據以免浪費資源。下表列出了 C# 支持的整型類型:開發

C# 類型/關鍵字 範圍 大小 .NET 類型
sbyte -128 到 127 8 位帶符號整數 System.SByte
byte 0 到 255 無符號的 8 位整數 System.Byte
short -32,768 到 32,767 有符號 16 位整數 System.Int16
ushort 0 到 65,535 無符號 16 位整數 System.UInt16
int -2,147,483,648 到 2,147,483,647 帶符號的 32 位整數 System.Int32
uint 0 到 4,294,967,295 無符號的 32 位整數 System.UInt32
long -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 64 位帶符號整數 System.Int64
ulong 0 到 18,446,744,073,709,551,615 無符號 64 位整數 System.UInt64

C# 全部基元類型都有短名稱(最左列)和完整名稱(最右列)。完整名稱對應 BCL(基類庫)中的類型名稱。get

因爲基元數據類型是其餘類型的基礎,因此 C# 爲基元數據類型的完整名稱提供了短名稱(或稱爲縮寫)。其實從編譯器的角度看,兩種名稱徹底同樣,最終都生成相同的代碼。事實上,檢查最終生成的 CIL 代碼,根本看不出源代碼具體使用的名稱。編譯器

例如,如下聲明聲明瞭相同類型的變量:

int a = 123;
System.Int32 b = 123;

C# 支持完整 BCL 名稱和關鍵字,形成開發人員犯難在何時用什麼。不要時而用這個,時而用那個,最好堅持用一種。

C# 開發人員通常用 C# 關鍵字。例如,用 int 而不是 System.Int32,用 string 而不是 System.String(甚至不要用 String 這種簡化形式)。

浮點類型(floatdouble

C# 支持如下預約義浮點類型:

C# 類型/關鍵字 大體範圍 精度 大小 .NET 類型
float ±1.5 x 10−45 至 ±3.4 x 1038 大約 6-9 位數字 4 個字節 System.Single
double ±5.0 × 10−324 到 ±1.7 × 10308 大約 15-17 位數字 8 個字節 System.Double

在上表中,最左側列中的每一個 C# 類型關鍵字都是相應 .NET 類型的別名。 它們是可互換的。 例如,如下聲明聲明瞭相同類型的變量:

double a = 12.3;
System.Double b = 12.3;

decimal 類型

C# 類型/關鍵字 大體範圍 精度 大小 .NET 類型
decimal ±1.0 x 10-28 至 ±7.9228 x 1028 28-29 位 16 個字節 System.Decimal

floatdouble 相比,decimal 類型具備更高的精度和更小的範圍,所以它適合於財務和貨幣計算。

浮點數舍入偏差

floatdouble 在內部都是基於 2 來表示數值的。所以只有基於 2 表示的數值纔可以精確表示。事實上,這意味着大多數有小數部分的字面量(它們都基於 10)將沒法精確表示。例如:

float f1 = 1F;
float f2 = 0.9F;

Console.WriteLine(f1 - f2);

double d1 = 1D;
double d2 = 0.9D;

Console.WriteLine(d1 - d2);

decimal decimal1 = 1M;
decimal decimal2 = 0.9M;

Console.WriteLine(decimal1 - decimal2);

輸出

0.100000024
0.09999999999999998
0.1

這就是爲何 floatdouble 不適合金融計算。相反,decimal 基於 10,它可以精確表示基於 10 的數值(也包括它的因數,基於 2 和基於 5 的數值)。由於實數的字面量都是基於 10 的,因此 decimal 可以精確表示像 0.1 這樣的數。然而,floatdoubledecimal 都不能精確表示那些基於 10 的循環小數:

decimal m = 1M / 6M;
Console.WriteLine(m);

decimal m2 = m + m + m + m + m + m;
Console.WriteLine(m2);
Console.WriteLine();


double d = 1d / 6d;
Console.WriteLine(d);

double d2 = d + d + d + d + d + d;
Console.WriteLine(d2);

輸出

0.1666666666666666666666666667
1.0000000000000000000000000002

0.16666666666666666
0.9999999999999999

字面量

字面量(literal value)表示源代碼中的固定值。

Console.WriteLine(123);
Console.WriteLine(456.789);

默認狀況下,輸入帶小數點的字面量,編譯器自動把它解釋成 double 類型。 若是輸入的是整數值(沒有小數點)一般默認爲 int, 若是值太大,以致於沒法用 int 來存儲。編譯器會把它解釋成 long

static void Main(string[] args)
{
    var expectIsInt = 123;
    var expectIsLong = 9223372036854775807;
    var expectIsDouble = 3.14;

    Console.WriteLine($"expectIsInt 的類型是:{expectIsInt.GetType().Name};" +
                        $"expectIsLong 的類型是:{expectIsLong.GetType().Name};" +
                        $"expectIsDouble 的類型是:{expectIsDouble.GetType().Name}");
}

輸出

expectIsInt 的類型是:Int32;expectIsLong 的類型是:Int64;expectIsDouble 的類型是:Double

因爲帶小數點的值默認爲 double 類型,因此下面輸出的結果中,超過可容納的精度部分會被丟棄。

static void Main(string[] args)
{
    Console.WriteLine(5.141231231234567898765);
}

輸出

5.141231231234568

要顯示具備完整精度的數字,必須將字面量顯式聲明爲 decimal 類型,經過追加一個 M(或者 m)來實現。

static void Main(string[] args)
{
    Console.WriteLine(5.141231231234567898765M);
}

輸出

5.141231231234567898765

還可使用 FD 做爲後綴,將字面量分別顯式聲明爲 float 或者 double。 對於整數數據類型,整數字面量的類型是像下面這樣肯定的:

  • 若是整數字面量沒有後綴,則其類型爲如下類型中可表示其值的第一個類型:intuintlongulong
  • 若是整數字面量以 Uu 爲後綴,則其類型爲如下類型中可表示其值的第一個類型:uintulong
  • 若是整數字面量以 Ll 爲後綴,則其類型爲如下類型中可表示其值的第一個類型:longulong

    備註:可使用小寫字母 l 做爲後綴。 可是,這會生成一個編譯器警告,由於字母 l 可能與數字 1 混淆。 爲清楚起見,請使用 L

  • 若是整數字面量的後綴爲 ULUluLulLULulUlu,則其類型爲 ulong

字面量的後綴不區分大小寫。但通常推薦大寫,避免出現小寫字母 l 和數字 1 很差區分的狀況。

從 C# 7.0 開始提供支持將 _ 用做數字分隔符,能夠將數字分隔符用於全部類型的數字文本。

double d = 3D;
d = 4d;
d = 3.934_001;

float f = 3_000.5F;
f = 5.4f;

decimal myMoney = 3_000.5m;
myMoney = 400.75M;

C# 支持使用科學記數法,指數記數法要求使用 eE 中綴,在中綴字母后面添加正整數或者負整數,並在字面量最後添加恰當的數據類型後綴。

double d = 0.42e2;
Console.WriteLine(d);  // output 42;

float f = 134.45E-2f;
Console.WriteLine(f);  // output: 1.3445

decimal m = 1.5E6m;
Console.WriteLine(m);  // output: 1500000

使用 0x0X 前綴表示十六進制計數法,在 C# 7.0 和更高版本中使用 0b0B 前綴表示二進制計數法。

var hexLiteral = 0x2A;
var binaryLiteral = 0b_0010_1010;

總結

C# 語言的基元類型包括八種整數類型、兩種用於科學計算的二進制浮點類型、一種用於金融計算的十進制浮點類型。浮點型存在舍入偏差,使用的時候要注意。

相關文章
相關標籤/搜索