internal RawNum Sqrt(RawNum left) { m_targetSquare = left; m_targetSquareNum = m_targetSquare.OmgWrapper(); m_rootAprox = OmgPool.GetRawZero(); m_buffer = OmgPool.GetRawZero(); _FillInitialApproximation(); while (!_AproxEqualToBuffer()) { var aproxCopy = OmgPool.GetRawZero(); aproxCopy.CopyFrom(m_rootAprox); var bufferCopy = OmgPool.GetRawZero(); bufferCopy.CopyFrom(m_buffer); _MakeGeronIteration(); if (OmgOp.Equal(aproxCopy.OmgWrapper(), m_buffer.OmgWrapper()) && OmgOp.Equal(bufferCopy.OmgWrapper(), m_rootAprox.OmgWrapper()) && OmgOp.Less(m_rootAprox.OmgWrapper(), m_buffer.OmgWrapper())) { break; } OmgPool.ReleaseNumber(bufferCopy); OmgPool.ReleaseNumber(aproxCopy); } OmgPool.ReleaseNumber(m_buffer); return(m_rootAprox); }
public (OmgNum div, OmgNum mod) DivMod(OmgNum left, OmgNum right) { _InitializeDivModResult(); if (OmgOp.Equal(right, s_two)) { _DivModByTwo(left); return(m_divRes, m_modRes); } bool isNegative = left.IsNegative != right.IsNegative; m_divRes.IsNegative = isNegative; _FindDivModSolution(left.Raw, right.Raw); if (isNegative) { m_divRaw.Inc(); _Subtract(right.Raw, m_modRaw); } _RemoveModLeadingZeros(); return(m_divRes, m_modRes); }
private bool _MakeTest(OmgNum testBase) { OmgNum numDec = (new OmgNum(m_tested)).Dec(); OmgNum tested = OmgOp.Pow(testBase, m_initialTested, m_tested); OmgNum iterationsLeft = new OmgNum(m_powerOfTwo); try { if (OmgOp.Equal(tested, OmgNum.GetConst(1)) || OmgOp.Equal(tested, numDec)) { return(true); } while (!iterationsLeft.IsZero()) { iterationsLeft.Dec(); var nwTested = OmgOp.Multiply(tested, tested, m_tested); tested.Release(); tested = nwTested; if (OmgOp.Equal(tested, numDec)) { return(true); } } return(false); } finally { numDec.Release(); tested.Release(); iterationsLeft.Release(); } }
private OmgNum _FermaFactorization(Dictionary <OmgNum, OmgNum> result, OmgNum num) { OmgNum factor = null; if (OmgOp.DivMod(num, 2.ToOmgNum()).mod.IsZero()) { factor = 2.ToOmgNum(); } if (factor == null) { OmgNum a = OmgOp.Sqrt(num); OmgNum aSq = OmgOp.Multiply(a, a); bool isSquare = OmgOp.Equal(num, aSq); if (isSquare) { factor = a; } a.Inc(); aSq = OmgOp.Multiply(a, a); var s = OmgOp.Subtract(aSq, num); while (factor == null) { var testSqrt = OmgOp.Sqrt(s); if (OmgOp.Equal(s, OmgOp.Multiply(testSqrt, testSqrt))) { factor = (OmgOp.Equal(testSqrt, a)) ? OmgOp.Add(a, a) : OmgOp.Subtract(a, testSqrt); break; } a.Inc(); aSq = OmgOp.Multiply(a, a); s = OmgOp.Subtract(aSq, num); } } if (factor == null || factor.IsOne()) { return(num); } OmgNum pow = _FindPow(ref num, factor); if (result.ContainsKey(factor)) { result[factor] = OmgOp.Add(result[factor], pow); } else { result[factor] = pow; } return(num); }
private bool _IsSmallPrime(Dictionary <OmgNum, OmgNum> result, OmgNum num) { smallPrimesOmg ??= smallPrimes.Select(x => x.ToOmgNum()).ToArray(); foreach (var prime in smallPrimesOmg) { if (OmgOp.Equal(prime, num)) { result[prime] = 1.ToOmgNum(); return(true); } } return(false); }
public OmgNum FindFactor(OmgNum n, int maxIterations = -1) { m_iterations = 0; m_current = n; OmgNum x = OmgOp.Random(1.ToOmgNum(), OmgOp.Subtract(n, 2.ToOmgNum())); OmgNum y = 1.ToOmgNum(); OmgNum i = 0.ToOmgNum(); OmgNum stage = 2.ToOmgNum(); OmgNum sub = OmgOp.Subtract(x, y).MakeAbs(); OmgNum gcd = OmgOp.Gcd(n, sub); sub.Release(); while (gcd.IsOne()) { if (maxIterations >= 0 && m_iterations++ > maxIterations) { return(null); } if (OmgOp.Equal(i, stage)) { y.Release(); y = new OmgNum(x); stage.MultByTwo(); } OmgNum xSquare = OmgOp.Multiply(x, x).Inc(); x.Release(); x = OmgOp.Mod(xSquare, n); xSquare.Release(); i.Inc(); sub = OmgOp.Subtract(x, y).MakeAbs(); gcd.Release(); gcd = OmgOp.Gcd(n, sub); sub.Release(); } return(gcd); }
private OmgNum _FindFactorsWithPollard(Dictionary <OmgNum, OmgNum> result, OmgNum num) { num = num.Copy(); while (!num.IsOne()) { OmgNum factor = m_polard.FindFactor(num, maxIterations: 100000); if (factor == null || factor.IsOne() || OmgOp.Equal(factor, num)) { return(num); } OmgNum pow = _FindPow(ref num, factor); result[factor] = pow; } return(num); }
public bool IsPrime(OmgNum tested) { foreach (var prime in s_smallPrimes) { if (OmgOp.Less(tested, prime) || OmgOp.Equal(tested, prime)) { return(true); } var mod = OmgOp.Mod(tested, prime); bool isComposite = mod.IsZero(); mod.Release(); if (isComposite) { return(false); } } return(true); }
private bool _AproxEqualToBuffer() { return(OmgOp.Equal(m_rootAprox.OmgWrapper(), m_buffer.OmgWrapper())); }