本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《 阿里云开发者社区用户服务协议 》和 《 阿里云开发者社区知识产权保护指引 》。如果您发现本社区中有涉嫌抄袭的内容,填写 侵权投诉表单 进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

在程序中,十六进制的表示形式通常为字符串;而十进制则为数字整型(本质的内存存储都是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