国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

基本類型間的類型轉換(數值型)

2019-11-14 16:27:27
字體:
來源:轉載
供稿:網友

今天一打開博客,看到左上角的園齡5年,目光有些恍然,昔日作為學生上課的情景、已經慢慢變的模糊。是啊、畢業已經3年有余,時光不再來...

 

一、原碼和補碼

在步入正文說類型轉換之前,先做一個小鋪墊,了解一下原碼和補碼。

[注:由于同一個數字在用不同位數的原碼或補碼表示時、結果不同,所以如無特殊說明、該小節下出現的所有原碼和補碼均為8位]

 

原碼(true form)是一種計算機中對數字的二進制定點表示方法。原碼表示法在數值前面增加了一位符號位(即最高位為符號位):

正數該位為0,負數該位為1(0有兩種表示:+0和-0),其余位表示數值的大小。

1、原碼優點:簡單直觀;例如,我們用8位二進制表示一個數,+11的原碼為00001011,-11的原碼就是10001011

2、原碼缺點:原碼不能直接參加運算,可能會出錯。例如數學上,1+(-1)=0,而在二進制中 00000001+10000001=

10000010,換算成十進制為-2。顯然出錯了。

 

補碼(two's complement) 在計算機系統中,數值一律用補碼來表示和存儲。補碼是可以直接參與運算的。原碼和補碼表示方法均有

符號位和數值位兩部分,符號位都是用0表示“正”,用1表示“負”,而數值位表示方法不相。

1、知原碼求補碼

求正數的補碼:正整數的補碼與原碼相同。

【例】+9的補碼是00001001。

求負數的補碼:求負整數的補碼, 在原碼的基礎之上 符號位不變,數值位各位取反,最后整個數加1。

【例】求-5的補碼。
-5的原碼(10000101)→符號位不變(10000101)→數值位取反(11111010)→加1(11111011)
所以-5的補碼是11111011。
【例】數0的補碼表示是唯一的。
[+0]補=[+0]原=00000000
[-0]補=11111111+1=00000000


2、知補碼求原碼

已知一個數的補碼,求原碼的操作其實就是對該補碼再求補碼:
1)如果補碼的符號位為“0”,表示是一個正數,其原碼就是補碼。
2)如果補碼的符號位為“1”,表示是一個負數,那么求給定的這個補碼的補碼就是要求的原碼。
【例】已知一個補碼為11111001,則原碼是10000111(-7)。
因為符號位為“1”,表示是一個負數,所以該位不變,仍為“1”。
其余七位1111001取反后為0000110;
再加1,所以是10000111。

3、補碼的運算

 補碼:http://baike.baidu.com/view/377340.htm

 

