C#实现十六进制与十进制相互转换以及及不同进制表示
前言
在程序中,十六进制的表示形式通常为字符串;而十进制则为数字整型(本质的内存存储都是01二进制)。数字的进制表示一般使用的不多,通常最大的需求是进制之间的相互转换。C#中提供了内置的转换方法,同时,我们也可以依据不同进制之间的规则自己实现进制之间的转换。
C#中数字的进制表示形式
对于进制的表示,编程语言基本上都提供了特殊前缀表示不同进制的数字,一般0x
/0X
表示16进制、0o
/0O
表示8进制、0b
/0B
表示2进制,十进制数字则没有特殊前缀,直接输入数字即可。
C#中没有对8进制数字的直接表示形式。对于这个几乎用不到的历史遗留的进制,编程中很少会使用。通常比较常用的是2进制和16进制。
比如,下面举例的不同进制的数字表示形式:
// 16进制表示
var hexadecimal = 0xaf2;
Console.WriteLine(hexadecimal); // 2802
// 2进制表示
var binary = 0b1011110000;
Console.WriteLine(binary); // 752
// 10进制
var decimal_ = 910;
Console.WriteLine(decimal_); // 910
十六进制转十进制
十六进制到十进制的转换可以通过下面的步骤实现:
- 从十六进制数字的最右侧(个位)开始获取每一位的数字
- 获取的数字乘以16^n,n从0开始
- 将相乘后的结果相加到最终值
- 以等值的十进制对应十六进制,比如 A或a作为10,B或b作为11
代码实现十六进制转十进制
下面的代码使用上面介绍的算法,实现将十六进制字符串转换为十进制数字,通过遍历十六进制的字符得到最后的值。
使用正则验证传入的是否是合格的16进制字符串。
/// <summary>
/// Hex十六进制数字转十进制
/// </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("不是十六进制数字");
}
var decimalValue = 0;
var hexUp = hex.ToUpper();
// 从最后一位到第一位循环获取每位的值,并乘以基数的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进制转10进制的处理方式,Multiplier参与*16的循环很巧妙,对Multiplier的处理很推荐,逻辑统一
/// </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#内置方法16转10进制
Convert.ToInt32()
Convert.ToInt32
的第二个参数可以指定进制数,从而转为32位的10进制int整型。
Convert.ToInt32(hexStr,16)
同理,可以根据需要,将2进制、8进制的字符串转换为10进制的int类型。
int.Parse()和int.TryParse
int.Parse(hexStr,System.Globalization.NumberStyles.HexNumber)
第二个参数指定当前为HexNumber数字,实现16转10进制。
int.TryParse
同理。
十进制转十六进制
代码实现十进制转十六进制
实现步骤对应上面16转10进制的过程,代码如下:
/// <summary>
/// 十进制数字转十六进制
/// </summary>
/// <param name="dec">十进制数字</param>
/// <param name="lower">16进制结果是否为小写,默认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;
}
// 从个位即最右边开始往前获取16进制值
hexBuilder.Insert(0, currHex);
dec /= 16;
}
return lower ? hexBuilder.ToString().ToLower() : hexBuilder.ToString();
}
C#内置方法10转16进制
Convert.ToString() 转换数字为不同的进制
Convert.ToString(dec, 16)
的第二个参数可以指定要换为的字符串的进制数。
它转换的结构是小写表示的16进制,且个位数时为单数,即如果是5,其结果为"5",如果是F,其结果为"F"。
.ToString()方法
dec.ToString("X2")
或 dec.ToString("X")
将整型转为16进制。
- X2表示个位是两位的16进制,比如5表示为"05",F表示为"0F"。在用
Hex
格式表示二进制时很常用,2位16进制FF
正好表示8位一个字节。 - X表示16进制格式。
dec.ToString("x2")
或 dec.ToString("x")
中使用小写x,则转换为对应的小写的16进制字符串,比如15转换为"f"或"0f"。【X
对应为大写】。
string.Format()
与.ToString()
方法同样的格式化要求。
string.Format("{0:X2}", dec)
或 string.Format("{0:X}",dec)
将整型转为16进制。
Convert.ToString()实现将数字转换为特定进制的字符串
将decimal_2
分别转换为16进制、8进制、2进制的字符串
var decimal_2 = 15;
Console.WriteLine($"{decimal_2}的16进制表示{Convert.ToString(decimal_2, 16)}");
Console.WriteLine($"{decimal_2}的8进制表示{Convert.ToString(decimal_2, 8)}");
Console.WriteLine($"{decimal_2}的2进制表示{Convert.ToString(decimal_2, 2)}");
// 15的16进制表示f
// 15的8进制表示17
// 15的2进制表示1111
实现进制转换的Winform程序
新建一个简单的Winform项目HEXAndDECInterConvert
,窗体添加从16进制的TextBox输入框转为10进制TextBox输出框、从10进制的TextBox输入框转为16进制TextBox输出框。
在输入框的TextChanged中,分别完成进制的转换
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))
{
// 不是数字或者不能正确的转为数字则清空
decFromTxt.Text =hexToTxt.Text = "";
return;
}
var hex1 = HexDecConvert.DecimalToHex(dec);
hexToTxt.Text = hex1;
var tmp = Convert.ToString(dec, 16); // ab..f等为小写表示
// X2表示两位的16进制,比如5表示为05
// X表示16进制格式
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
总结
到此这篇关于C#实现十六进制与十进制相互转换以及及不同进制表示的文章就介绍到这了,更多相关C#十六进制与十进制相互转换内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
相关文章