C#實(shí)現(xiàn)十六進(jìn)制與十進(jìn)制相互轉(zhuǎn)換以及及不同進(jìn)制表示
前言
在程序中,十六進(jìn)制的表示形式通常為字符串;而十進(jìn)制則為數(shù)字整型(本質(zhì)的內(nèi)存存儲(chǔ)都是01二進(jìn)制)。數(shù)字的進(jìn)制表示一般使用的不多,通常最大的需求是進(jìn)制之間的相互轉(zhuǎn)換。C#中提供了內(nèi)置的轉(zhuǎn)換方法,同時(shí),我們也可以依據(jù)不同進(jìn)制之間的規(guī)則自己實(shí)現(xiàn)進(jìn)制之間的轉(zhuǎn)換。
C#中數(shù)字的進(jìn)制表示形式
對(duì)于進(jìn)制的表示,編程語言基本上都提供了特殊前綴表示不同進(jìn)制的數(shù)字,一般0x
/0X
表示16進(jìn)制、0o
/0O
表示8進(jìn)制、0b
/0B
表示2進(jìn)制,十進(jìn)制數(shù)字則沒有特殊前綴,直接輸入數(shù)字即可。
C#中沒有對(duì)8進(jìn)制數(shù)字的直接表示形式。對(duì)于這個(gè)幾乎用不到的歷史遺留的進(jìn)制,編程中很少會(huì)使用。通常比較常用的是2進(jìn)制和16進(jìn)制。
比如,下面舉例的不同進(jìn)制的數(shù)字表示形式:
// 16進(jìn)制表示 var hexadecimal = 0xaf2; Console.WriteLine(hexadecimal); // 2802 // 2進(jìn)制表示 var binary = 0b1011110000; Console.WriteLine(binary); // 752 // 10進(jìn)制 var decimal_ = 910; Console.WriteLine(decimal_); // 910
十六進(jìn)制轉(zhuǎn)十進(jìn)制
十六進(jìn)制到十進(jìn)制的轉(zhuǎn)換可以通過下面的步驟實(shí)現(xiàn):
- 從十六進(jìn)制數(shù)字的最右側(cè)(個(gè)位)開始獲取每一位的數(shù)字
- 獲取的數(shù)字乘以16^n,n從0開始
- 將相乘后的結(jié)果相加到最終值
- 以等值的十進(jìn)制對(duì)應(yīng)十六進(jìn)制,比如 A或a作為10,B或b作為11
代碼實(shí)現(xiàn)十六進(jìn)制轉(zhuǎn)十進(jìn)制
下面的代碼使用上面介紹的算法,實(shí)現(xiàn)將十六進(jìn)制字符串轉(zhuǎn)換為十進(jìn)制數(shù)字,通過遍歷十六進(jìn)制的字符得到最后的值。
使用正則驗(yàn)證傳入的是否是合格的16進(jìn)制字符串。
/// <summary> /// Hex十六進(jìn)制數(shù)字轉(zhuǎn)十進(jìn)制 /// </summary> /// <param name="hex"></param> /// <returns></returns> public static int HexToDecimal(string hex) { if (!Regex.Match(hex, "^[0-9A-F]$", RegexOptions.IgnoreCase).Success) { throw new Exception("不是十六進(jìn)制數(shù)字"); } var decimalValue = 0; var hexUp = hex.ToUpper(); // 從最后一位到第一位循環(huán)獲取每位的值,并乘以基數(shù)的n-1次方 for (int i = hexUp.Length-1; i >= 0; i--) { int currV = 0; switch (hexUp[i]) { case 'A': currV = 10; break; case 'B': currV = 11; break; case 'C': currV = 12; break; case 'D': currV = 13; break; case 'E': currV = 14; break; case 'F': currV = 15; break; case '0': currV = 0; break; case '1': currV = 1; break; case '2': currV = 2; break; case '3': currV = 3; break; case '4': currV = 4; break; case '5': currV = 5; break; case '6': currV = 6; break; case '7': currV = 7; break; case '8': currV = 8; break; case '9': currV = 9; break; default: break; } for (int n = 0; n < hexUp.Length - 1 -i; n++) { currV *= 16; } decimalValue += currV; } return decimalValue; }
基本邏輯和介紹的一致。
參考文章中給出了更加清晰的邏輯處理,和介紹的處理算法完全邏輯一致,尤其Multiplier的使用,比較巧妙,推薦。代碼如下:
/// <summary> /// 另一種16進(jìn)制轉(zhuǎn)10進(jìn)制的處理方式,Multiplier參與*16的循環(huán)很巧妙,對(duì)Multiplier的處理很推薦,邏輯統(tǒng)一 /// </summary> /// <param name="HexaDecimalString"></param> /// <returns></returns> public static int HexaToDecimal(string HexaDecimalString) { int Decimal = 0; int Multiplier = 1; for (int i = HexaDecimalString.Length - 1; i >= 0; i--) { Decimal += HexaToDecimal(HexaDecimalString[i]) * Multiplier; Multiplier *= 16; } return Decimal; } static int HexaToDecimal(char c) { switch (c) { case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4; case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9; case 'A': case 'a': return 10; case 'B': case 'b': return 11; case 'C': case 'c': return 12; case 'D': case 'd': return 13; case 'E': case 'e': return 14; case 'F': case 'f': return 15; } return -1; }
C#內(nèi)置方法16轉(zhuǎn)10進(jìn)制
Convert.ToInt32()
Convert.ToInt32
的第二個(gè)參數(shù)可以指定進(jìn)制數(shù),從而轉(zhuǎn)為32位的10進(jìn)制int整型。
Convert.ToInt32(hexStr,16)
同理,可以根據(jù)需要,將2進(jìn)制、8進(jìn)制的字符串轉(zhuǎn)換為10進(jìn)制的int類型。
int.Parse()和int.TryParse
int.Parse(hexStr,System.Globalization.NumberStyles.HexNumber)
第二個(gè)參數(shù)指定當(dāng)前為HexNumber數(shù)字,實(shí)現(xiàn)16轉(zhuǎn)10進(jìn)制。
int.TryParse
同理。
十進(jìn)制轉(zhuǎn)十六進(jìn)制
代碼實(shí)現(xiàn)十進(jìn)制轉(zhuǎn)十六進(jìn)制
實(shí)現(xiàn)步驟對(duì)應(yīng)上面16轉(zhuǎn)10進(jìn)制的過程,代碼如下:
/// <summary> /// 十進(jìn)制數(shù)字轉(zhuǎn)十六進(jìn)制 /// </summary> /// <param name="dec">十進(jìn)制數(shù)字</param> /// <param name="lower">16進(jìn)制結(jié)果是否為小寫,默認(rèn)false</param> /// <returns></returns> public static string DecimalToHex(int dec, bool lower = false) { var hexBuilder = new StringBuilder(); while (dec != 0) { var currV = dec % 16; char currHex; switch (currV) { case 0: currHex = '0'; break; case 1: currHex = '1'; break; case 2: currHex = '2'; break; case 3: currHex = '3'; break; case 4: currHex = '4'; break; case 5: currHex = '5'; break; case 6: currHex = '6'; break; case 7: currHex = '7'; break; case 8: currHex = '8'; break; case 9: currHex = '9'; break; case 10: currHex = 'A'; break; case 11: currHex = 'B'; break; case 12: currHex = 'C'; break; case 13: currHex = 'D'; break; case 14: currHex = 'E'; break; case 15: currHex = 'F'; break; default: currHex = '-'; break; } // 從個(gè)位即最右邊開始往前獲取16進(jìn)制值 hexBuilder.Insert(0, currHex); dec /= 16; } return lower ? hexBuilder.ToString().ToLower() : hexBuilder.ToString(); }
C#內(nèi)置方法10轉(zhuǎn)16進(jìn)制
Convert.ToString() 轉(zhuǎn)換數(shù)字為不同的進(jìn)制
Convert.ToString(dec, 16)
的第二個(gè)參數(shù)可以指定要換為的字符串的進(jìn)制數(shù)。
它轉(zhuǎn)換的結(jié)構(gòu)是小寫表示的16進(jìn)制,且個(gè)位數(shù)時(shí)為單數(shù),即如果是5,其結(jié)果為"5",如果是F,其結(jié)果為"F"。
.ToString()方法
dec.ToString("X2")
或 dec.ToString("X")
將整型轉(zhuǎn)為16進(jìn)制。
- X2表示個(gè)位是兩位的16進(jìn)制,比如5表示為"05",F(xiàn)表示為"0F"。在用
Hex
格式表示二進(jìn)制時(shí)很常用,2位16進(jìn)制FF
正好表示8位一個(gè)字節(jié)。 - X表示16進(jìn)制格式。
dec.ToString("x2")
或 dec.ToString("x")
中使用小寫x,則轉(zhuǎn)換為對(duì)應(yīng)的小寫的16進(jìn)制字符串,比如15轉(zhuǎn)換為"f"或"0f"?!?code>X對(duì)應(yīng)為大寫】。
string.Format()
與.ToString()
方法同樣的格式化要求。
string.Format("{0:X2}", dec)
或 string.Format("{0:X}",dec)
將整型轉(zhuǎn)為16進(jìn)制。
Convert.ToString()實(shí)現(xiàn)將數(shù)字轉(zhuǎn)換為特定進(jìn)制的字符串
將decimal_2
分別轉(zhuǎn)換為16進(jìn)制、8進(jìn)制、2進(jìn)制的字符串
var decimal_2 = 15; Console.WriteLine($"{decimal_2}的16進(jìn)制表示{Convert.ToString(decimal_2, 16)}"); Console.WriteLine($"{decimal_2}的8進(jìn)制表示{Convert.ToString(decimal_2, 8)}"); Console.WriteLine($"{decimal_2}的2進(jìn)制表示{Convert.ToString(decimal_2, 2)}"); // 15的16進(jìn)制表示f // 15的8進(jìn)制表示17 // 15的2進(jìn)制表示1111
實(shí)現(xiàn)進(jìn)制轉(zhuǎn)換的Winform程序
新建一個(gè)簡(jiǎn)單的Winform項(xiàng)目HEXAndDECInterConvert
,窗體添加從16進(jìn)制的TextBox輸入框轉(zhuǎn)為10進(jìn)制TextBox輸出框、從10進(jìn)制的TextBox輸入框轉(zhuǎn)為16進(jìn)制TextBox輸出框。
在輸入框的TextChanged中,分別完成進(jìn)制的轉(zhuǎn)換
hexFromTxt.TextChanged += HexFromTxt_TextChanged; decFromTxt.TextChanged += DecFromTxt_TextChanged; // ....... private void DecFromTxt_TextChanged(object sender, EventArgs e) { var decStr = decFromTxt.Text.Trim(); if (!int.TryParse(decStr, out int dec)) { // 不是數(shù)字或者不能正確的轉(zhuǎn)為數(shù)字則清空 decFromTxt.Text =hexToTxt.Text = ""; return; } var hex1 = HexDecConvert.DecimalToHex(dec); hexToTxt.Text = hex1; var tmp = Convert.ToString(dec, 16); // ab..f等為小寫表示 // X2表示兩位的16進(jìn)制,比如5表示為05 // X表示16進(jìn)制格式 var tmp2 = dec.ToString("X2"); var tmp3 = string.Format("{0:X2}", dec); } private void HexFromTxt_TextChanged(object sender, EventArgs e) { var hex = hexFromTxt.Text.Trim(); var dec1 = HexDecConvert.HexToDecimal(hex); var dec2 = HexDecConvert.HexaToDecimal(hex); decToTxt.Text = dec1.ToString(); decToTxt2.Text = dec2.ToString(); }
效果如下:
參考
4 ways in C# to convert a hexadecimal value to Decimal
總結(jié)
到此這篇關(guān)于C#實(shí)現(xiàn)十六進(jìn)制與十進(jìn)制相互轉(zhuǎn)換以及及不同進(jìn)制表示的文章就介紹到這了,更多相關(guān)C#十六進(jìn)制與十進(jìn)制相互轉(zhuǎn)換內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#與SQL連接:GridView控件對(duì)數(shù)據(jù)庫的操作
GridView控件操作方面的知識(shí),需要的朋友可以參考一下2013-02-02C#實(shí)現(xiàn)兩個(gè)richtextbox控件滾動(dòng)條同步滾動(dòng)的簡(jiǎn)單方法
這篇文章主要給大家介紹了C#實(shí)現(xiàn)兩個(gè)richtextbox控件滾動(dòng)條同步滾動(dòng)的簡(jiǎn)單方法,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-05-05C#實(shí)現(xiàn)凍結(jié)Excel窗口以鎖定行列或解除凍結(jié)
在處理大型Excel工作簿時(shí),有時(shí)候我們需要在工作表中凍結(jié)窗格,這樣可以在滾動(dòng)查看數(shù)據(jù)的同時(shí)保持某些行或列固定不動(dòng),下面我們就來看看如何使用C#實(shí)現(xiàn)凍結(jié)Excel窗口吧2024-04-04C# 總結(jié)QueueUserWorkItem傳參幾種方式案例詳解
這篇文章主要介紹了C# 總結(jié)QueueUserWorkItem傳參幾種方式案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-09-09