首页 > 代码库 > 任意进制转换算法

任意进制转换算法

任意进制转换算法

N年没有写博客,发个进制转换的玩下,支持负数;功能属于简化版的 Convert.ToInt32 ,特点是:

1、任意位,如:0,1(二进制),0...7(八进制),0...9,A...F(16进制),0...N(N进制),或者是:!@#$%^&*(8进制,字符符号),也可以是中文。

2、8 位最大长度。

3、C#源码。

最近写markdown格式习惯啦,cnblogs啥时候全改掉算了,别用这个htmleditor算了。

先说明下进制转换的基础知识,不会的可以了解下,会的就别看了,后面的也别看,纯粹属于浪费时间。

 

?
1
2
3
4
5
6
7
8
9
10
11
12
十六进制转十进制表
  
                                           10         15        1
<--------------------------------------------------------------------
0         0         0        0      0      A         F         1
<--------------------------------------------------------------------
16^7       16^6      16^5     16^4   16^3  16^2       16^1      16^0
268435456  16777216  1048576  65536  4096  256        16        1
<--------------------------------------------------------------------
                                           (10*256) + (15*16) + (1*1)
                                           =2560+240+1
                                           =2801

  

 十进制转十六进制表          ^19%16=3   | 0x319/16=1   | 0x1          = 0x13H

 

 十六进制到二进制快速转换 <----------------------- 2^3   2^2  2^1  2^0 8     4    2    1 <----------------------- 0xF821 = 1111 1000 0010 0001 <----------------------- 0xF = 15     = 8 + 4 + 2 + 1     = 1   1   1   1 0x8 = 8     = 8 + 0 + 0 + 0     = 1   0   0   0 0x2 = 2     = 0 + 0 + 2 + 0     = 0   0   1   0 0x1 = 1     = 0 + 0 + 0 + 1     = 0   0   0   1

 

 二进制到十六进制快速转换 <----------------------- 2^3   2^2  2^1  2^0 8     4    2    1 <----------------------- 1111 1000 0010 0001 = 0xF821 <----------------------- 1111    = 8 + 4 + 2 + 1        = 15        = 0xF 1000    = 8 + 0 + 0 + 0        = 8        = 0x8 0010    = 0 + 0 + 2 + 0        = 2        = 0x2 0001    = 0 + 0 + 0 + 1        = 1        = 0x1

 

十进制快速转换十六进制        103 = (6 * 16) + 7 = 0x67        22  = (1 * 16) + 6 = 0x16        54  = (3 * 16) + 6 = 0x36        255 = (15* 16) + 15 = 0xff        999 = (62 * 16) + 7 ~ 0x7          62= (3 * 16) + 14 ~ 0xe            = 3 ~ 0x3            = 0x3e7        9999= (624 * 16) + 15 ~ 0xF         624= (39*16) + 0 ~ 0x0          39= (2* 16) + 7 ~ 0x7           2= 2 ~ 0x2            = 0x270f        1980= (123 * 16) + 12 ~ 0xc         123= (7 * 16) + 11 ~ 0xb           7= 7 ~ 0x7            = 0x7bc

 

