Feedback

Veröffentlicht von am 15.10.2006
(1 Bewertungen)
Ermittelt Primzahlen durch Anwendung des Siebes des Eratosthenes und speichert diese in einer Datei. Dies kann auch automatisch in einem Hintergrund-Thread geschehen.
GFU-Schulungen  [Anzeige]

C# 2017/2015/2013 Aufbau

In dieser Schulung lernen Sie fortgeschrittene Techniken im Bereich .Net C#. Dabei stehen neben den eigentlichen Techniken auch architektonische Aspekte im Mittelpunkt.

Visual Studio Team Foundation Server 2017/2015 (TFS) für Projektmitglieder - Kompakt

Nach Teilnahme an dieser Schulung sind Ihnen die Grundlagen von ALM geläufig. Sie planen und steuern Projekte effizient mit dem Visual Studio Team Foundation Server.

```using System;
using System.Text;
using System.IO;
using System.Diagnostics;

/// <summary>
/// A static class for generating prime numbers
/// Calculated prime numbers are stored in a binary file
/// </summary>
/// <remarks>
/// Usage:
///
/// static void Main(string[] args)
/// {
///    ...
///    run your program as usual
///    ...
/// }
/// </remarks>
{
/// <summary>
/// Returns the greatest prime number found in the file
/// </summary>
{
get
{
if (File.Exists(PrimeDatabaseFileName))
{
long buf;
{
// seek to the last long
// read the last long, it's the last found prime number
// close
}
return buf;
}
else
{
return 1;
}
}
}
// how many numbers are tested in each run of Eratosthenes()
private static long _NumbersToTest = 100000;
/// <summary>
/// Minimum value for NumbersToTest
/// </summary>
public const long MinNumbersToTest = 1000;
/// <summary>
/// Maximum value for NumbersToTest
/// </summary>
public const long MaxNumbersToTest = 1000000000;
/// <summary>
/// Get/set the count of numbers to test in a run of Eratosthenes()
/// <para>The value is automatically corrected to be in the bounds given by MinNimbersToTest and MaxNumbersToTest</para>
/// </summary>
public static long NumbersToTest
{
get
{
return _NumbersToTest;
}
set
{
// TODO: enter code setting bounds to this value
if (value < MinNumbersToTest)
{
_NumbersToTest = MinNumbersToTest;
}
else
{
if (value > MaxNumbersToTest)
{
_NumbersToTest = MaxNumbersToTest;
}
else
{
_NumbersToTest = value;
}
}
}
}
// true if Eratosthenes() is running as background thread
private static bool RunThreaded = false;
private static string _FileName;
/// <summary>
/// The name of the file in which the prime numbers are stored
/// </summary>
public static string PrimeDatabaseFileName
{
get { return _FileName; }
set
{
{
_FileName = value;
}
else
{
throw new InvalidOperationException("Stop generator using StopBackgoundPNG() first");
}
}
}
/// <summary>
/// Initializes the prime number generator with a default filename
/// <para>FileName = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\PrimeNumberDatabase.bin";</para>
/// </summary>
{
}
/// <summary>
/// Tests NumberToTest numbers for prime and saves found primes to PrimeDatabaseFileName
/// </summary>
public static void Eratosthenes()
{
// do at least once
do
{
// file access variables
BinaryWriter writer = null;
// we do not need any exception here
try
{
// every number to test is an element in this array
bool[] Zahlen = new bool[NumbersToTest];
// initializes the array to false meaning the number is prime
Zahlen.Initialize();
// initialize last found prime number with 1
// although 1 is not a prime number it is necessary here
// anyway, algorithm starts by successor
// is prime number file existing?
if (File.Exists(PrimeDatabaseFileName))
{
// if yes:
// seek to the last long
// read the last long, it's the last found prime number
// seek back to beginning
}
#if DEBUG
Debug.WriteLine("last found prime number is " + LastFoundPrimeNumber.ToString());
Debug.WriteLine("looking for primes lower than " + ((long)(LastFoundPrimeNumber + NumbersToTest)).ToString());
#endif
// first number to be test
// this is the number represented by Zahlen
long ZIB = LastFoundPrimeNumber + 1;
// calc last number which multiples must be tested
long MaxSieb = Convert.ToInt64(Math.Ceiling(Math.Sqrt(LastFoundPrimeNumber + NumbersToTest)));
// the number of which multiples are beeing eliminated
long AktSieb = 0;
// if we have to look up prime numbers in Zahlen
// start at this index
long StartIndex = 0;
// repeat until all multiples of all primes lower than MaxSieb are eliminated
do
{
// current index
long SuchIndex = StartIndex;
// test, where the next prime number can be retrieved
// it has to be taken from file if
// -ZIB is greater than 2 (meaning that are already prime numbers in the file)
// -and current prime (AktSieb) is lower than the greatest prime in file
// -and there is actually a file opened
if ((ZIB > 2) && (AktSieb < LastFoundPrimeNumber) && (reader != null))
{
do
{
}
// until the number is greater than the current prime number
// or end of file
// current prime number is the loaded
AktSieb = SuchIndex;
#if DEBUG
Debug.WriteLine("prime number loaded from file: " + AktSieb.ToString());
#endif
}
else
{
// find in Zahlen
// find first element that is not true (meaning it is not a multiple of any prime number)
while (Zahlen[SuchIndex] == true)
{
SuchIndex++;
}
// current prime number is the number represented bei Zahlen[SuchIndex]
// (remember: ZIB is the number represented by Zahlen)
AktSieb = SuchIndex + ZIB;
#if DEBUG
Debug.WriteLine("prime number found in current list: " + AktSieb.ToString());
#endif
}
#if DEBUG
Debug.WriteLine("now eliminating multiples of " + AktSieb.ToString() + " in current block");
#endif
// find next multiple of the current prime
// repeat if the multiple is in the current block
while (Sieb < (LastFoundPrimeNumber + NumbersToTest + 1))
{
// do not "unprime" the prime itself
if (Sieb != AktSieb)
{
// "unprime" the multiple
Zahlen[Sieb - ZIB] = true;
}
// elevate to next mutliple
Sieb += AktSieb;
}
#if DEBUG
Debug.WriteLine("elimination finished");
#endif
// elevate look up start point for next loop
StartIndex++;
}
// loop until we have checked all possible primes
while (AktSieb <= MaxSieb);

// if there is input file
{
// close it
// and null it for next loop
}

// write data to file (append)
writer = new BinaryWriter(new FileStream(PrimeDatabaseFileName, FileMode.Append, FileAccess.Write, FileShare.ReadWrite));
// loop all elements of Zahlen
for (long i = 0; i < Convert.ToInt64(Zahlen.LongLength); i++)
{
// false is meaning that the number has not been multiple of anything
// so it is prime
if (Zahlen[i] == false)
{
// write it to file
// remember: ZIB is the number represented by Zahlen
writer.Write(((long)(ZIB + i)));
}
}
}
// if we encounter any exception above
// we have to make sure, all files are closed before the next loop
finally
{
// is input file existing
{
// close it
// null it for next loop
}
// same for output file
if (writer != null)
{
writer.Flush();
writer.Close();
writer = null;
}
}
}
// repeat this if running as background thread

}

/// <summary>
/// Signals the generator to stop after next loop
/// </summary>
public static void EndBackgroundPNG()
{
}

/// <summary>
/// Immediately stops a running background prime number generator
/// </summary>
public static void StopBackgroundPNG()
{
// if there is no thread return
{
return;
}
// if this is false Eratosthenes() will not loop
// raise exception in Eratosthenes()
// wait until Eratosthenes() closes all files
}

/// <summary>
/// starts the prime number generator to run in the background
/// </summary>
public static void StartBackgroundPNG()
{
{
return;
}
// inform Eratosthenes() about running continuosly
// it's only a background thread (will be aborted if main threads end)