C#实现2~36进制转换的完整代码

 更新时间:2025年10月12日 10:21:30   作者:liulilittle  
进制转换是计算机科学中的基础技能,进制转换的本质是将数字从一种表示系统转换为另一种表示系统,下面我们就来看看如何使用C#实现2~36进制的相互转换吧

1. 引言:进制转换的重要性

进制转换是计算机科学中的基础技能,在编程开发、网络通信、数据加密等领域有着广泛应用。虽然C#提供了Convert类等内置转换方法,但自定义进制转换工具类能提供更大的灵活性,特别是支持2~36进制的任意转换。本文将深入解析一个完整的进制转换工具类,逐行分析代码实现,并通过流程图直观展示算法原理。

进制转换的本质是将数字从一种表示系统转换为另一种表示系统。例如二进制使用0和1两个数字,十六进制使用0-9和A-F共16个字符。而36进制则使用0-9和A-Z所有字符,能够更紧凑地表示大数字。

2. 进制转换工具类完整实现

以下是一个完整的C#进制转换工具类,支持2~36进制之间的相互转换:

using System;

/// <summary>
/// 进制转换工具类,支持2~36进制之间的转换
/// </summary>
public static class RadixConverter
{
    // 字符集定义:0-9和A-Z分别表示0~35
    [DebuggerBrowsable(DebuggerBrowsableState.Never)]
    private static readonly string _keys = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    
    /// <summary>
    /// 将字符串转换为double类型
    /// </summary>
    /// <param name="v">要转换的字符串</param>
    /// <param name="radix">进制基数(2-36)</param>
    /// <returns>转换后的double值</returns>
    public static double ToDouble(string v, int radix) => BitConverter.Int64BitsToDouble(ToInt64(v, radix));
    
    /// <summary>
    /// 将字符串转换为long类型
    /// </summary>
    public static long ToInt64(string v, int radix) => (long)ToUInt64(v, radix);
    
    /// <summary>
    /// 核心方法:将字符串转换为ulong(支持2~36进制)
    /// </summary>
    public static ulong ToUInt64(string v, int radix)
    {
        // 处理空字符串或null值
        if (string.IsNullOrEmpty(v))
        {
            return 0;
        }
        
        // 进制参数验证与修正
        if (radix < 2)
        {
            radix = 10;  // 默认使用十进制
        }
        else if (radix > _keys.Length)
        {
            radix = _keys.Length;  // 最大不能超过字符集长度
        }
        
        ulong result = 0;     // 存储转换结果
        ulong baseValue = (ulong)radix;  // 进制基数
        ulong weight = 0;     // 当前位的权重(基数的幂次)
        
        // 从字符串末尾向前遍历(从低位到高位)
        for (int i = v.Length - 1; i > -1; i--)
        {
            char ch = v[i];
            ulong digitValue;
            
            // 字符到数字的映射转换
            if (ch >= '0' && ch <= '9')
            {
                digitValue = (ulong)(ch - '0');  // 数字0-9直接转换
            }
            else if (ch >= 'A' && ch <= 'Z')
            {
                digitValue = 10 + (ulong)(ch - 'A');  // 大写字母A-Z对应10-35
            }
            else if (ch >= 'a' && ch <= 'z')
            {
                digitValue = 10 + (ulong)(ch - 'a');  // 小写字母a-z对应10-35
            }
            else
            {
                return 0;  // 非法字符返回0
            }
            
            // 检查数字是否有效(不能大于等于基数)
            if (digitValue >= baseValue)
            {
                return 0;
            }
            
            // 计算当前位的贡献值
            if (i == v.Length - 1)  // 最低位(权重为1)
            {
                result += digitValue;
                weight = baseValue;  // 初始化权重
            }
            else  // 高位:权重递增
            {
                result += digitValue * weight;
                weight = weight * baseValue;  // 权重乘以基数
            }
        }
        return result;
    }
    
    // 以下为数值转字符串的重载方法
    public static string ToString(long v, int radix) => ToString(v, radix, 0);
    public static string ToString(ulong v, int radix) => ToString(v, radix, 0);
    public static string ToString(double v, int radix) => ToString(v, radix, 0);
    public static string ToString(long v, int radix, int padding) => ToString(v, radix, padding, '0');
    public static string ToString(ulong v, int radix, int padding) => ToString(v, radix, padding, '0');
    public static string ToString(double v, int radix, int padding) => ToString(v, radix, padding, '0');
    
