algorytm.org

Implementacja w C#

Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Test pierwszości - test Millera-Rabina - Implementacja w C#
Ocena użytkownikóww: *****  / 3
SłabyŚwietny
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.");
		   }
		}
	}
}
Dodaj komentarz