/// <summary> /// Calculates 'this'^power /// </summary> /// <param name="power"></param> public void Power(BigInt power) { if (power.IsZero() || power.sign) { Zero(); digitArray[0] = 1; return; } BigInt pow = new BigInt(power); BigInt temp = new BigInt(this); BigInt powTerm = new BigInt(this); pow.Decrement(); for (; !pow.IsZero(); pow.RSH(1)) { if ((pow.digitArray[0] & 1) == 1) { temp.Mul(powTerm); } powTerm.Square(); } Assign(temp); }
/// <summary> /// Converts this to a string, in the specified base /// </summary> /// <param name="numberBase">the base to use (min 2, max 16)</param> /// <returns>a string representation of the number</returns> public string ToString(int numberBase) { char[] digitChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; string output = ""; BigInt clone = new BigInt(this); clone.sign = false; int numDigits = 0; while (!clone.IsZero()) { BigInt div, mod; DivMod(clone, (uint)numberBase, out div, out mod); int iMod = (int)mod; output = String.Concat(digitChars[(int)mod], output); numDigits++; clone = div; } if (output.Length == 0) output = "0"; if (sign) output = String.Concat("-", output); return output; }
/// <summary> /// This function is used for floating-point division. /// </summary> /// <param name="n2"></param> //Given two numbers: // In floating point 1 <= a, b < 2, meaning that both numbers have their top bits set. // To calculate a / b, maintaining precision, we: // 1. Double the number of digits available to both numbers. // 2. set a = a * 2^d (where d is the number of digits) // 3. calculate the quotient a <- q: 2^(d-1) <= q < 2^(d+1) // 4. if a >= 2^d, s = 1, else s = 0 // 6. shift a down by s, and undo the precision extension // 7. return 1 - shift (change necessary to exponent) public int DivAndShift(BigInt n2) { if (n2.IsZero()) return -1; if (digitArray.Length != n2.digitArray.Length) MakeSafe(ref n2); int oldLength = digitArray.Length; //Double the number of digits, and shift a into the higher digits. Pad(); n2.Extend(); //Do the divide (at double precision, ouch!) Div(n2); //Shift down if 'this' >= 2^d int ret = 1; if (digitArray[oldLength] != 0) { RSH(1); ret--; } SetNumDigits(oldLength); n2.SetNumDigits(oldLength); return ret; }
/// <summary> /// True iff n2 (precision-adjusted to this) == n1 /// </summary> /// <param name="n2"></param> /// <returns></returns> public bool Equals(BigInt n2) { if (IsZero() && n2.IsZero()) return true; if (sign != n2.sign) return false; int Length = digitArray.Length; if (n2.digitArray.Length != Length) MakeSafe(ref n2); for (int i = 0; i < Length; i++) { if (digitArray[i] != n2.digitArray[i]) return false; } return true; }