计算过程摆完了,下面是测试代码(代码未经优化,纯属测试):

    class MainClass    {        public static void Main (string[] args)        {            var nt = -3212;            var ct = "";            ct = ConvertToAny (nt, 0, "a,b,c");            Console.WriteLine (ct);            var rt = AnyToNumber (ct, "a,b,c");            Console.WriteLine (rt);            Console.WriteLine (Convert.ToString(nt,2));            Console.ReadLine ();            Console.WriteLine ("Test begin");            for (int n = -1230; n < 1230; n++) {                var a = n.ToString ("X");                var b = ConvertToAny (n, 0, "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F");                if (a != b) {                    Console.WriteLine ("[{2}]Error:a!=b: {0} {1}", a, b, n);                } else if (n % 100 == 0) {                    Console.WriteLine ("[{2}]Curr: a!=b: {0} {1}  OK", a, b, n);                }            }            Console.WriteLine ("Test ok");            Console.WriteLine ("Test begin");            for (int n = -1230; n < 1230; n++) {                var hex = n.ToString ("X");                var a = Convert.ToInt32 (hex, 16);                var b = AnyToNumber (hex, "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F");                if (a != b) {                    Console.WriteLine ("[{2}]Error:a!=b: {0} {1}", a, b, hex);                } else if (n % 100 == 0) {                    Console.WriteLine ("[{2}]Curr: a!=b: {0} {1}  OK", a, b, hex);                }            }            Console.WriteLine ("Test ok");            Console.WriteLine (ConvertToAny (int.MaxValue, 0, "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F"));        }        static bool isNegativeNumber(string any, string anyString ){            var s = ConvertToAny (int.MaxValue, 0, anyString);            if (s.Length != any.Length) {                return false;            } else {                var ReverseTable = BuildReverseTable (anyString);                if (ReverseTable [any [0].ToString ()] > ReverseTable [s [0].ToString ()]) {                    return true;                }            }            return false;        }        static int AnyToNumber (string any, string anyString = "0,1,2,3,4,5,6,7,8,9")        {            int sum = 0;            var ConversionTable = BuildConversionTable (anyString);            var ReverseTable = BuildReverseTable (anyString);            var tableBit = ConversionTable.Count;            bool negativeNumber = false;            var conversionPadSize = 0;            conversionPadSize = 128 / tableBit;            if (tableBit < 10) {                conversionPadSize /= 2;            }            //是否负数            if( isNegativeNumber( any, anyString) ){                negativeNumber = true;                //反转                var res = any;                any = "";                var moveBit = tableBit - 1;                foreach (var c in res) {                    any += NumberConversion (ConversionTable, moveBit - FindConversion (ReverseTable, c.ToString ()));                }            }            var cur = any.Length - 1;            for (var n = 0; n < any.Length; n++,cur--) {                var c = any [n].ToString ();                var bitSum = FindConversion (ReverseTable, c) * (int)Math.Pow (tableBit, cur);                sum += bitSum;            }            if (negativeNumber) {                //补位                sum++;                sum = 0 - sum;            }            return sum;        }        static string ConvertToAny (int number, int padSize = 8, string anyString = "0,1,2,3,4,5,6,7,8,9")        {            var conversionPadSize = padSize;            var ConversionTable = BuildConversionTable (anyString);            var ReverseTable = BuildReverseTable (anyString);            var tableBit = ConversionTable.Count;            long input = Math.Abs ((long)number);            //补码            if (number < 0) {                input -= 1;                conversionPadSize = 128 / tableBit;                if (tableBit < 10) {                    conversionPadSize /= 2;                }            }                        var result = "";            while (true) {                if (input >= tableBit) {                    result = NumberConversion (ConversionTable, (int)(input % tableBit)) + result;                    input = (int)(input / tableBit);                } else {                    result = NumberConversion (ConversionTable, (int)input) + result;                    break;                }            }            if (result.Length < conversionPadSize) {                //补位                result = StringPadLeft (result, conversionPadSize, ConversionTable [0]);            } else {//                //对齐//                if (result.Length % 2 != 0) {//                    result = ConversionTable[0] + result;//                }            }                if (number < 0) {                //反转                var res = result;                result = "";                var moveBit = tableBit - 1;                foreach (var c in res) {                    result += NumberConversion (ConversionTable, moveBit - FindConversion (ReverseTable, c.ToString ()));                }            }            return result;        }        static string StringPadLeft (string src, int size, string c)        {            var nsize = size - src.Length;            for (var n = 0; n < nsize; n++) {                src = c + src;            }            return src;        }        static string NumberConversion (Dictionary<int,string> table, int n)        {            return table [n];        }        static int FindConversion (Dictionary<string,int> table, string c)        {            return table [c];        }        static Dictionary<string,int> BuildReverseTable (string tableString)        {            var table = tableString.Split (",".ToCharArray (), StringSplitOptions.RemoveEmptyEntries).ToList ();            //补位操作,必须是2的倍数            if (table.Count % 2 != 0) {                table.Insert (0, "0");            }            var result = new Dictionary<string,int> ();            for (var i = 0; i < table.Count; i++) {                result.Add (table [i].ToString (), i);            }            return result;        }        static Dictionary<int,string> BuildConversionTable (string tableString)        {            var table = tableString.Split (",".ToCharArray (), StringSplitOptions.RemoveEmptyEntries).ToList ();            //补位操作,必须是2的倍数            if (table.Count % 2 != 0) {                table.Insert (0, "0");            }            var result = new Dictionary<int,string> ();            for (var i = 0; i < table.Count; i++) {                result.Add (i, table [i].ToString ());            }            return result;        }    }

 

有趣的测试:

技术分享

转换结果

技术分享

 

代码未经测试,自己可以完善

 

 

http://www.cnblogs.com/Chinasf/p/5547968.html

任意进制转换算法