private static void _MulNumber(ref BigInt C, ref BigInt B, ulong A) { if (B == 0) { C = new BigInt(B.Size, 0); } else if (A == 0) { C = new BigInt(B.Size, 0); } else if (A == 1) { C = B; } else if (A == 2) { C = B.Clone(); C.ShiftLeft(1); } else if (A == 8) { C = B.Clone(); // C = B C.ShiftLeft(2); // C = C * 4 C.ShiftLeft(1); // C = C * 2 } else if (A == 10) { C = B.Clone(); // C = B C.ShiftLeft(2); // C = C * 4 C = C + B; // C = C + B C.ShiftLeft(1); // C = C * 2 } else if (A == 16) { C = B.Clone(); // C = B C.ShiftLeft(2); // C = C * 4 C.ShiftLeft(2); // C = C * 4 } else { BigInt A1 = new BigInt(B.Size, A); _Mul(ref C, ref B, ref A1, B.Sign); } }
private static void _MulCell(ref BigInt C, ref BigInt B1, ulong A) { BigInt B1C = B1.Clone(); // C = B while (A > 1) { if (A % 16 == 0) { B1C.ShiftLeft(2); // C = C * 4 B1C.ShiftLeft(2); // C = C * 4 A = A / 16; } else if (A % 10 == 0) { B1C.ShiftLeft(2); // C = C * 4 B1C = B1C + B1; // C = C + B B1C.ShiftLeft(1); // C = C * 2 A = A / 10; } else if (A % 2 == 0) { B1C = B1.Clone(); B1C.ShiftLeft(1); A = A / 2; } else { // A is not a multiple of 2, 10 or 16 BigInt C1 = new BigInt(B1C.Size, 0); BigInt A1 = new BigInt(B1C.Size, A); _Mul(ref C1, ref B1C, ref A1, B1C.Sign); B1C = C1.Clone(); break; } } C = B1C.Clone(); }
public static BigInt operator %(BigInt B1, BigInt B2) { B2 = (BigInt)B1.SameSize(B2); BigInt B2Copy = B2.Clone(); BigInt Q = new BigInt(B2Copy.Size, 0); BigInt R = new BigInt(B2Copy.Size, 0); switch (B1.LookAtSign(B2Copy)) { case signt2.pp: _Divmod(ref Q, ref R, ref B1, ref B2Copy, signt.positive); break; case signt2.np: _Divmod(ref Q, ref R, ref B1, ref B2Copy, signt.negative); break; case signt2.pn: _Divmod(ref Q, ref R, ref B1, ref B2Copy, signt.negative); break; case signt2.nn: _Divmod(ref Q, ref R, ref B1, ref B2Copy, signt.positive); break; default: throw new Exception("Could not determine the sign of the result value."); } if (B1.Sign == signt.negative && R != 0) { BigInt RCopy = R.Clone(); RCopy.Sign = signt.negative; B2Copy.Sign = signt.positive; RCopy = RCopy + B2Copy; while (!(RCopy >= 0 && RCopy.Sign == signt.positive)) { RCopy = RCopy + B2Copy; } R = RCopy.Clone(); R.Sign = signt.positive; } return(R); }
private static void _DivCellMod(ref BigInt Q, ref BigInt R, BigInt B, uint DefaultBase, signt ResultSign) { uint[] Result = new uint[B.Size]; short ResultPos = 0; // First copy the Dividend (B) to the Remainder R B.Reduce(); R = B.Clone(); short Pos = (short)(R.Spart - 1); ulong Dividend = R.Value[Pos]; if (Dividend >= DefaultBase) { ulong LocalQuotient = Dividend / DefaultBase; Result[ResultPos++] = (uint)LocalQuotient; R.Value[Pos] = (uint)(Dividend % DefaultBase); } Pos--; while (Pos >= 0) { Dividend = ((ulong)R.Value[Pos + 1] << CELL_SIZE) + (ulong)R.Value[Pos]; ulong LocalQuotient = Dividend / DefaultBase; Result[ResultPos++] = (uint)LocalQuotient; R.Value[Pos + 1] = 0; R.Value[Pos--] = (uint)(Dividend % DefaultBase); } Q.Spart = ResultPos; int j = 0; for (int i = Q.Spart - 1; i >= 0; i--, j++) { Q.Value[j] = Result[i]; } for (; j < B.Size; j++) { Q.Value[j] = 0; } Q.Sign = ResultSign; Q.Reduce(); R.Reduce(); }
public static BigInt GetNextBlumPrime(BigInt Start, bool IsP = true, int Rounds = 20) { BigInt PNext = Start.Clone(); if (!IsP) { PNext = PNext + (PNext / 4) + 2; } //int PBitsCount = Start.BitsCount(); if (PNext.Even()) { PNext.Value[0] |= 0x01; } if (!PNext.IsProbablePrime(Rounds) || PNext % 4 != 3 || PNext == Start) { do { PNext += 2; }while (!PNext.IsProbablePrime(Rounds) || PNext % 4 != 3); } return(PNext); }
private static void _MulKara(ref BigInt C, ref BigInt B1, ref BigInt B2, signt ResultSign) { short B1Spart = B1.Spart; short B2Spart = B2.Spart; B1.Reduce(); B2.Reduce(); B2 = (BigInt)B1.SameSize(B2); C.Resize((short)(2 * B1.Spart + 1)); if (B1.Spart <= SPART_LIMIT || ((B1Spart < SPART_LIMIT && (B2Spart - B1Spart) > SPART_LIMIT) || (B2Spart < SPART_LIMIT && (B1Spart - B2Spart) > SPART_LIMIT))) { _Mul(ref C, ref B1, ref B2, ResultSign); } else { B1.Reduce(); B2.Reduce(); short Part = B1.Spart < B2.Spart ? (short)(B1.Spart / 2) : (short)(B2.Spart / 2); //short PartCopy = Part; //while (PartCopy != 0 && PartCopy < (B1.Spart < B2.Spart ? B1.Spart : B2.Spart) && CELL_SIZE % PartCopy != 0) //{ // PartCopy++; //} //if (PartCopy != 0 && CELL_SIZE % PartCopy == 0) //{ // Part = PartCopy; //} //else //{ // PartCopy = Part; // while (PartCopy > 0 && CELL_SIZE % PartCopy != 0) // { // PartCopy--; // } // Part = PartCopy; //} B2 = (BigInt)B1.SameSize(B2); BigInt D = new BigInt(B1.Size, 0), E = new BigInt(B1.Size, 0); BigInt F = new BigInt(B1.Size, 0), G = new BigInt(B1.Size, 0); BigInt Z0 = new BigInt(B1.Size, 0), Z1 = new BigInt(B1.Size, 0), Z2 = new BigInt(B1.Size, 0); // C := Z2 * (Base ^ (2 * Part)) + (Z1 - Z2 - Z0) * (Base ^ Part) + Z0 B1.Split(ref D, ref E, Part); B2.Split(ref F, ref G, Part); // K = D + E // L = F + G BigInt K = D + E; BigInt L = F + G; // Z0 := E*G // Z1 := K*L // Z2 := D*F _MulKara(ref Z0, ref E, ref G, ResultSign); _MulKara(ref Z1, ref K, ref L, ResultSign); _MulKara(ref Z2, ref D, ref F, ResultSign); Z0.Reduce(); Z1.Reduce(); Z2.Reduce(); // Z2Copy = Z2 * (Base ^ (2 * Part)) BigInt Z2Copy = Z2.Clone(); for (int i = 0; i < 2 * Part; i++) { // Z2 * Base // Base = 2 ^ CELL_SIZE Z2Copy.ShiftLeft(CELL_SIZE); } // (Z1 - Z2 - Z0) * (Base ^ Part) BigInt ZDiff = Z1 - Z2 - Z0; for (int i = 0; i < Part; i++) { // ZDiff * Base // Base = 2 ^ CELL_SIZE ZDiff.ShiftLeft(CELL_SIZE); } C = Z2Copy + ZDiff + Z0; C.Reduce(); } }
private string ToString(uint DefaultBase, bool Fill = true, OutputFormat OutType = OutputFormat.hex) { if (DefaultBase < 2 || DefaultBase > 16) { throw new ArgumentOutOfRangeException("Provided argument DefaultBase is out of range."); } string HString = "0123456789ABCDEF"; string Result = ""; BigInt B = this.Clone(); BigInt Quotient = new BigInt(this.Size, 0); BigInt Remainder = new BigInt(this.Size, 0); if (B.Spart == 1 && B.Value[0] == 0) { Result = "0"; } else { while (B.Spart > 1 || (B.Spart == 1 && B.Value[0] != 0)) { _DivCellMod(ref Quotient, ref Remainder, B, DefaultBase, B.Sign); if (Remainder.Value[0] < 10) { Result = Remainder.Value[0] + Result; } else { Result = HString[(int)(Remainder.Value[0])] + Result; } B = Quotient.Clone(); } } // Fill the result with 000... based on size if (Fill) { int ResultSize = this.Size / 4 - Result.Length; while (ResultSize > 0) { Result = "0" + Result; ResultSize--; } } else if (Result.Length == 0) { Result = "0"; } if (DefaultBase == 8) { Result = this.Sign == signt.positive ? $"+0o{Result}" : $"-0o{Result}"; } else if (DefaultBase == 10) { Result = this.Sign == signt.positive ? $"+{Result}" : $"-{Result}"; } else if (DefaultBase == 16) { Result = this.Sign == signt.positive ? $"+0x{Result}" : $"-0x{Result}"; } return(Result); }