    /// <summary>
    /// 将double转换为字符串
    /// </summary>
    public static string ToString(double v, int radix, int padding, char paddingChar) 
        => ToString(BitConverter.DoubleToInt64Bits(v), radix, padding, paddingChar);
    
    /// <summary>
    /// 将long转换为字符串
    /// </summary>
    public static string ToString(long v, int radix, int padding, char paddingChar) 
        => ToString((ulong)v, radix, padding, paddingChar);
    
    /// <summary>
    /// 核心方法:将ulong数值转换为指定进制的字符串
    /// </summary>
    public static string ToString(ulong v, int radix, int padding, char paddingChar)
    {
        // 进制参数验证
        if (radix < 2)
        {
            radix = 10;
        }
        else if (radix > _keys.Length)
        {
            radix = _keys.Length;
        }
        
        uint baseValue = (uint)radix;
        string result;
        
        // 处理零值特殊情况
        if (v == 0)
        {
            result = "0";
        }
        else
        {
            result = string.Empty;
            // 使用除基取余法进行转换
            while (v > 0)
            {
                ulong remainder = v % baseValue;  // 计算当前余数
                result = _keys[(int)remainder] + result;  // 将余数映射为字符并拼接到结果前
                v /= baseValue;  // 更新商值
            }
        }
        
        // 填充处理:确保结果达到指定长度
        if (padding > result.Length)
        {
            result = result.PadLeft(padding, paddingChar);
        }
        return result;
    }
}

3. 算法原理详解

3.1 字符串转数值算法(ToUInt64)

此算法采用权重累加法,从字符串的最右字符(最低位)开始处理,每位数值乘以其权重(基数的幂次)后累加。

算法步骤解析:

  • 参数验证:检查输入字符串是否为空,修正进制基数到有效范围(2-36)
  • 字符映射:将每个字符转换为对应的数值(0-9对应0-9,A-Z/a-z对应10-35)
  • 权重计算:从最低位开始,每位权重是基数的递增幂次(基数的0次方、1次方、2次方…)
  • 结果累加:将每位数值乘以其权重后累加到最终结果

示例:二进制"1101"转换为十进制

1×2³ + 1×2² + 0×2¹ + 1×2⁰ = 8 + 4 + 0 + 1 = 13

3.2 数值转字符串算法(ToString)

此算法采用除基取余法,通过反复除以基数并记录余数来实现转换。

算法步骤解析:

  • 特殊情况处理:数值为0时直接返回"0"
  • 除基取余:反复将数值除以基数,记录每次的余数
  • 字符映射:将余数映射为字符集中的对应字符
  • 结果构建:将映射的字符从后向前拼接(逆序)
  • 填充处理:在结果前填充指定字符以达到最小长度要求

示例:十进制13转换为二进制

13 ÷ 2 = 6 余 1 → "1"
6 ÷ 2 = 3 余 0 → "01"  
3 ÷ 2 = 1 余 1 → "101"
1 ÷ 2 = 0 余 1 → "1101"

4. 关键位置

4.1 字符映射机制

工具类使用_keys字符串作为字符映射表,其中0-9对应数字0-9,A-Z对应数字10-35。这种设计支持最大36进制转换,且通过统一的映射表提高代码可维护性。

4.2 错误处理与边界条件

  • 空值处理:空字符串或null值返回0,避免异常
  • 进制范围:自动修正超出2-36范围的进制参数
  • 非法字符:遇到非法字符时返回0,保证程序稳定性
  • 数值越界:使用ulong类型支持更大数值范围

5. 使用示例与场景

5.1 基础转换示例

// 字符串转数值
Console.WriteLine(RadixConverter.ToInt64("1A", 16));  // 输出:26(16进制转10进制)
Console.WriteLine(RadixConverter.ToDouble("1010", 2)); // 输出:10(二进制转double)

