C# 大数运算

我想法就是用string去替换int,然后做加减乘除。
于是我开始百度之旅。。。

参考链接:腾讯游戏学院 

参考链接:CSDN
是不是感觉很对,这2个链接解决了问题,然而我测试了下,除了除法其他都没有问题。

100/1 = 商1100余数0, 100/2=商550余数0,60000/10000 = 商0余数60000

你们可以测试下,反正我测试是这样(因为我一开始很信任源代码的,后来使用出现的)

我很好奇,没有人指出来吗?用的都是对的吗?还是都偷偷摸摸的自己改的。。。

  public static string Des(char[] num1, char[] num2)
        {
            string finalRes = string.Empty;
            //判断两个数的大小,如果除数大于被除数,则直接返回结果
            int bigger = num1BiggerThanNum2(num1, num2);
            if (bigger < 0)
            {
                finalRes = "0";
            }
            else if (bigger == 0)
            {
                finalRes = "1";
            }
            else//除数小于被除数
            {
                //int alen = num1.Length;
                //int blen = num2.Length;
                string chushu = "";
                string shang = "";
                string mut = "";
                string num = "";
                char[] remove;
                //if (alen > blen)
                {
                    for (int i = 0; i < num1.Length; i++)
                    {
                        chushu += num1[i].ToString();
                        remove = RemoveZero(chushu).ToCharArray();
                        if (num1BiggerThanNum2(remove, num2) < 0)
                        {
                            //++
                            shang += "0";
                            continue;
                        }
                        else
                        {
                            for (int count = 9; count >= 0; count--)
                            {
                                num = count.ToString();
                                mut = Mut(num2, num.ToCharArray());
                                if (num1BiggerThanNum2(mut.ToCharArray(), remove) > 0)
                                {
                                    continue;
                                }
                                else
                                {
                                    break;
                                }
                            }
                            shang += num;
                            chushu = Sub(chushu.ToCharArray(), mut.ToCharArray());
                        }
                    }
                    finalRes = RemoveZero(shang);
                }
            }
            return finalRes;
        }

这是我后来自己改写的除法,用除法公式方式去算最后的值。

然后去实现一个int的变体,去模拟int的写法,然而我失败了。。一个驴唇不对马嘴的类就出来了。

格式为"111AA",计算主位111和副位AA
"111000000000000000",计算主位111和副位AA

