65.9K
CodeProject 正在变化。 阅读更多。
Home

从一个数制到另一个数制

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (8投票s)

2012年5月10日

CPOL
viewsIcon

15776

这是“从一个数制到另一个数制”的替代方案

正如我在原始评论中所提到的,这段代码是针对一个关于如何最好地做到这一点的主题而编写的——我认为这个主题在Lounge论坛,但也可能在C#论坛。

首先,你需要有一组数字,以下是我对于最多64进制的首选数字集——用户可以根据需要提供不同的集合。

namespace PIEBALD.Lib
{
    public static partial class LibStr
    {
        /* Digits used for string representations of numeric values */
        public const string Digits 
          = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_$" ;
    }
}

然后,你需要将现有的字符串转换为数字(我选择使用long,但你的需求可能不同)。

public static long
StringToLong
(
    string Subject
,
    int    Base
,
    string Digits
)
{
    if ( Subject == null )
    {
        throw ( new System.ArgumentNullException
        (
            "Subject"
        ,
            "Subject must not be null"
        ) ) ;
    }

    if ( Base < 2 )
    {
        throw ( new System.ArgumentException
        (
            "Base must not be less than 2"
        ,
            "Base"
        ) ) ;
    }

    if ( Digits == null )
    {
        Digits = LibStr.Digits ;
    }

    if ( Digits.Length < Base )
    {
        throw ( new System.ArgumentException
        (
            "Not enough Digits were provided for the Base"
        ,
            "Digits"
        ) ) ;
    }

    long result = 0 ;
    int  sign   = 0 ;
    int  offset ;

    string DIGITS = Digits.ToUpper() ;

    foreach ( char ch in Subject )
    {
        offset = Digits.IndexOf ( ch ) ;

        if ( ( offset == -1 ) || ( offset >= Base ) )
        {
            offset = DIGITS.IndexOf ( char.ToUpper ( ch ) ) ;
        }

        if ( ( offset != -1 ) && ( offset < Base ) )
        {
            result = result * Base + offset ;

            if ( sign == 0 )
            {
                sign = 1 ;
            }
        }
        else
        {
            if ( ( sign == 0 ) && ( ch == '-' ) )
            {
                sign = -1 ;
            }
        }
    }

    return ( result * sign ) ;
}

然后,你可以转换回字符串,使用不同的进制或不同的字符集。

public static string
LongToString
(
    long   Subject
,
    int    Base
,
    string Digits
)
{
    if ( Base < 2 )
    {
        throw ( new System.ArgumentException
        (
            "Base must not be less than 2"
        ,
            "Base"
        ) ) ;
    }

    if ( Digits == null )
    {
        Digits = PIEBALD.Lib.LibStr.Digits ;
    }

    if ( Digits.Length < Base )
    {
        throw ( new System.ArgumentException
        (
            "Not enough Digits were provided for the Base"
        ,
            "Digits"
        ) ) ;
    }

    System.Text.StringBuilder result = new System.Text.StringBuilder() ;

    int sign = 1 ;

    if ( Subject < 0 )
    {
        Subject *= sign = -1 ;
    }

    do
    {
        result.Insert ( 0 , Digits [ (int) ( Subject % Base ) ] ) ;

        Subject /= Base ;
    }
    while ( Subject > 0 ) ;

    if ( sign == -1 )
    {
        result.Insert ( 0 , '-' ) ;
    }

    return ( result.ToString() ) ;
}

我还有这些方法的重载,允许调用者仅指定值或值和进制——在C# 4中,可以使用可选参数来实现这一点。我注意到这段代码假定大写数字小于小写数字。如果你想添加分隔符,应该在另一个方法中完成,并可能考虑文化差异。

© . All rights reserved.