// 数值转字符串
Console.WriteLine(RadixConverter.ToString(26, 16));    // 输出:"1A"(10进制转16进制)
Console.WriteLine(RadixConverter.ToString(10, 2, 8));  // 输出:"00001010"(填充至8位)

// 高进制转换(32进制)
Console.WriteLine(RadixConverter.ToString(100, 32));    // 输出:"34"

5.2 实际应用场景

  • 短URL生成:使用高进制(如36进制)将长数字转换为短字符串
  • 数据压缩:高进制表示可以更紧凑地存储数值数据
  • 编码解码:自定义进制用于简单加密或编码方案
  • 系统间数据交换:不同系统可能使用不同进制表示数据

6. 总结

本文详细介绍了C#中2~36进制转换的完整实现,涵盖了算法原理、代码实现和实际应用。该工具类具有良好的健壮性和扩展性,可以满足大多数进制转换需求。

到此这篇关于C#实现2~36进制转换的完整代码的文章就介绍到这了,更多相关C#进制转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#交错数组浅析

    C#交错数组浅析

    这里介绍C#交错数组,数组是具有同一类型的一组值,数组是引用类型的,因此存在内存堆中。数组中的元素值可以在定义数组时赋予,也可以在定义数组后对单个元素进行赋值
    2012-09-09
  • C#实现读取Excel文件并将数据写入数据库和DataTable

    C#实现读取Excel文件并将数据写入数据库和DataTable

    Excel文件是存储表格数据的普遍格式,因此能够高效地读取和提取信息对于我们来说至关重要,下面我们就来看看C#如何实现读取Excel文件并将数据写入数据库和DataTable吧
    2024-03-03
  • C#编写的windows计算器的实例代码

    C#编写的windows计算器的实例代码

    这篇文章介绍了C#编写windows计算器的代码,有需要的朋友可以参考一下
    2013-07-07
  • SQL+C#实现获得当前月的第一天与最后一天

    SQL+C#实现获得当前月的第一天与最后一天

    本文分享了SQL+C#获得当前月的第一天与最后一天的代码实例,代码简洁,适合初学者参考。需要的朋友可以看下
    2016-12-12
  • C#线程处理系列之线程池中的I/O线程

    C#线程处理系列之线程池中的I/O线程

    这篇文章主要介绍了C#线程处理系列之线程池中的I/O线程,在这篇文章中将介绍如何用线程池中的I/O线程来执行I/O操作,感兴趣的小伙伴们可以参考一下
    2016-04-04
  • C#中将DataTable转化成List<T>的方法解析

    C#中将DataTable转化成List<T>的方法解析

    大家应该都知道在.net项目中使用到DataTable和List<T>集合的地方较多,有的时候需要将DataTable转化成List<T>,那么改如何转化呢?下面通过这篇文章来一起学习下吧,本文中给出了详细的示例代码,相信对大家的理解和学习具有一定的参考借鉴价值。
    2016-12-12
  • C#并发容器之ConcurrentDictionary与普通Dictionary带锁性能详解

    C#并发容器之ConcurrentDictionary与普通Dictionary带锁性能详解

    这篇文章主要介绍了C#并发容器之ConcurrentDictionary与普通Dictionary带锁性能详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • c# 关闭窗体时提示的小例子

    c# 关闭窗体时提示的小例子

    这篇文章介绍了c#中关闭窗体时提示的小例子代码,有需要的朋友可以参考一下
    2013-07-07
  • C#中将UTC时间转换为JST时间的实现方法

    C#中将UTC时间转换为JST时间的实现方法

    在C#中,将UTC时间转换为JST(日本标准时间,即UTC+9)时间可以通过使用 DateTime 和 TimeZoneInfo 类来实现,JST比UTC快9小时,因此可以直接进行转换,本文将通过代码示例给大家介绍C#中将UTC时间转换为JST时间,需要的朋友可以参考下
    2025-01-01
  • 通过C#调取打印机打印文本和图片的多种方法

    通过C#调取打印机打印文本和图片的多种方法

    本文介绍了C#中五种常用的打印方法:使用.NET内置类、WPF打印功能、RDLC报表、第三方库iTextSharp和PDFsharp,以及如何处理异常和异步打印,需要的朋友可以参考下
    2026-01-01

最新评论