C# 中的基本數值類型

来源:https://www.cnblogs.com/vin-c/archive/2019/12/15/12043961.html
-Advertisement-
Play Games

在之前的文章中(地址: "https://www.vinanysoft.com/c sharp basics/introducing/" ),以 HelloWorld 程式為基礎,介紹 C 語言、它的結構、基本語法以及如何編寫最簡單的程式有了初步理解。 接下來介紹基本的 C 類型,繼續鞏固 C 的基 ...


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

接下來介紹基本的 C# 類型,繼續鞏固 C# 的基礎知識。本系列文章到目前為止只用過少量的內置數據類型,而且只是一筆帶過。在 C# 中有大量的類型,而且可以通過合併類型來創建新類型。

但 C# 有幾種類型非常簡單,是其他所有類型的基礎,它們稱為預定義類型(predefined type)或基元類型( primitive type)。

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

所有預定義類型的名稱都由全小寫的字母組成。預定義的簡單類型包括以下 3 種。

  • 11 種數值類型。
    • 不同長度的有符號和無符號整數類型。
    • 用於科學計算的二進位浮點類型 floatdouble
    • 一種用於金融計算的十進位高精度浮點類型 decimal。與 floatdouble 不同,decimal 類型可以準確地表示分數。decimal 類型常用於貨幣的計算。
  • 一種 Unicode 字元類型 char
  • 一種布爾類型 boolbool 類型表示布爾值並且必須為 truefalse

非簡單類型如下:

  • 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(基類庫)中的類型名稱。

由於基元數據類型是其他類型的基礎,所以 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# 語言的基元類型包括八種整數類型、兩種用於科學計算的二進位浮點類型、一種用於金融計算的十進位浮點類型。浮點型存在舍入誤差,使用的時候要註意。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一種可以實現" 先進先出 "的存儲結構 分類: 1. 鏈式隊列:用鏈表實現 2. 靜態隊列:用數組實現,靜態隊列通常都必須是 迴圈隊列 迴圈隊列的講解: 1. 靜態隊列為什麼是迴圈隊列 減少對記憶體的浪費 2. 迴圈隊列需要幾個參數來確定 兩個參數, frant 、rear 但這2個參數不同場合有不同 ...
  • 大家好,我是Dotnet9小編,一個從事dotnet開發8年+的程式員。我最近在寫dotnet分享文章,希望能讓更多人看到dotnet的發展,瞭解更多dotnet技術,幫助dotnet程式員應用dotnet技術更好的運用於工作和學習中去。 文章閱讀導航 一、寫在前面的話 二、HZHControls介 ...
  • 題外話 筆者有個習慣,就是在接觸新的東西時,一定要先搞清楚新事物的基本概念和背景,對之有個相對全面的瞭解之後再開始進入實際的編碼,這樣做最主要的原因是儘量避免由於對新事物的認知誤區導致更大的缺陷,Bug 一旦發生,將比普通的代碼缺陷帶來更加昂貴的修複成本。 相信有了前一篇和園子里其他同學的文章,你已 ...
  • 背景 筆者所在的公司正在進行微服務改造,這其中服務治理組件是必不可少的組件之一,在一番討論之後,最終決定放棄 Zookeeper 而採用 Consul 作為服務治理框架基礎組件。主要原因是 Consul 自帶健康檢查,通過該功能可以比較方便的監控應用的運行狀態,從而更好的運維整個系統。但在實際實施過 ...
  • 最近讀了一些文章,總結一下: 在1999年,當時微軟的windows系統運行的所有的應用程式都是有組件對象模型為根本基礎開發的,用VB來處理數據訪問和複雜的用戶界面,缺點是不能使用函數指針,因為當時的開發環境開發起來很不輕鬆,所有.NET的出現,變得更好了。 .NET 平臺由一個類框架和一個CLR的 ...
  • 數據的類型定義了存儲數據需要的記憶體大小及組成該類型的數據成員。類型還決定了對象在記憶體中的存儲位置——棧或堆。 類型被分為兩種:值類型和引用類型,這兩種類型的對象在記憶體中的存儲方式不同。 值類型只需要一段單獨的記憶體,用於存儲實際的數據。 引用類型需要兩段記憶體。 第一段存儲實際的數據,它總是位於堆中。 ...
  • 程式運行時,它的數據必須存儲在記憶體中。一個數據項需要多大的記憶體、存儲在記憶體中的什麼位置、以及如何存儲都依賴於該數據項的類型。 運行中的程式使用兩個記憶體區域來存儲數據:棧和堆。 棧 棧是一個記憶體數組,是一個 LIFO (Last In First Out,後進先出)的數據結構。棧存儲幾種類型的數據: ...
  • 上一篇(地址: "https://www.vinanysoft.com/c sharp basics/data types/fundamental numeric types/" )只介紹了基本數值類型,本篇將介紹其他的一些類型: 、`char string`。 布爾類型( ) 關鍵字是 的別名。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...