/// <summary> /// 按位取模运算(不考虑正负号) /// </summary> /// <param name="num">模数</param> /// <param name="maxDecimalPlaces">答案保留小数位数</param> /// <returns>包含余数和商的元组</returns> protected override (Digitable, Digitable) Mod_unsigned(Digitable num, int maxDecimalPlaces) { NumStr a = this, b = num as NumStr; if (a == null || b == null) { throw new ProgramInterruptException(ProgramInterruptExceptionType.IllegalValue); } //统一计算空间 if (a.Space != b.Space) { if (a.Space == OperationSpace.DefaultSpace) { a = (NumStr)a.ChangeOperationSpace(b.Space); } else if (b.Space == OperationSpace.DefaultSpace) { b = (NumStr)b.ChangeOperationSpace(a.Space); } else { throw new ProgramInterruptException(ProgramInterruptExceptionType.NotSameOperationSpace); } } if (CompareAbsolute(a, b) < 0) { return(new NumStr(a), new NaturalNumStr(0, a.Space)); } var quotient = a.Divide_unsigned(b, 0) as NumStr; var ans = a.Minus_unsigned(quotient * b, maxDecimalPlaces, out bool tmp); return(ans, quotient); }
/// <summary> /// 改变元素的计算空间 /// </summary> /// <param name="space">新的计算空间,为null即为默认计算空间</param> /// <param name="newInstance">是否返回新的实例(如果为null,即为不确定)</param> /// <param name="maxDecimalPlaces">最大保留小数位数</param> /// <returns></returns> protected NumStr ChangeOS(OperationSpace space, bool?newInstance, int?maxDecimalPlaces) { if (space == null) { space = OperationSpace.DefaultSpace; } if (this.Space == space && (maxDecimalPlaces == null || maxDecimalPlaces == space.DefaultMaxDecimalPlaces)) { if (newInstance == true) { return(new NumStr(this)); } else { return(this); } } NumStr new_num = new NumStr(0, space, maxDecimalPlaces); if (IsZero) { return(new_num); } new_num.PositiveOrNegative = PositiveOrNegative; NumberBaseConversion(new_num, space.NumberBase, this); if (newInstance == false) { Copy(new_num, null, false); return(this); } else { return(new_num); } }
/// <summary> /// 取自然对数 /// </summary> /// <param name="maxDecimalPlaces">答案保留小数位数</param> /// <returns></returns> protected override Digitable Ln(int maxDecimalPlaces) { NumStr a = this; if (a == null) { throw new ProgramInterruptException(ProgramInterruptExceptionType.IllegalValue); } //特殊情况 if (!a.IsPositive) { throw new IllegalOperationException(IllegalOperationExceptionType.AntilogIsNotPositive); } else if (a.IsOne) { return(new NumStr(0, a.Space, maxDecimalPlaces)); } /* 原理: * 泰勒展开式:ln(1+x) = x-x^2/2+x^3/3-...+(-1)^(k-1)*(x^k)/k * = x(1-x(1/2-x(1/3-x(1/4-x(1/5...))))) */ NumStr ans = null; return(ans); }
/// <summary> /// 拷贝初始化 /// </summary> /// <param name="num">原始对象</param> /// <param name="deep">是否为深拷贝</param> public NaturalNumStr(NumStr num, bool deep = true) : base(num, 0, deep) { if (PositiveOrNegative < 0) { PositiveOrNegative = 1; } }
/// <summary> /// 用纯数字初始化,转换为指定的计算空间 /// </summary> /// <param name="num">数字</param> /// <param name="space">计算空间</param> public NaturalNumStr(NumStr num, OperationSpace space) : base(num, space, 0) { if (PositiveOrNegative < 0) { PositiveOrNegative = 1; } }
/// <summary> /// 用相同类型的数字初始化,转换为指定的计算空间 /// </summary> /// <param name="num">原始对象</param> /// <param name="space">计算空间</param> /// <param name="maxDecimalPlaces">最大保留小数位数</param> /// <param name="positiveOrNegative">正负性</param> public NumStr(NumStr num, OperationSpace space, int?maxDecimalPlaces = null, int?positiveOrNegative = null) { Space = space ?? num.Space; PositiveOrNegative = positiveOrNegative ?? num.PositiveOrNegative; MaxDecimalPlaces = maxDecimalPlaces.HasValue ? Math.Min(maxDecimalPlaces.Value, this.Space.DefaultMaxDecimalPlaces) : this.Space.DefaultMaxDecimalPlaces; NumberBaseConversion(this, Space.NumberBase, num); }
/// <summary> /// 拷贝 /// </summary> /// <param name="num">原始对象</param> /// <param name="maxDecimalPlaces">最大保留小数位数</param> /// <param name="deep">是否为深拷贝</param> protected void Copy(NumStr num, int?maxDecimalPlaces = null, bool deep = true) { PositiveOrNegative = num.PositiveOrNegative; Space = num.Space; MaxDecimalPlaces = maxDecimalPlaces.HasValue ? Math.Min(maxDecimalPlaces.Value, this.Space.DefaultMaxDecimalPlaces) : num.MaxDecimalPlaces; integerNumList = null; decimalNumList = null; if (deep) { if (num.integerNumList != null) { integerNumList = new LinkedList <uint>(); foreach (var i in num.integerNumList) { integerNumList.AddLast(i); } } if (MaxDecimalPlaces > 0 && num.decimalNumList != null) { decimalNumList = new LinkedList <uint>(); var i = num.decimalNumList.First; while (i != null && DecimalPlaces < MaxDecimalPlaces) { decimalNumList.AddLast(i.Value); i = i.Next; } } } else { integerNumList = num.integerNumList; if (MaxDecimalPlaces < num.DecimalPlaces) { decimalNumList = new LinkedList <uint>(); var i = num.decimalNumList.First; while (i != null && DecimalPlaces < MaxDecimalPlaces) { decimalNumList.AddLast(i.Value); i = i.Next; } } else { decimalNumList = num.decimalNumList; } } }
public InverseEnumerator(NumStr num) { list = num; current = 0; if (list.integerNumList != null) { node = list.integerNumList.Last; } else if (list.decimalNumList != null) { node = list.decimalNumList.First; } else { node = null; } }
/// <summary> /// 从小数点处分割,分别生成整数与小数部分 /// </summary> /// <param name="deepCopy">分割时是否深拷贝</param> /// <returns>包含整数与小数的元组</returns> public (NumStr, NumStr) SplitByDecimalPoint(bool deepCopy = false) { var integerPart = new NumStr(this, 0, deepCopy); var decimalPart = new NumStr(0, Space, MaxDecimalPlaces); if (decimalNumList != null) { decimalPart.PositiveOrNegative = PositiveOrNegative; if (deepCopy) { decimalPart.decimalNumList = new LinkedList <uint>(); foreach (var i in decimalNumList) { decimalPart.decimalNumList.AddLast(i); } } else { decimalPart.decimalNumList = decimalNumList; } } return(integerPart, decimalPart); }
/// <summary> /// 按位除法运算的除数倍数表的二分查找 /// </summary> /// <param name="b_table">数组</param> /// <param name="b">除数</param> /// <param name="v">要查找的值</param> /// <returns></returns> protected static uint Divide_unsigned_b_table_binary_search(NumStr[] b_table, NumStr b, NumStr v) { uint h = 0, t = (uint)b_table.Length, m; do { m = (h + t) / 2; if (b_table[m] == null) { b_table[m] = b * m; } var cpr = CompareAbsolute(v, b_table[m]); if (cpr == 0) { return(m); } else if (cpr < 0) { t = m - 1; } else { h = m; } }while (t - h > 1); if (h == t) { return(h); } else { if (t == b_table.Length) { return(h); } if (b_table[t] == null) { b_table[t] = b * t; } if (CompareAbsolute(v, b_table[t]) < 0) { if (b_table[h] == null) { b_table[h] = b * h; } return(h); } else { return(t); } } }
/// <summary> /// 开平方运算 /// </summary> /// <param name="maxDecimalPlaces">答案保留小数位数</param> /// <returns></returns> protected override Digitable Sqrt(int maxDecimalPlaces) { NumStr a = new NumStr(this); if (a == null) { throw new ProgramInterruptException(ProgramInterruptExceptionType.IllegalValue); } //特殊情况 if (a.IsNegative) { throw new IllegalOperationException(); } else if (a.IsZero) { return(new NumStr(0, a.Space, maxDecimalPlaces)); } //设进制为k,先将数字多次放大或缩小k^2倍,使其归一化为:1<=a<=k^2 var one = new NaturalNumStr(1, a.Space); var k2 = new NaturalNumStr(a.Space.NumberBase * a.Space.NumberBase, a.Space); var shiftTimes = 0; while (a < one) { a.RightShift(2); shiftTimes++; } while (a > k2) { a.LeftShift(2); shiftTimes--; } //平方根初值x var x = new NumStr(0, a.Space); //x当前的有效数字位数 var nx = 0; //x^2初值 var x2 = new NumStr(0, a.Space); //(x+1)^2的值 NumStr x12; do { //用完全平方公式计算(y+1)^2 x12 = x2 + x + x + one; if (a < x12) { //本位枚举完成,开始枚举下一位 x.RightShift(1); //x=x*k nx++; x2.RightShift(2); //x2=x2*k^2 a.RightShift(2); //a=a*k^2 } else { //继续枚举 x = x + one; x2 = x12; } } while (nx < maxDecimalPlaces + 1 - shiftTimes && a != x12); x.LeftShift(x.IntegerPlaces + x.DecimalPlaces - 1 + shiftTimes); return(x); }
/// <summary> /// 乘方运算(不考虑正负号) /// </summary> /// <param name="num">指数</param> /// <param name="maxDecimalPlaces">答案保留小数位数</param> /// <returns></returns> protected override Digitable Power_unsigned(Digitable num, int maxDecimalPlaces) { NumStr a = this, b = num as NumStr; if (a == null || b == null) { throw new ProgramInterruptException(ProgramInterruptExceptionType.IllegalValue); } //统一计算空间 if (a.Space != b.Space) { if (a.Space == OperationSpace.DefaultSpace) { a = (NumStr)a.ChangeOperationSpace(b.Space); } else if (b.Space == OperationSpace.DefaultSpace) { b = (NumStr)b.ChangeOperationSpace(a.Space); } else { throw new ProgramInterruptException(ProgramInterruptExceptionType.NotSameOperationSpace); } } //特殊情况 if (a.IsZero) { if (b.IsZero) { throw new IllegalOperationException(IllegalOperationExceptionType.ZeroSquareOfZero); } return(new NumStr(0, a.Space, maxDecimalPlaces)); } else if (b.IsZero) { return(new NumStr(1, a.Space, maxDecimalPlaces)); } NumStr ans; //将指数分割出整数,先做快速幂 var split = b.SplitByDecimalPoint(); if (!split.Item1.IsZero) { if (split.Item1.IsOne) { ans = split.Item2.IsZero ? new NumStr(a, maxDecimalPlaces) : a; } else { var tmp = a; ans = new NumStr(1, a.Space, maxDecimalPlaces); //将指数化为2进制 var binary = split.Item1.ChangeOperationSpace(new OperationSpace(0, 2)) as NumStr; var count = 0; foreach (var i in binary.integerNumList) { if (i == 1) { ans = ans.Multiply_unsigned(tmp, maxDecimalPlaces) as NumStr; ans.PositiveOrNegative = 1; //小心符号陷阱 } if (++count < binary.integerNumList.Count) { tmp = tmp.Multiply_unsigned(tmp, maxDecimalPlaces) as NumStr; tmp.PositiveOrNegative = 1; //小心符号陷阱 } } } } else { ans = new NumStr(1, a.Space, maxDecimalPlaces); } //小数部分乘方 return(ans); }
/// <summary> /// 按位乘法运算(不考虑正负号) /// </summary> /// <param name="num">乘数</param> /// <param name="maxDecimalPlaces">答案保留小数位数</param> /// <returns></returns> protected override Digitable Multiply_unsigned(Digitable num, int maxDecimalPlaces) { NumStr a = this, b = num as NumStr; if (a == null || b == null) { throw new ProgramInterruptException(ProgramInterruptExceptionType.IllegalValue); } //统一计算空间 if (a.Space != b.Space) { if (a.Space == OperationSpace.DefaultSpace) { a = (NumStr)a.ChangeOperationSpace(b.Space); } else if (b.Space == OperationSpace.DefaultSpace) { b = (NumStr)b.ChangeOperationSpace(a.Space); } else { throw new ProgramInterruptException(ProgramInterruptExceptionType.NotSameOperationSpace); } } var ans = new NumStr(0, a.Space, maxDecimalPlaces); //特殊情况 if (a.IsZero || b.IsZero) { return(ans); } var ansDecimalPlaces = a.DecimalPlaces + b.DecimalPlaces; //更换乘数 if (a.integerNumList == null && a.decimalNumList?.First.Value == 0) { a = a.RemoveDecimalPoint(); } if (b.integerNumList == null && b.decimalNumList?.First.Value == 0) { b = b.RemoveDecimalPoint(); } long remain = 0; var maxAnsPlaces = DefaultSettings.MaxIntegerPlaces + ansDecimalPlaces; var tmpList = new LinkedList <uint>(); //缓存链 var ptrHead = tmpList.First; var ptr = tmpList.First; foreach (var bi in b) { if (ptrHead == null) { tmpList.AddLast(0); if (tmpList.Count > maxAnsPlaces) { throw new NumberOutOfRangeException(); } ptrHead = tmpList.Last; } ptr = ptrHead; if (bi > 0) { foreach (var ai in a) { var product = ai * bi + remain; remain = product / ans.NumberBase; product %= ans.NumberBase; if (ptr == null) { tmpList.AddLast((uint)product); if (tmpList.Count > maxAnsPlaces) { throw new NumberOutOfRangeException(); } ptr = tmpList.Last; } else { ptr.Value += (uint)product; } ptr = ptr.Next; } if (remain > 0) { if (ptr == null) { tmpList.AddLast((uint)remain); if (tmpList.Count > maxAnsPlaces) { throw new NumberOutOfRangeException(); } } else { ptr.Value += (uint)remain; } remain = 0; } } ptrHead = ptrHead.Next; } //依次进位 remain = 0; ptr = tmpList.First; while (ptr != null) { ptr.Value += (uint)remain; if (ptr.Value >= ans.NumberBase) { remain = ptr.Value / ans.NumberBase; ptr.Value %= ans.NumberBase; } else { remain = 0; } ptr = ptr.Next; } if (remain > 0) { tmpList.AddLast((uint)remain); if (tmpList.Count > maxAnsPlaces) { throw new NumberOutOfRangeException(); } } //录入答案 ptr = tmpList.First; //调整光标位置 var tmpn = Math.Max(0, (long)ansDecimalPlaces - (long)maxDecimalPlaces); for (int i = 0; i < tmpn; i++) { ptr = ptr.Next; } var DecimalPlaces = Math.Min(ansDecimalPlaces, maxDecimalPlaces); bool flag = true; //判断小数位最高位是否为0 for (int i = 0; i < DecimalPlaces; i++) { if (ptr == null) { ans.decimalNumList.AddFirst(0); } else { if (ptr.Value > 0 || !flag) { if (flag) { flag = false; ans.decimalNumList = new LinkedList <uint>(); } ans.decimalNumList.AddFirst(ptr.Value); } ptr = ptr.Next; } } if (ptr != null) { ans.integerNumList = new LinkedList <uint>(); do { ans.integerNumList.AddLast(ptr.Value); ptr = ptr.Next; }while (ptr != null); } return(ans); }
/// <summary> /// 转换内部进制 /// </summary> /// <param name="container">容器(原有数值会丢失)</param> /// <param name="numberBase">新的进制</param> /// <param name="value">新的数值(不会改变原有内容)</param> protected static void NumberBaseConversion(NumStr container, uint numberBase, NumStr value = null) { if (value == null) { value = new NumStr(container); } if (numberBase == value.NumberBase) { if (value.integerNumList != null) { container.integerNumList = new LinkedList <uint>(); foreach (var i in value.integerNumList) { container.integerNumList.AddLast(i); } } if (container.MaxDecimalPlaces > 0 && value.decimalNumList != null) { container.decimalNumList = new LinkedList <uint>(); var i = value.decimalNumList.First; while (i != null && container.DecimalPlaces < container.MaxDecimalPlaces) { container.decimalNumList.AddLast(i.Value); i = i.Next; } } } else { //整数转换进制 if (value.IntegerPlaces > 0) { //特殊情况:2的幂进制之间互相转换 var i1 = tkTable.IndexOf(value.Space.NumberBase) + 1; var i2 = tkTable.IndexOf(numberBase) + 1; if (i1 > 0 && i2 > 0) { if (i2 % i1 == 0) { //特殊方法:相邻位组合 container.integerNumList = new LinkedList <uint>(); int q = i2 / i1, t = 0; uint k = 1; foreach (var v in value.integerNumList) { if (t == 0) { container.integerNumList.AddLast(0); k = 1; } container.integerNumList.Last.Value += v * k; t = (t + 1) % q; k *= value.NumberBase; } } else { //普通方法:先转为2进制 NumStr tmp = null; if (value.Space.NumberBase == 2) { tmp = value; } else { NumStr tmpNum = value; var two = new NumStr(2, tmpNum.Space); while (!tmpNum.IsZero) { var t = Mod(tmpNum, two, 0); t.Item1.PositiveOrNegative = t.Item1.IsEmpty() ? 0 : 1; if (tmp == null) { tmp = new NumStr() { PositiveOrNegative = 1, integerNumList = new LinkedList <uint>() } } ; tmp.integerNumList.AddLast((uint)t.Item1.ToInt64()); tmpNum = t.Item2; } } //再转换为目标进制,相邻位组合 if (numberBase == 2) { container.integerNumList = tmp.integerNumList; } else { container.integerNumList = new LinkedList <uint>(); int t = 0; uint k = 1; foreach (var v in tmp.integerNumList) { if (t == 0) { container.integerNumList.AddLast(0); k = 1; } container.integerNumList.Last.Value += v * k; t = (t + 1) % i2; k *= 2; } } } } else { //普通方法:先转为默认进制 NumStr tmp; if (value.Space.NumberBase == OperationSpace.DefaultSpace.NumberBase) { tmp = value; } else { var ni = value.integerNumList.First; tmp = ni.Value; NumStr nb = null; for (var i = 1; i < value.IntegerPlaces; i++) { ni = ni.Next; if (nb == null) { nb = value.NumberBase; } else { nb *= value.NumberBase; } tmp += ni.Value * nb; } } //再转换为目标进制 LinkedList <uint> tmpList = null; if (numberBase == OperationSpace.DefaultSpace.NumberBase) { tmpList = tmp.integerNumList; } else { var nb = new NumStr(numberBase, tmp.Space); while (!tmp.IsZero) { var t = Mod(tmp, nb, 0); t.Item1.PositiveOrNegative = CompareAbsolute(t.Item1, 0) == 0 ? 0 : 1; if (tmpList == null) { tmpList = new LinkedList <uint>(); } tmpList.AddLast((uint)t.Item1.ToInt64()); tmp = t.Item2; } } container.integerNumList = tmpList; } } //小数转换进制 if (container.MaxDecimalPlaces > 0 && value.DecimalPlaces > 0) { //先转为默认进制 NumStr tmp = null; if (value.Space.NumberBase == OperationSpace.DefaultSpace.NumberBase) { tmp = value; } else { NumStr nb = new NumStr(1, container.MaxDecimalPlaces == OperationSpace.DefaultSpace.DefaultMaxDecimalPlaces ? OperationSpace.DefaultSpace : new OperationSpace(container.MaxDecimalPlaces, OperationSpace.DefaultSpace.NumberBase)); tmp = new NumStr(0, nb.Space); foreach (var ni in value.decimalNumList) { //todo: 用有理数类替换,提高精度 nb /= value.NumberBase; tmp += ni * nb; } } //再转换为目标进制 LinkedList <uint> tmpList = null; if (numberBase == OperationSpace.DefaultSpace.NumberBase) { tmpList = tmp.decimalNumList; } else { tmpList = new LinkedList <uint>(); var zeroCount = 0; //记录小数末尾0的数量 var nb = new NumStr(numberBase, tmp.Space); do { tmp = new NumStr() { decimalNumList = tmp.decimalNumList, PositiveOrNegative = tmp.DecimalPlaces == 0 ? 0 : tmp.PositiveOrNegative, MaxDecimalPlaces = tmp.MaxDecimalPlaces, Space = tmp.Space }; tmp *= nb; var v = (uint)tmp.ToInt64(); tmpList.AddLast(v); if (v == 0) { zeroCount++; } else { zeroCount = 0; } }while (tmp.DecimalPlaces > 0 && tmpList.Count < container.MaxDecimalPlaces); //去除小数末尾0 if (zeroCount == tmpList.Count) { tmpList = null; } else { for (var i = 0; i < zeroCount; i++) { tmpList.RemoveLast(); } } } container.decimalNumList = tmpList; } } }
/// <summary> /// 将本数和另一个数取绝对值进行比较,大于输出1,小于输出-1,等于输出0 /// </summary> /// <param name="num"></param> /// <returns></returns> public override int CompareAbsolute(Digitable num) { NumStr a = this, b = num as NumStr; if (ReferenceEquals(a, b)) { return(0); } if (a == null || b == null) { throw new ProgramInterruptException(ProgramInterruptExceptionType.IllegalValue); } //统一计算空间 if (a.Space != b.Space) { if (a.Space == OperationSpace.DefaultSpace) { a = (NumStr)a.ChangeOperationSpace(b.Space); } else if (b.Space == OperationSpace.DefaultSpace) { b = (NumStr)b.ChangeOperationSpace(a.Space); } else { throw new ProgramInterruptException(ProgramInterruptExceptionType.NotSameOperationSpace); } } if (a.IntegerPlaces > b.IntegerPlaces) { return(1); } else if (a.IntegerPlaces < b.IntegerPlaces) { return(-1); } else { //比较整数 if (a.integerNumList != null) { var ai = a.integerNumList.Last; var bi = b.integerNumList.Last; while (ai != null && ai.Value == bi.Value) { ai = ai.Previous; bi = bi.Previous; } if (ai != null) { return(ai.Value > bi.Value ? 1 : -1); } } //比较小数 if (a.decimalNumList != null && b.decimalNumList == null) { return(1); } else if (a.decimalNumList == null && b.decimalNumList != null) { return(-1); } else if (a.decimalNumList == null && b.decimalNumList == null) { return(0); } else { var ai = a.decimalNumList.First; var bi = b.decimalNumList.First; while (ai != null && bi != null && ai.Value == bi.Value) { ai = ai.Next; bi = bi.Next; } if (ai != null && bi == null) { return(1); } else if (ai == null && bi != null) { return(-1); } else if (ai == null && bi == null) { return(0); } else { return(ai.Value > bi.Value ? 1 : -1); } } } }
/// <summary> /// 将两数进行比较,大于输出1,小于输出-1,等于输出0 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns></returns> public static int CompareAbsolute(NumStr a, NumStr b) => a.CompareAbsolute(b);
/// <summary> /// 取模运算 /// </summary> /// <param name="a">被模数</param> /// <param name="b">模数</param> /// <param name="maxDecimalPlaces">答案保留小数位数</param> /// <returns>包含余数和商的元组</returns> public static (NumStr, NumStr) Mod(NumStr a, NumStr b, int maxDecimalPlaces) { var ans = Digitable.Mod(a, b, maxDecimalPlaces); return(ans.Item1 as NumStr, ans.Item2 as NumStr); }
/// <summary> /// 按位除法运算(不考虑正负号) /// </summary> /// <param name="num">除数</param> /// <param name="maxDecimalPlaces">答案保留小数位数</param> /// <returns></returns> protected override Digitable Divide_unsigned(Digitable num, int maxDecimalPlaces) { NumStr a = this, b = num as NumStr; //方法:手动模拟法 + 二分查找优化 if (a == null || b == null) { throw new ProgramInterruptException(ProgramInterruptExceptionType.IllegalValue); } //统一计算空间 if (a.Space != b.Space) { if (a.Space == OperationSpace.DefaultSpace) { a = (NumStr)a.ChangeOperationSpace(b.Space); } else if (b.Space == OperationSpace.DefaultSpace) { b = (NumStr)b.ChangeOperationSpace(a.Space); } else { throw new ProgramInterruptException(ProgramInterruptExceptionType.NotSameOperationSpace); } } var ans = new NumStr(0, a.Space, maxDecimalPlaces); //特殊情况 if (a.IsZero) { return(ans); } else if (b.IsZero) { throw new IllegalOperationException(IllegalOperationExceptionType.DivideByZero); } int a_ptr = 0; var a_integerPlaces = a.IntegerPlaces + b.DecimalPlaces; //被除数的小数点位置 if (b.decimalNumList != null) { b = b.RemoveDecimalPoint(); } var an = a.IntegerPlaces + a.DecimalPlaces; var bn = b.IntegerPlaces; var new_a = new NumStr(0, a.Space, 0); //被除数片段 var b_table = new NumStr[ans.NumberBase]; //除数的倍数表 var aii = a.GetInverseEnumerator(); var bii = b.GetInverseEnumerator(); bool?a_less_than_b = null; LinkedListNode <uint> node_ptr = null; while (true) { //补位 bii = b.GetInverseEnumerator(); a_less_than_b = null; if (new_a.IsPositive) { var aii2 = new_a.GetInverseEnumerator(); while (a_less_than_b == null && aii2.MoveNext() && bii.MoveNext()) { if (aii2.Current < bii.Current) { a_less_than_b = true; } else if (aii2.Current > bii.Current) { a_less_than_b = false; } } } do { var v = aii.MoveNext() ? aii.Current : 0; if (v > 0 || new_a.IsPositive) { if (new_a.IsZero) { new_a.PositiveOrNegative = 1; new_a.integerNumList = new LinkedList <uint>(); } new_a.integerNumList.AddFirst(v); bii.MoveNext(); if (a_less_than_b == null) { if (v < bii.Current) { a_less_than_b = true; } else if (v > bii.Current) { a_less_than_b = false; } } } a_ptr++; if (a_ptr <= a_integerPlaces) { if (ans.IsZero) { ans.PositiveOrNegative = 1; ans.integerNumList = new LinkedList <uint>(); } if (ans.IntegerPlaces != 1 || ans.integerNumList.Last.Value > 0) { ans.integerNumList.AddFirst(0); if (ans.IntegerPlaces > DefaultSettings.MaxIntegerPlaces) { throw new NumberOutOfRangeException(); } node_ptr = ans.integerNumList.First; } } else { if (ans.DecimalPlaces == maxDecimalPlaces) { return(ans); } if (ans.decimalNumList == null) { ans.decimalNumList = new LinkedList <uint>(); } ans.decimalNumList.AddLast(0); node_ptr = ans.decimalNumList.Last; } } while (new_a.IntegerPlaces < bn + (a_less_than_b == true ? 1 : 0)); //做整除 var quotient = Divide_unsigned_b_table_binary_search(b_table, b, new_a); if (node_ptr != null) { node_ptr.Value = quotient; node_ptr = null; } else { if (a_ptr <= a_integerPlaces) { if (ans.integerNumList == null) { ans.integerNumList = new LinkedList <uint>(); } ans.integerNumList.AddFirst(quotient); if (ans.IntegerPlaces > DefaultSettings.MaxIntegerPlaces) { throw new NumberOutOfRangeException(); } } else { if (ans.decimalNumList == null) { ans.decimalNumList = new LinkedList <uint>(); } ans.decimalNumList.AddLast(quotient); } } if (maxDecimalPlaces > 0 && ans.DecimalPlaces >= maxDecimalPlaces) { return(ans); } //求余 new_a = new_a - b_table[quotient]; if (new_a.IsZero && a_ptr >= an) { return(ans); } } }
public bool Equals(NumStr other) { return(other != null && this == other && MaxDecimalPlaces == other.MaxDecimalPlaces); }
/// <summary> /// 拷贝初始化 /// </summary> /// <param name="num">原始对象</param> /// <param name="maxDecimalPlaces">最大保留小数位数</param> /// <param name="deep">是否为深拷贝</param> public NumStr(NumStr num, int?maxDecimalPlaces = null, bool deep = true) : base(num, maxDecimalPlaces) { Copy(num, maxDecimalPlaces, deep); }