• C# 10进制与62进制互转 数据大无压力 10进制与72,96进制任意转换


    因项目需要把10进制的ID转换成62进制的字符串,分享给别人。

    于是在网上搜索了很多算法,但都未能满足需要,项目里的ID是固定算法算出来的18~20位数据的ulong整型。

    如:17223472272256398107,509488277152981097。

    网上找的算法问题在于,将ulong的值转换62进制的字符串后,再将字符串转换成ulong值时会不准确。

    于是各种测试与假象问题所在,最后确定算法确实没有问题,于是开始怀疑数据类型的问题。

    果然,原因是使用了Math.Pow(double x,double y)(该方法计算x的y次方的值),double和float的精度只能精确到小数后面7位,但是我算法里没有用到小数,所以问题应该是在于Pow方法,估计应该是内部实现,可能会以幂的形式来计算,所以如果数据大了,以幂的形式表示超出7位的会出现类似int的计算方法。

    所以重新写了Pow方法,果然问题解决了。重新改写的方法最大值可以支持到decimal的最大值(79228162514264337593543950335),28位。

    理论上是可以支持无限大的数值的,只是要改写decimal类型。

    直接上代码吧:

      public class Converter
        {
            private static String keys = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";//编码,可加一些字符也可以实现72,96等任意进制转换,但是有符号数据不直观,会影响阅读。
            private static int exponent = keys.Length;//幂数
    
            /// <summary>
            /// decimal value type to 62 string
            /// </summary>
            /// <param name="value">The max value can not more decimal.MaxValue<</param>
            /// <returns>Return a specified 62 encode string</returns>
            public static string Decimal2Str(decimal value)//17223472558080896352ul
            {
                string result = string.Empty;
                do
                {
                    decimal index = value % exponent;
                    result = keys[(int)index] + result;
                    value = (value - index) / exponent;
                }
                while (value > 0);
    
                return result;
            }
    
    
            /// <summary>
            /// 62 encode string to decimal
            /// </summary>
            /// <param name="value">62 encode string</param>
            /// <returns>Return a specified decimal number that decode by 62 string</returns>
            public static decimal Str2Decimal(string value)//bUI6zOLZTrj
            {
                decimal result = 0;
                for (int i = 0; i < value.Length; i++)
                {
                    int x = value.Length - i - 1;
                    result += keys.IndexOf(value[i]) * Pow(exponent, x);// Math.Pow(exponent, x);
                }
                return result;
            }
    
            /// <summary>
            /// 一个数据的N次方
            /// </summary>
            /// <param name="x"></param>
            /// <returns></returns>
            private static decimal Pow(decimal baseNo, decimal x)
            {
                decimal value = 1;////1 will be the result for any number's power 0.任何数的0次方,结果都等于1
                while (x > 0)
                {
                    value = value * baseNo;
                    x--;
                }
                return value;
            }
        }

    这位朋友的数据类型解说的比较详细,参见:http://www.cnblogs.com/Lxiaojiang/p/3631371.html

    PS: 这段时间Google的强力封杀,只好自己奋发,希望政府能还我们一个开阔、正常的网络。

  • 相关阅读:
    环形链表II 找环入口
    最短无序连续子数组 复制数组排序后与原数组相比
    和为K的子数组 暴力 或 hash+前缀
    在排序数组中查找元素的第一个和最后一个位置 二分法+递归
    NodeJs 批量重命名文件,并保存到指定目录
    NodeJs 批量图片瘦身,重设尺寸和图片质量并保存到指定目录
    NodeJs 获取照片拍摄日期和视频拍摄日期,并按日期目录存档
    Oracle迁移记录
    Oracle数据库迁移前的准备工作(创建用户并且分配权限及表空间)
    Oracle 11g R2性能优化 10046 event【转载】
  • 原文地址:https://www.cnblogs.com/Jeremys/p/3796466.html
Copyright © 2020-2023  润新知