C#快速入門教程(9)——浮點數、Decimal型別和數值型別轉換

曹化宇發表於2018-09-16

相對於整數,浮點數和Decimal型別的資料就沒那麼複雜了,本課,我們主要了解float、double和decimal資料型別,並討論整數、浮點數和Decimal混合運算時應該注意的一些情況。

我們知道,計算機處理資料的範圍是有限的,整數包含了8位、16位、32位和64位資料型別,而浮點數則包含了單精度和雙精度兩種,它們對於精度的要求是不同的。float型別對應於System.Single結構型別,用於處理單精度浮點數,保留7位精度;double型別對應於System.Double結構型別,用於處理雙精度浮點數,保留15位精度。此外,decimal型別對應於System.Decimal結構型別,用於對精度要求較高的資料處理。下面看一個簡單的浮點數和Decimal型別的除法運算示例。

static void Main(string[] args)
{
    Console.WriteLine(5f / 3f);
    Console.WriteLine(5d / 3d);
    Console.WriteLine(5m / 3m);
}

程式碼執行結果如下圖所示。

enter image description here

從運算結果中可以看到float、double和decimal精度上的不同,實際開發時,可以根據計算任務對資料精度的要求選擇使用不同的浮點數或decimal型別。

我們已經接觸到整數、浮點數和decimal型別,現在的問題是,如果這些型別的資料混合在一起進行算術運算會怎麼樣呢?這裡有一個簡單的基本原則,即,當兩個不同型別的資料進行運算,會先將取值範圍小的資料型別轉換為取值範圍大的型別,然後進行運算。

下面的程式碼,我們來觀察運算結果的型別。

static void Main(string[] args)
{
    Console.WriteLine((5 / 3).GetType().ToString());
    Console.WriteLine((5 / 3L).GetType().ToString());
    Console.WriteLine((5F / 3).GetType().ToString());
    Console.WriteLine((5L / 3D).GetType().ToString());
    Console.WriteLine((5F / 3D).GetType().ToString());
    Console.WriteLine((5 / 3M).GetType().ToString());
}

程式碼執行結果如下圖所示。

enter image description here

我們可以看到這裡給出了六種運算結合,分別是: - int與int型別資料運算,也就是相同型別的資料運算,其結果依然是此型別。 - int與long型別資料運算,結果為long型別(System.Int64)。 - float與int型別資料運算,結果為float型別(System.Single)。 - long與double型別資料運算,結果為double型別(System.Double)。 - float與double型別資料運算,結果為double型別(System.Double)。 - int與decimal型別資料運算,結果為decimal型別(System.Decimal)。

對於常用的資料型別,自動轉換的優先順序從大到小分別decimal、double、float、long、int、short;請注意,這裡主要包含了處理有符號資料的型別。

前面的示例中,資料型別可以自動完成轉換,稱為“隱式轉換”;相對應的,我們還可以對資料進行強制轉換;但應注意,在將取值大型別的資料向下轉換時,有可能造成資料精度的降低,甚至是得到錯誤的資料。比如,一個大杯和一個小杯,將小杯的水倒入大杯不會有問題,而將大杯的水倒入小杯,是否能成功,還要看大杯中原來有多少水。

強制轉換時,需要在待轉換資料使用一對圓括號指定目標型別,如下面的程式碼。

static void Main(string[] args)
{
    long x = 99L;
    int y = (int)x;
    Console.WriteLine(y.GetType().ToString());
}

毫無疑問,執行結果會顯示System.Int32。程式碼中,首先定義一個long型別的變數x,然後,將其資料轉換為int型別並賦值到變數y中,最後顯示y的資料型別為System.Int32,即int型別。

接下來,我們做個測試,如下面的程式碼,我將x的值設定為long.MaxValue。

static void Main(string[] args)
{
    long x = long.MaxValue;
    int y = (int)x;
    Console.WriteLine(y);
}

程式碼中,我們將x設定為long型別的最大值,然後強制轉換為int型別,想一想結果也不可能靠譜。執行結果會顯示-1,那麼它是怎麼來的呢?

我們知道,long型別是64位有符號整數,那麼它的最大值的二進位制最高位會是0,其他63位是1;而強制轉換為int型別後,會進行位截斷操作,即將高位的32位捨去,只保留後32位,即32個1元件的二進位制數。而int也是有符號型別,所以,當最高位是1時表示這是一個負數,而後面的31個1則是資料絕對值的補碼,通過反向計算可以得到30個0和最低位一個1組成的二制數,也就是十進位制數1;所以,最終顯示的結果是-1。

本課,我們討論了整數、浮點數、Decimal型別之間可能的轉換操作,包括隱式轉換和強制轉換;另外,還演示了將取值較大整數轉換為取值較小整數時會出現什麼情況。大家在開發時,要注意資料型別轉換時的一些特殊情況,並需要特別小心可能的資料丟失問題,要深入使用者資料處理業務,瞭解資料所需要的精度,合理選擇使用資料型別。

這裡只是C#中簡單的資料轉換操作,在整個軟體系統中,資料的轉換和傳遞是一個更大的工程,在後續的學習中,我們還會有更多討論。

CHY軟體小屋原創作品!

相關文章