二、整形間的類型轉換

    class PRogram    {        static void Main(string[] args)        {            Console.WriteLine("注:該demo中的所有例子均為整形間的無精度損失的類型轉換,為了方便閱讀打印的是字節而不是位");            Console.WriteLine("1、補位式轉化");            Console.WriteLine("/r/n###32位有符號 轉 64位無符號###");            Console.WriteLine("/r/n例1");            int i = int.MaxValue;            ulong ul = (ulong)i;            Print(BitConverter.GetBytes(i), i.ToString(), "轉化前");            Print(BitConverter.GetBytes(ul), ul.ToString(), "轉化后");            Console.WriteLine("/r/n例2");            i = int.MinValue;            ul = (ulong)i;            Print(BitConverter.GetBytes(i), i.ToString(), "轉化前");            Print(BitConverter.GetBytes(ul), ul.ToString(), "轉化后");            Console.WriteLine("/r/n###32位有符號 轉 64位有符號###");            Console.WriteLine("/r/n例3");            i = int.MinValue;            long l = (long)i;            Print(BitConverter.GetBytes(i), i.ToString(), "轉化前");            Print(BitConverter.GetBytes(l), l.ToString(), "轉化后");            Console.WriteLine("/r/n###32位無符號 轉 64位有符號###");            Console.WriteLine("/r/n例4");            uint ui = uint.MaxValue;            l = (long)ui;            Print(BitConverter.GetBytes(ui), ui.ToString(), "轉化前");            Print(BitConverter.GetBytes(l), l.ToString(), "轉化后");            Console.WriteLine("2、截位式轉化");            Console.WriteLine("/r/n###64位有符號 轉 32位有符號###");            Console.WriteLine("/r/n例5");            l = long.MaxValue;            i = (int)l;            Print(BitConverter.GetBytes(l), l.ToString(), "轉化前");            Print(BitConverter.GetBytes(i), i.ToString(), "轉化后");            Console.WriteLine("/r/n###64位無符號 轉 32位有符號###");            Console.WriteLine("/r/n例6");            ul = ulong.MaxValue;            i = (int)ul;            Print(BitConverter.GetBytes(ul), ul.ToString(), "轉化前");            Print(BitConverter.GetBytes(i), i.ToString(), "轉化后");            Console.WriteLine("3、轉換符號位式轉化");            Console.WriteLine("/r/n###32位無符號 轉 32位有符號###");            Console.WriteLine("/r/n例7");            ui = uint.MaxValue;            i = (int)ui;            Print(BitConverter.GetBytes(ui), ui.ToString(), "轉化前");            Print(BitConverter.GetBytes(i), i.ToString(), "轉化后");            Console.WriteLine("/r/n###32位有符號 轉 32位無符號###");            Console.WriteLine("/r/n例8");            i = int.MinValue;            ui = (uint)i;            Print(BitConverter.GetBytes(i), i.ToString(), "轉化前");            Print(BitConverter.GetBytes(ui), ui.ToString(), "轉化后");            Console.Read();        }        private static void Print(byte[] buffer, string result, string tag = "")        {            Console.WriteLine(tag);            Console.WriteLine("數值:" + result);            Console.Write("字節數組(補碼):");            foreach (byte b in buffer)            {                Console.Write(string.Format("{0},", b.ToString()));            }            Console.WriteLine("");        }    }

  

      

 根據上述的8個例子可以得出如下結果:

 1、補位式轉化、即少位數據類型向多位數據類型轉化 (例1、例2、例3、例4)

  所補位與操作數的數據類型有關,與目標數據類型無關。

  如果操作數是有符號的數據類型,所補位一律為操作數的符號位,如果操作數是無符號的數據類型,所補位一律為0。

 2、截位式轉化、即多位數據類型向少位數據類型轉化 (例5、例6)

  該轉換方式就是簡單的截取有效數位(即丟棄高位),和操作數的類型無關。

 3、轉換符號位式轉化、即相同位數有無符號數據類型間的轉化(例7、例8)

   發生該類型轉化時,只是最高位的意義發生了變化,進而可能導致結果改變。

 

三、整形與浮點型間的類型轉換

有了上面的基礎、再理解整形與浮點型的轉換就容易多了。

由整形向浮點型轉換的時候,如果整形數據的值過大或過小,就可能損失一些最低的有效位,造成精度損失(float的精度只有7位,double15~16位)。

 

四、參考資料:

原碼:http://baike.baidu.com/view/60480.htm

補碼:http://baike.baidu.com/view/377340.htm

 

最后祝園友們,中秋快樂(雖然晚了,但是誠意還在吧)。

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 五大连池市| 大厂| 洞口县| 隆回县| 阳朔县| 海阳市| 丹巴县| 东阳市| 林州市| 江源县| 湘潭县| 乌兰县| 社会| 福州市| 黑水县| 海原县| 吉木乃县| 吴旗县| 镇巴县| 永城市| 射阳县| 玛曲县| 毕节市| 沅江市| 日土县| 调兵山市| 仁布县| 夏河县| 抚顺县| 遂昌县| 宜阳县| 靖安县| 且末县| 安康市| 云阳县| 乳山市| 平南县| 高阳县| 大安市| 锡林郭勒盟| 石楼县|