public class PrimeNumber
{
//判断是否是素数(大于3的质数都分布在6的倍数的两侧)
public static bool IsPrime(long num)
{
if (num < 2)
return false;
//两个较小数另外处理
if (num == 2 || num == 3)
return true;
//不在6的倍数两侧的一定不是质数
if (num % 6 != 1 && num % 6 != 5)
return false;
//如果不是素数必定有一个小于等于自身平方根的因子
long tmp = (long)Math.Sqrt(num);
//剩下的都是在6的倍数两侧的数,也可能不是质数,能被6的倍数两侧的奇数整除必定不是素数
for (long i = 5; i <= tmp; i += 6)
if (num % i == 0 || num % (i + 2) == 0)
return false;
//排除所有,剩余的是质数
return true;
}
//获取小于等于max的素数列表
public static List<long> GetPrimeNumber(long max)
{
List<long> nums = new List<long>();
if (max > 1)
nums.Add(2);
if (max > 2)
nums.Add(3);
if (max < 5) return nums;
//大于等于5的素数都分布在6的倍数的两边
for (int i = 5; i <= max; i += 6)
{
if (IsPrime_6_(i))
nums.Add(i);
if (i + 2 <= max && IsPrime_6_(i + 2))
nums.Add(i + 2);
}
return nums;
}
//判断6的倍数两侧的数是否是素数
public static bool IsPrime_6_(long num)
{
long tmp = (long)Math.Sqrt(num);
for (int j = 5; j <= tmp; j += 6)
if (num % j == 0 || num % (j + 2) == 0)
return false;
return true;
}
//获取大于指定数的第一个素数
public static long GetNextPrime(long min)
{
if (min < 2) return 2;
if (min == 2) return 3;
//找出大于等于min的6的倍数
long m = min % 6;
long n = m == 0 ? min : min - m + 6;
while (true)
{
if (n - 1 > min && IsPrime_6_(n - 1))
return n - 1;
if (IsPrime_6_(n + 1))
return n + 1;
n += 6;
}
}
}