private BigInteger GetHigherPrime(BigInteger value) { if (value < Consts.BI2P64) { ulong ret = Prime53.GetHigherPrime(Common.ToULong(value)); if (ret != 0) { return(ret); } //value = Consts.BI2P64 - 1; value = Consts.BI2P64; // 2^64 is not prime } for (; ;) //while (value < Consts.BI2P4096_1) // 2^4096-1 is not prime { value++; if (PrimeUtils.IsPrime(value)) { return(value); } if (Ground.IsStopped()) { break; } } return(0); }
private static BigInteger GetPrimeCount_BIBI(BigInteger minval, BigInteger maxval, Func <double, double> rateFltr) { BigInteger count = 0; for (BigInteger value = minval; ; value++) { if (PrimeUtils.IsPrime(value)) { count++; { int permil = (int)(((value - minval) * 1000) / (maxval - minval)); double rate = permil / 1000.0; Common.Report(rateFltr(rate), value); } GC.Collect(); } if (value == maxval) { break; } if (Ground.IsStopped()) { break; // 中止 } } return(count); }
private static void FindPrimes_BIBI(BigInteger minval, BigInteger maxval, string outFile, Func <double, double> rateFltr) { using (FileStream writer = new FileStream(outFile, FileMode.Append, FileAccess.Write)) { for (BigInteger value = minval; ; value++) { if (PrimeUtils.IsPrime(value)) { FileTools.Write(writer, Encoding.ASCII.GetBytes(Common.ToString(value))); writer.WriteByte(0x0a); // '\n' { int permil = (int)(((value - minval) * 1000) / (maxval - minval)); double rate = permil / 1000.0; Common.Report(rateFltr(rate), value); } GC.Collect(); } if (value == maxval) { break; } if (Ground.IsStopped()) { FileTools.Write(writer, Encoding.ASCII.GetBytes("ABORTED - Prime4096\n")); break; // 中止 } } } }
// memo: // value の最小の素因数が p のとき、ランダムに選ばれた r が p の倍数である確率は 1/p また p 以外の約数も発見出来る可能性がある。 // なので、たかだか平均 p 回のトライで約数を発見出来る。 // -- 合成数のとき更に素因数分解する必要がある。処理速度に貢献していないじゃないか? // -- 愚直に 2, 3, 5, 7, 9, ... と割って試していく方法の方が速いんじゃないか? <-- トライ毎に FF_GCD() に比べ 1回の剰余で済む。 private static BigInteger FindFactor(BigInteger value) { if (Ground.IsStopped()) { throw new Cancelled(); } if (value < 2) { throw null; // bugged !!! } if (value <= 3) // 2, 3 are prime { goto retired; } int valueScale = BigIntegerUtils.GetByteArrayLength(value); if (valueScale < 1) { throw null; // souteigai !!! } for (int c = 0; c < 1000; c++) { // ここからトライ BigInteger r; if (valueScale < 100) { r = new BigInteger(BinTools.Join(new byte[][] { SecurityTools.CRandom.GetBytes(valueScale + 10), new byte[] { 0x00 } })) % (value - 2) + 2; // 2 ~ (value - 1) } else { r = new BigInteger(BinTools.Join(new byte[][] { SecurityTools.CRandom.GetBytes(valueScale / 2 + 10), new byte[] { 0x00 } })) + 2; // 2 ~ (about_sqrt(value)) } BigInteger f = FF_GCD(value, r); if (f != 1) { return(f); // トライ成功 } // トライ失敗 } retired: throw new FF_Retired(); }
private BigInteger GetLowerPrime(BigInteger value) { while (Consts.BI2P64 <= value) { value--; if (PrimeUtils.IsPrime(value)) { return(value); } if (Ground.IsStopped()) { return(0); } } return(Prime53.GetLowerPrime(Common.ToULong(value))); }
public static void FindPrimes(BigInteger minval, BigInteger maxval, string outFile) { FileTools.Delete(outFile); if (maxval < minval) { throw new Exception("maxval < minval"); } if (minval < Consts.BI2P64) { if (maxval < Consts.BI2P64) { Prime53.FindPrimes(Common.ToULong(minval), Common.ToULong(maxval), outFile, () => Ground.IsStopped() == false); } else { Prime53.FindPrimes(Common.ToULong(minval), ulong.MaxValue, outFile, () => Ground.IsStopped() == false); FindPrimes_BIBI(Consts.BI2P64, maxval, outFile, rate => 0.5 + rate * 0.5); } } else { FindPrimes_BIBI(minval, maxval, outFile, rate => rate); } }
public static BigInteger GetPrimeCount(BigInteger minval, BigInteger maxval) { BigInteger count; if (maxval < minval) { throw new Exception("maxval < minval"); } if (minval < Consts.BI2P64) { if (maxval < Consts.BI2P64) { count = Prime53.GetPrimeCount(Common.ToULong(minval), Common.ToULong(maxval), () => Ground.IsStopped() == false); } else { count = Prime53.GetPrimeCount(Common.ToULong(minval), ulong.MaxValue, () => Ground.IsStopped() == false); count += GetPrimeCount_BIBI(Consts.BI2P64, maxval, rate => 0.5 + rate * 0.5); } } else { count = GetPrimeCount_BIBI(minval, maxval, rate => rate); } return(count); }