Nadesłany przez Tomasz Lubiński, 26 kwietnia 2007 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
miller_rabin_cs/Miller_Rabin.cs:
// Test pierwszości - test Millera-Rabina
// www.algorytm.org
// Tomasz Lubinski (c) 2007
using System;
namespace miller_rabin_cs
{
/// <summary>
/// Miller-Rabin test
/// </summary>
class Miller_Rabin
{
private static int [] powerOf2 = {
1<<0, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6,
1<<7, 1<<8, 1<<9, 1<<10, 1<<11, 1<<12, 1<<13,
1<<14, 1<<15, 1<<16, 1<<17, 1<<18, 1<<19, 1<<20,
1<<21, 1<<22, 1<<23, 1<<24, 1<<25, 1<<26, 1<<27,
1<<28, 1<<29, 1<<30 };
/// <summary>
/// calculates a^b mod m
/// </summary>
/// <param name="a">a</param>
/// <param name="b">b</param>
/// <param name="m">m</param>
/// <returns>a^b mod m</returns>
private static int power_modulo_fast(int a, int b, int m)
{
int i;
long result = 1;
long x = a%m;
for (i=1; i<=b; i<<=1)
{
x %= m;
if ((b&i) != 0)
{
result *= x;
result %= m;
}
x *= x;
}
return (int)result;
}
/// <summary>
/// Miller-Rabin test
/// </summary>
/// <param name="n">number to check</param>
/// <param name="k">number of checks</param>
/// <returns>true - probably prime, false - not prime</returns>
private static Boolean MillerRabin(int n, int k)
{
int s = 0;
int s2 = 1;
int a, d, i, r, prime;
Random rand = new Random();
if (n<4)
{
return true;
}
if (n%2 == 0)
{
return false;
}
// calculate s and d
while ((s2 & (n-1)) == 0)
{
s += 1;
s2 <<= 1;
}
d = n/s2;
// try k times
for (i=0; i<k; i++)
{
a = rand.Next(n-1) + 1;
if (power_modulo_fast(a, d, n) != 1)
{
prime = 0;
for (r=0; r<=s-1; r++)
{
if (power_modulo_fast(a, powerOf2[r]*d, n) == n - 1)
{
prime = 1;
break;
}
}
if (prime == 0)
{
return false;
}
}
}
return true;
}
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
int n, k;
Console.WriteLine("Podaj liczbe do sprawdzenia.");
n = int.Parse(Console.ReadLine());
Console.WriteLine("Podaj dokladnosc sprawdzenia.");
k = int.Parse(Console.ReadLine());
if (MillerRabin(n, k))
{
Console.WriteLine("Liczba jest prawdopodobnie pierwsza.");
}
else
{
Console.WriteLine("Liczba jest zlozona.");
}
}
}
}