主位长度最长为6位,副位超过枚举的最大值,主位值为int的最大值

 public enum VarEnum
    {
        None = 0,
        K = 3,
        M = 6,
        G = 9,
        T = 12,
        AA = 15,
        AB = 18,
        AC = 21,
        AD = 24,
        AE = 27,
        AF = 30,
        AG = 33,
        AH = 36,
        AI = 39,
        AJ = 42,
        AK = 45,
        AL = 48,
        AM = 51,
        AN = 54,
        AO = 57,
        AP = 60,
        AQ = 63,
        AR = 66,
        AS = 69,
        AT = 72,
        AU = 75,
        AV = 78,
        AW = 81,
        AX = 84,
        AY = 87,
        AZ = 90,
    }
 public class VarInt
    {
        public static readonly VarInt Zero = new VarInt(0);
        public static readonly VarInt One = new VarInt(1);
        public static readonly VarInt Two = new VarInt(2);
        public static readonly VarInt Three = new VarInt(3);
        public static readonly VarInt Four = new VarInt(4);
        public static readonly VarInt Five = new VarInt(5);
        public static readonly VarInt Six = new VarInt(6);
        public static readonly VarInt Seven = new VarInt(7);
        public static readonly VarInt Eight = new VarInt(8);
        public static readonly VarInt Nine = new VarInt(9);
        public static readonly VarInt Ten = new VarInt(10);
        public static readonly VarInt Hundred = new VarInt(100);
        public static readonly VarInt Thousand = new VarInt(1000);
        public static readonly VarInt TenThousand = new VarInt(10 * 1000);

        /// <summary>
        /// 主位
        /// </summary>
        public int MainValue { get; private set; }
        /// <summary>
        /// 副位
        /// </summary>
        public VarEnum ViceValue { get; private set; }
        /// <summary>
        /// 总位
        /// </summary>
        private string m_TotalValue = string.Empty;

        private int _CalcNum = 0;
        private string _CalcString = string.Empty;

        /// <summary>
        /// 由主位+副位计算
        /// </summary>
        /// <param name="main"></param>
        /// <param name="vice"></param>
        public VarInt(int main = 0, VarEnum vice = VarEnum.None)
        {
            Set(main, vice);
        }

        public VarInt(string splicingValue)
        {
            Set(splicingValue);
        }

        public void Set(int main = 0, VarEnum vice = VarEnum.None)
        {
            MainValue = main;
            ViceValue = vice;
            m_TotalValue = VarIntUtility.Conversion(MainValue, ViceValue);
        }

        public void Set(string splicingValue)
        {
            if (string.IsNullOrEmpty(splicingValue))
            {
                Set(0, VarEnum.None);
                return;
            }
            //纯数字"111222333444"
            if (VarIntUtility.IsNumber(splicingValue))
            {
                _CalcNum = 0;
                _CalcString = CalcBit(splicingValue, ref _CalcNum);

                //计算结果大于上限,更新结果
                if ((_CalcNum * VarIntUtility.VarIntBitNum) > (int)VarEnum.AZ)
                {
                    string finishStr = splicingValue.Remove(splicingValue.Length - ((int)VarEnum.AZ));
                    MainValue = VarMathf.num1BiggerThanNum2(finishStr.ToCharArray(), int.MaxValue.ToString().ToCharArray()) > 0 ? int.MaxValue : int.Parse(finishStr);
                    ViceValue = VarEnum.AZ;
                    m_TotalValue = VarIntUtility.Conversion(MainValue, ViceValue); ;
                }
                else
                {
                    MainValue = int.Parse(_CalcString);
                    ViceValue = (VarEnum)(_CalcNum * VarIntUtility.VarIntBitNum);
                    m_TotalValue = splicingValue;
                }
            }
            //主位+副位 "111222M"
            else
            {
               //从字符串中提取所有数字
                string finishStr = VarIntUtility.GetNumbers(splicingValue);
                MainValue = VarMathf.num1BiggerThanNum2(finishStr.ToCharArray(), int.MaxValue.ToString().ToCharArray()) > 0 ? int.MaxValue : int.Parse(finishStr);
                //从字符串中提取所有字母,转为枚举
                ViceValue = (VarEnum)Enum.Parse(typeof(VarEnum), VarIntUtility.GetLetter(splicingValue));
                //根据枚举值在主位后面加几个0
                m_TotalValue = VarIntUtility.Conversion(MainValue, ViceValue);
            }
        }

        private string CalcBit(string splicingValue, ref int num)
        {
            if (splicingValue.Length > 6)
            {
                string str = splicingValue.Remove(splicingValue.Length - VarIntUtility.VarIntBitNum);
                num++;
                return CalcBit(str, ref num);
            }
            return splicingValue;
        }

        #region 重载  
        public static VarInt operator +(VarInt a, VarInt b)
        {
            string calc = VarMathf.Add(a.ToCharArray(), b.ToCharArray());
            return new VarInt(calc);
        }

        public static VarInt operator -(VarInt a, VarInt b)
        {
            string calc = VarMathf.Sub(a.ToCharArray(), b.ToCharArray());
            return new VarInt(calc);
        }

        public static VarInt operator *(VarInt a, VarInt b)
        {
            string calc = VarMathf.Mut(a.ToCharArray(), b.ToCharArray());
            return new VarInt(calc);
        }

        public static VarInt operator /(VarInt a, VarInt b)
        {
            string calc = VarMathf.Des(a.ToCharArray(), b.ToCharArray());
            return new VarInt(calc);
        }

        public static bool operator ==(VarInt left, VarInt right)
        {
            return (left.MainValue == right.MainValue && left.ViceValue == right.ViceValue);
        }

        public static bool operator !=(VarInt left, VarInt right)
        {
            return (left.MainValue != right.MainValue && left.ViceValue != right.ViceValue);
        }

        public static bool operator >(VarInt left, VarInt right)
        {
            if (left.ViceValue > right.ViceValue)
            {
                return true;
            }
            else if (left.ViceValue == right.ViceValue)
            {
                return left.MainValue > right.MainValue;
            }
            else if (left.ViceValue < right.ViceValue)
            {
                return false;
            }
            return false;
        }

        public static bool operator <(VarInt left, VarInt right)
        {
            if (left.ViceValue < right.ViceValue)
            {
                return true;
            }
            else if (left.ViceValue == right.ViceValue)
            {
                return left.MainValue < right.MainValue;
            }
            else if (left.ViceValue > right.ViceValue)
            {
                return false;
            }
            return false;
        }

        public static bool operator >=(VarInt left, VarInt right)
        {
            if (left.ViceValue > right.ViceValue)
            {
                return true;
            }
            if (left.ViceValue == right.ViceValue)
            {
                return left.MainValue >= right.MainValue;
            }
            return false;
        }

        public static bool operator <=(VarInt left, VarInt right)
        {
            if (left.ViceValue < right.ViceValue)
            {
                return true;
            }
            if (left.ViceValue == right.ViceValue)
            {
                return left.MainValue <= right.MainValue;
            }
            return false;
        }

        public static VarInt Pow(VarInt a, int b)
        {
            if (b == 0)
                return VarInt.One;
            VarInt varInt = new VarInt(a.ToString());
            for (int i = 0; i < b - 1; i++)
            {
                varInt *= a;
            }
            return varInt;
        }
        #endregion

        public override string ToString()
        {
            return m_TotalValue;
        }

        public char[] ToCharArray()
        {
            return VarIntUtility.GetNumbers(m_TotalValue).ToCharArray();
        }

        public string ToFormatString()
        {
            if (MainValue == 0 && ViceValue == VarEnum.None)
                return "0";
            if (MainValue != 0 && ViceValue == VarEnum.None)
                return string.Format("{0}", MainValue);
            return string.Format("{0}{1}", MainValue, ViceValue.ToString());
        }
    }

最终可以去使用,应该是有恐怖的GC。

测试

VarInt varInt = new VarInt(101, VarEnum.AA);
Debug.Log("[test]" + varInt.ToString());
Debug.Log("[test]" + varInt.ToFormatString());

VarInt varInt1 = new VarInt("1AZ");
Debug.Log("[test]" + varInt1.ToString());
Debug.Log("[test]" + varInt1.ToFormatString());
VarInt varInt2 = new VarInt("2AZ");
Debug.Log("[test]" + varInt2.ToString());
Debug.Log("[test]" + varInt2.ToFormatString());

Debug.Log(varInt1 - varInt2);
Debug.Log((varInt1 - varInt2).ToFormatString());
发布了2 篇原创文章 · 获赞 4 · 访问量 548

猜你喜欢

转载自blog.csdn.net/flj135792468/article/details/88355351
今日推荐