public BigNum ShiftDigitsToHigh(BigNum a, int i) { BigNum result = new BigNum(a.array.Length + i); for (int k = 0; k < a.array.Length; k++) { result.array[k + i] = a.array[k]; } return(result); }
public static int HighNotZeroIndex(BigNum a) { for (var i = a.array.Length - 1; i >= 0; i--) { if (a.array[i] > 0) { return(i); } } return(0); }
public static BigNum LongMulOneDigit(BigNum a, ulong b) { BigNum c = new BigNum(a.array.Length + 1); for (int i = 0; i < a.array.Length; i++) { temp = a.array[i] * b + carry; c.array[i] = temp & 0xffffffff; carry = temp >> 32; } c.array[a.array.Length] = carry; return(c); }
public int Bitlen(BigNum a) { var bits = 0; var index = HighNotZeroIndex(a); var temp = a.array[index]; while (temp > 0) { temp >>= 1; bits++; } return(bits + 32 * index); }
public static BigNum RemoveHighZeros(BigNum c) { int i = c.array.Length - 1; while (c.array[i] == 0) { i--; } BigNum result = new BigNum(i + 1); Array.Copy(c.array, result.array, i + 1); return(result); }
public int Compare(BigNum a, BigNum b) { var maxlen = Math.Max(a.array.Length, b.array.Length); Control(a, b, maxlen); for (int i = a.array.Length - 1; i > -1; i--) { if (a.array[i] > b.array[i]) { return(1); } if (a.array[i] < b.array[i]) { return(-1); } } return(0); }
public BigNum ShiftBitsToHigh(BigNum a, int shift) { int t = shift / 32; int s = shift - t * 32; ulong n, carry = 0; BigNum result = new BigNum(a.array.Length + t + 1); for (int i = 0; i < a.array.Length; i++) { n = a.array[i]; n = n << s; result.array[i + t] = (n & 0xFFFFFFFF) | carry; carry = (n & 0xFFFFFFFF00000000) >> 32; } result.array[a.array.Length + t] = carry; return(result); }
public BigNum Addition(BigNum a, BigNum b) { var maxlen = Math.Max(a.array.Length, b.array.Length); Control(a, b, maxlen); carry = 0; var result = new BigNum(maxlen + 1); for (int i = 0; i < maxlen; i++) { ulong temp = a.array[i] + b.array[i] + carry; carry = temp >> 32; result.array[i] = temp & 0xffffffff; } result.array[a.array.Length] = carry; return(result); }
public BigNum LongPowerWindow(BigNum a, BigNum b) { Dictionary <char, int> HexToDecimal = new Dictionary <char, int> { { '0', 0 }, { '1', 1 }, { '2', 2 }, { '3', 3 }, { '4', 4 }, { '5', 5 }, { '6', 6 }, { '7', 7 }, { '8', 8 }, { '9', 9 }, { 'A', 10 }, { 'B', 11 }, { 'C', 12 }, { 'D', 13 }, { 'E', 14 }, { 'F', 15 } }; var Bstring = b.ToString(); var result = new BigNum("1"); if (Compare(a, Zero) == 0) { return(Zero); } if (Compare(b, Zero) == 0) { return(One); } BigNum[] DegreesOfTwo = new BigNum[16]; DegreesOfTwo[0] = new BigNum("1"); DegreesOfTwo[1] = a; for (int k = 2; k < DegreesOfTwo.Length; k++) { DegreesOfTwo[k] = Multiplication(DegreesOfTwo[k - 1], a); } for (int i = 0; i < Bstring.Length; i++) { var x = Bstring[i]; result = Multiplication(result, DegreesOfTwo[HexToDecimal[Bstring[i]]]); if (i != Bstring.Length - 1) { for (int j = 1; j <= 4; j++) { result = Multiplication(result, result); } } } return(result); }
public BigNum Substraction(BigNum a, BigNum b) { if (Compare(a, b) == 0 || Compare(a, b) == -1) { return(Zero); } var maxlen = Math.Max(a.array.Length, b.array.Length); Control(a, b, maxlen); var result = new BigNum(maxlen); for (int i = 0; i < maxlen; i++) { temp = a.array[i] - b.array[i] - borrow; result.array[i] = temp & 0xffffffff; borrow = (temp <= a.array[i]) ? 0ul : 1ul; } return(result); }
public BigNum Multiplication(BigNum a, BigNum b) { var maxlen = Math.Max(a.array.Length, b.array.Length); Control(a, b, maxlen); var result = new BigNum(a.array.Length + b.array.Length); for (int i = 0; i < a.array.Length; i++) { carry = 0; for (int j = 0; j < b.array.Length; j++) { ulong temp = result.array[i + j] + a.array[j] * b.array[i] + carry; result.array[i + j] = temp & 0xFFFFFFFF; carry = temp >> 32; } result.array[i + a.array.Length] = carry; } result = RemoveHighZeros(result); return(result); }
public BigNum[] LongDiv(BigNum a, BigNum b) { int k = Bitlen(b); int t = 0; BigNum r = new BigNum(a.ToString()); BigNum q = new BigNum(1); BigNum c = new BigNum(1); while (Compare(r, b) >= 0) { t = Bitlen(r); c = ShiftBitsToHigh(b, t - k); if (Compare(r, c) == -1) { t--; c = ShiftBitsToHigh(b, t - k); } r = Substraction(r, c); q = Addition(q, ShiftBitsToHigh(One, t - k)); } BigNum[] result = new BigNum[] { q, r }; return(result); }
public static void Control(BigNum a, BigNum b, int maxlen) { Array.Resize(ref a.array, maxlen); Array.Resize(ref b.array, maxlen); }