いくつかの素数関連のメソッドを含む小さなライブラリを作成しています。私は基礎(別名作業方法)を行ったので、今はいくつかの最適化を探しています。もちろん、インターネットはそうするのに最適な場所です。しかし、丸めの問題に遭遇し、これを解決する方法を考えていました。
数の素数をテストするために使用するループでは、n/2 または n - 1 の代わりに sqrt(n) まで検索する方が効率的です。たとえば、10000 番目の素数は 104729 のはずですが、「最適化された」バージョンは 103811 になります。
いくつかのコード (より多くの最適化のために開いていることは知っていますが、一度に 1 つのことしか処理できません):
/// <summary>
/// Method for testing the primality of a number e.g.: return IsPrime(29);
/// History:
/// 1. Initial version, most basic form of testing: m smaller then n -1
/// 2. Implemented m smaller then sqrt(n), optimization due to prime factoring
/// </summary>
/// <param name="test">Number to be tested on primality</param>
/// <returns>True if the number is prime, false otherwise</returns>
public static bool IsPrime(int test)
{
// 0 and 1 are not prime numbers
if (test == 0 || test == 1) return false;
// 2 and 3 are prime numbers
if (test == 2) return true;
// all even numbers, save 2, are not prime
if (test % 2 == 0) return false;
double squared = Math.Sqrt(test);
int flooredAndSquared = Convert.ToInt32(Math.Floor(squared));
// start with 5, make increments of 2, even numbers do not need to be tested
for (int idx = 3; idx < flooredAndSquared; idx++)
{
if (test % idx == 0)
{
return false;
}
}
return true;
}
2乗部分が失敗する(または失敗する)ことを知っており、Math.Ceilingも試してみましたが、ほぼ同じ結果が得られました。