public static HugeNumber operator -(HugeNumber a) { HugeNumber num = new HugeNumber(a); num.Reverse(); return(num); }
public static HugeNumber operator -(HugeNumber a, HugeNumber b) { HugeNumber num = new HugeNumber(a); num.Substract(b); return(num); }
public static HugeNumber operator /(HugeNumber a, HugeNumber b) { HugeNumber num = new HugeNumber(a); num.Divide(b); return(num); }
public static HugeNumber operator *(HugeNumber a, HugeNumber b) { HugeNumber num = new HugeNumber(a); num.Multiply(b); return(num); }
/// <summary> /// 计算指数 /// </summary> /// <param name="times"></param> /// <param name="precision">记录计算过程中的精度(即原数乘了10^precision倍)</param> public void Pow(int times, int precision = 0) { if (times < 0) { Reset(); } else if (times == 0) { SetABit(precision); } else { HugeNumber cache = new HugeNumber(this); HugeNumber temp = One; temp.MoveLeft(precision); SetABit(precision); int p = 0; for (int i = 0; i < 32; i++) { if ((times & (1 << i)) == 0) { continue; } while (p <= i) { temp.Multiply(cache); temp.MoveRight(precision); cache.SetValue(temp); p++; } Multiply(temp); MoveRight(precision); } } }
public static HugeNumber operator +(HugeNumber a, HugeNumber b) { HugeNumber num = new HugeNumber(a); num.Add(b); return(num); }
public int CompareAbsTo(HugeNumber b) { if (b.IsZero) { return(IsZero ? 0 : 1); } else if (IsZero) { return(-1); } if (mOffset != b.mOffset) { return(mOffset > b.mOffset ? 1 : -1); } byte ca, cb; for (int i = mOffset; i >= 0; i--) { ca = mDatas[i]; cb = b.mDatas[i]; if (ca < cb) { return(-1); } else if (ca > cb) { return(1); } } return(0); }
public int CompareTo(HugeNumber b) { if (b.IsZero) { return(IsZero ? 0 : (mNegative ? -1 : 1)); } if (mNegative ^ b.mNegative) { return(mNegative ? -1 : 1); } return(mNegative ? b.CompareAbsTo(this) : this.CompareAbsTo(b)); }
public void SetValue(HugeNumber num) { if (num.IsZero) { Reset(); } else { mNegative = num.mNegative; int size = num.mOffset + 1; Malloc(size); System.Array.Copy(num.mDatas, mDatas, size); mOffset = num.mOffset; } }
public HugeNumber(HugeNumber num) { mNegative = num.mNegative; if (num.mDatas != null) { int len = num.mDatas.Length; mDatas = new byte[len]; System.Array.Copy(num.mDatas, mDatas, len); } else { mDatas = null; } mOffset = num.mOffset; }
public void Divide(HugeNumber num) { if (num.IsZero) { throw new System.Exception(string.Format("{0} divided by 0 or null was not allowed.", this)); } if (IsZero) { return; } if (CompareAbsTo(num) < 0) { Reset(); return; } mNegative = mNegative ^ num.mNegative; HugeNumber tmp = new HugeNumber(this); tmp.Abs(); HugeNumber div = new HugeNumber(num); div.Abs(); Reset(); HugeNumber sum = Zero; while (tmp.CompareTo(div) >= 0) { int mov = tmp.mOffset - div.mOffset; div.MoveLeft(mov); if (tmp.CompareTo(div) < 0) { mov--; div.MoveRight(1); } tmp.Substract(div); if (tmp.CompareTo(Zero) >= 0) { sum.SetABit(mov); Add(sum); div.MoveRight(mov); } else { break; } } }
public void Multiply(HugeNumber num) { if (IsZero) { return; } if (num.IsZero) { Reset(); return; } mNegative = mNegative ^ num.mNegative; HugeNumber temp = new HugeNumber(this); Reset(); int a, b; int stepin = 0; int v; int p; for (int i = 0; i <= num.mOffset; i++) { if (num.mDatas[i] == 0) { continue; } for (int j = 0; j <= temp.mOffset; j++) { p = i + j; Malloc(p + 1); a = temp.mDatas[j]; b = num.mDatas[i]; v = a * b + stepin + mDatas[p]; mDatas[p] = (byte)(v % 10); stepin = v / 10; } if (stepin > 0) { p = i + temp.mOffset + 1; Malloc(p + 1); mDatas[p] = (byte)stepin; stepin = 0; } } mOffset = GetOffset(mDatas.Length - 1); }
public void Substract(HugeNumber num) { num.Reverse(); Add(num); num.Reverse(); }
public void Add(HugeNumber num) { if (num.IsZero) { return; } int size = Mathf.Max(num.mOffset, mOffset); Malloc(size + 1); if (num.mNegative ^ mNegative) { int cmp = CompareAbsTo(num); if (cmp == 0) { Reset(); } else { // 借位 int borrow = 0; int v; if (cmp < 0) { for (int i = 0; i <= size; i++) { v = num.mDatas[i] - borrow - mDatas[i]; if (v < 0) { v += 10; borrow = 1; } else { borrow = 0; } mDatas[i] = (byte)v; } mOffset = GetOffset(size); mNegative = !mNegative; } else { for (int i = 0; i <= size; i++) { v = mDatas[i] - borrow - num.mDatas[i]; if (v < 0) { v += 10; borrow = 1; } else { borrow = 0; } mDatas[i] = (byte)v; } mOffset = GetOffset(size); } } } else { int v; int stepin = 0; for (int i = 0; i <= size; i++) { v = mDatas[i] + num.mDatas[i] + stepin; if (v >= 10) { v -= 10; stepin = 1; } else { stepin = 0; } mDatas[i] = (byte)v; } if (stepin != 0) { Malloc(size + 2); mDatas[size + 1] = (byte)(mDatas[size + 1] + stepin); } mOffset = GetOffset(mDatas.Length - 1); } }