Consider this method that works well:
public static bool mightBePrime(int N) {
BigInteger a = rGen.Next (1, N-1);
return modExp (a, N - 1, N) == 1;
}
-
Here's an alternate way to generate numbers within range without throwing away values and allowing BigIntegers for min and max.
public BigInteger RandomBigInteger(BigInteger min, BigInteger max)
{
Random rnd = new Random();
string numeratorString, denominatorString;
double fraction = rnd.NextDouble();
BigInteger inRange;
//Maintain all 17 digits of precision,
//but remove the leading zero and the decimal point;
numeratorString = fraction.ToString("G17").Remove(0, 2);
//Use the length instead of 17 in case the random
//fraction ends with one or more zeros
denominatorString = string.Format("1E{0}", numeratorString.Length);
inRange = (max - min) * BigInteger.Parse(numeratorString) /
BigInteger.Parse(denominatorString,
System.Globalization.NumberStyles.AllowExponent)
+ min;
return inRange;
}
For generality you may want to specify precision as well. This seems to work.
public BigInteger RandomBigIntegerInRange(BigInteger min, BigInteger max, int precision)
{
Random rnd = new Random();
string numeratorString, denominatorString;
double fraction = rnd.NextDouble();
BigInteger inRange;
numeratorString = GenerateNumeratorWithSpecifiedPrecision(precision);
denominatorString = string.Format("1E{0}", numeratorString.Length);
inRange = (max - min) * BigInteger.Parse(numeratorString) / BigInteger.Parse(denominatorString, System.Globalization.NumberStyles.AllowExponent) + min;
return inRange;
}
private string GenerateNumeratorWithSpecifiedPrecision(int precision)
{
Random rnd = new Random();
string answer = string.Empty;
while(answer.Length < precision)
{
answer += rnd.NextDouble().ToString("G17").Remove(0, 2);
}
if (answer.Length > precision) //Most likely
{
answer = answer.Substring(0, precision);
}
return answer;
}
- 热议问题