Zum Inhalt springen

Die Software unterliegt der GNU GENERAL PUBLIC LICENSE.

Die Software ist in C geschrieben. Sie stellt ein Schnittstelle ähnlich von Pseudozufallszahlengeneratoren zur Verfügung, um einen unkomplizierten Einsatz in schon vorhandene Programme zu ermöglichen. Für Windows wird die Software zusätzlich als Dll ausgeliefert, um sie leichter in die verschiedensten Entwicklungsumgebungen bzw. Programmiersprachen integrieren zu können. Zur Erzeugung grössere Mengen von Zufallszahlen wurde Puran2 mit einem Tausworthegenerator kombiniert. Der Tausworthegenerator stellt unter den Pseudozufallszahlengeneratoren einen guten Generator dar. Er generiert die Zufallszahlen mit Hilfe eines Schieberegisters, welches hier 159 Bit lang ist. Unter der Voraussetzung, das nicht alle Initialwerte 0 sind erlangt der Tausworthegenerator  eine Sequenzlänge von 2159 – 1. Eine genauere Beschreibung ist hier [7] zu finden. Um seine Schwächen zu mildern bzw. zu beseitigen werden der Tausworthegenerator und Puran2 mit einer exklusive Oder Operation verknüpft.

Beschreibung der Funktionen von Puran2

  • int puran2_init(char *filename, int wrap)
    Die Funktion initialisiert Puran2. Als filename wird der Name des Files übergeben, die die Zufallsbits inklusive der Paritybits enthält. Falls wrap <> 0 ist wird beim erreichen des Dateiendes wieder am Anfang der Datei begonnen zu lesen. Diese Funktion muss als erste Funktion aufgerufen werden, um die nachfolgenden Funktionen benutzen zu können.

    Als Rückgabewerte gibt es folgende Möglichkeiten:
0Puran2 wurde initialisiert
-1Es ist ein Fehler aufgetreten
  • int puran2_get_errornum()
    Die Funktion gibt den letzten Fehlercode zurück. Mögliche Werte sind dabei:
0Ok
-1Fehler während der Initialisierung.
-2Puran2 nicht initialisiert.
-3Position beim seek kleiner 0 oder grösser als die Dateilänge.
-4Position beim seek konnte nicht ereicht werden. Möglicher Fehler ist eine defekte Datei.
-5Es wurde das Dateiende erreicht.
-6Es konnte kein gesammter Block mehr gelesen werden.
-7Es ist ein Parityfehler aufgetreten. Die Puran2 Datei ist defekt und darf nicht mehr verwendet werden.
  • char *puran2_get_error()
    Die Funktion gibt eine Beschreibung des letzten Fehlers als Text zurück. Der Rückgabewert darf nicht verändert oder frei gegeben werden.
  • void puran2_stop()
    Die Funktion schliesst die Puran2 Daten
  • int puran2_seek(long pos)
    Mit dieser Funktion kann ein anderer Startpunkt innerhalb der Datei angesprungen werden. Die Position wird relative zum Anfang der Datei angegeben. Als Rückgabewerte gibt es folgende Möglichkeiten:
posWenn die gewüschte Position zurückgeben wird wurde die Funktion korrekt ausgeführt.
-2Puran2 ist nicht initialisiert
-3pos ist kleiner 0 oder grösser als die Datei
-4Bei Positionieren ist ein sonstiger Fehler aufgetreten.
  • unsigned long puran2_random()
    Es wird eine Zufallszahl zwischen 0 und 232– 1 erzeugt. Falls ein Fehler auftritt wird 0 zurückgegeben. Es sollte daher nach jedem Aufruf der Fehlercode geprüft werden.
  • long puran2_long()
    Es wird eine Zufallszahl zwischen 0 und 231– 1 erzeugt indem tausworthe_random mit 0x7fffffff maskiert wird.

Beschreibung der Funktionen des Tausworthe Generators

  • void tausworthe_init(unsigned long i0, unsigned long i1, unsigned long i2, unsigned long i3, unsigned longi4)
    Die Funktion initialiert den Generator.
  • unsigned long tausworthe_random()
    Es wird eine Zufallszahl zwischen 0 und 232– 1 erzeugt.
  • long tausworthe_long()
    Es wird eine Zufallszahl zwischen 0 und 231– 1 erzeugt indem tausworthe_random mit 0x7fffffff maskiert wird.
  • unsigned long tausworthe_puran2_random()
    Es wird eine Zufallszahl zwischen 0 und 232– 1 erzeugt indem die Zufallszahl aus tausworthe_random mit der Zufallzahl von puran2_random mittles einer Exklusivoder Operation verknüpft und ausgegeben wird.
  • long tausworthe_puran2_long()
    Es wird eine Zufallszahl zwischen 0 und 231– 1 aus tausworthe_puran2_random erzeugt.

Beispielprogramm

#include <stdlib.h>
#include <stdio.h>

#ifdef CYGWIN

#include <windows.h>

typedef unsigned int   (*RANDOM)(void);
typedef unsigned int   (*RANDOMLONG)(void);

typedef int   (*PURAN2INIT)(char *, int);
typedef void  (*PURAN2STOP)(void);
typedef int   (*PURAN2SEEK)(long);
typedef char* (*PURAN2ERROR)(void);

typedef void          (*TAUSWORTHEINIT)(unsigned long i0, unsigned long i1, unsigned long i2, unsigned long i3, unsigned long i4);

PURAN2INIT   puran2_init;
PURAN2STOP   puran2_stop;
PURAN2SEEK   puran2_seek;
PURAN2ERROR  puran2_get_error;

TAUSWORTHEINIT   tausworthe_init;

RANDOM puran2_random;
RANDOMLONG puran2_long;

RANDOM tausworthe_random;
RANDOM tausworthe_puran2_random;

RANDOMLONG tausworthe_long;
RANDOMLONG tausworthe_puran2_long;

void init_dll()
{
    HINSTANCE dll;

    dll = LoadLibrary("mnerandom");
    if ( dll == NULL )
    {
        fprintf(stderr,"can't load mnerandom");
        exit(1);
    }

    puran2_init      = (PURAN2INIT)GetProcAddress(dll,"puran2_init");
    puran2_stop      = (PURAN2STOP)GetProcAddress(dll,"puran2_stop");
    puran2_random    = (RANDOM)GetProcAddress(dll,"puran2_random");
    puran2_long      = (RANDOMLONG)GetProcAddress(dll,"puran2_long");
    puran2_seek      = (PURAN2SEEK)GetProcAddress(dll,"puran2_seek");
    puran2_get_error = (PURAN2ERROR)GetProcAddress(dll,"puran2_get_error");

    if ( puran2_init      == NULL ||
         puran2_stop      == NULL ||
         puran2_random    == NULL ||
         puran2_long      == NULL ||
         puran2_seek      == NULL ||
         puran2_get_error == NULL )
    {
        fprintf(stderr,"can't load all function for puran2\n");
        FreeLibrary(dll);
        exit(2);
    }

    tausworthe_init             = (TAUSWORTHEINIT)GetProcAddress(dll,"tausworthe_init");
    tausworthe_random           = (RANDOM)GetProcAddress(dll,"tausworthe_random");
    tausworthe_puran2_random    = (RANDOM)GetProcAddress(dll,"tausworthe_puran2_random");
    tausworthe_long             = (RANDOMLONG)GetProcAddress(dll,"tausworthe_long");
    tausworthe_puran2_long      = (RANDOMLONG)GetProcAddress(dll,"tausworthe_puran2_long");

    if ( tausworthe_init      == NULL ||
    	 tausworthe_random    == NULL ||
    	 tausworthe_long      == NULL ||
    	 tausworthe_puran2_random  == NULL ||
    	 tausworthe_puran2_long  == NULL )
    {
        fprintf(stderr,"can't load all function for tausworthe\n");
        FreeLibrary(dll);
        exit(2);
    }
}
#else
#include <random/tausworthe.h>
#include <random/puran2.h>
void init_dll() {}
#endif

int main(int argc, char* argv[])
{
     int i, j, k;
     double m,mg, mgg;
     
     if ( argc < 3 )
     {
         fprintf(stderr, "usage puran2example <datei> <seek>\n");
         exit(3);
     }

     init_dll();

     if ( puran2_init(argv[1], 1) < 0 )
     {
         fprintf(stderr, "%s\n", puran2_get_error());
         exit(4);
      }

     puran2_seek(atol(argv[2]));
	 tausworthe_init(puran2_random(), puran2_random(), puran2_random(),
				     puran2_random(), puran2_random());
     

    mgg = mg = k = 0;
 	while ( 1)
	{
		for (j=0; j<1000; j++)

		{
			for (m=0, i=0; i< 100; i++)
				m += (tausworthe_puran2_long() )
						/(double)0x7fffffff;
			mg += m / 100.0;
			m = 0;
		}

		mgg += mg / 1000.0;
		k++;
		fprintf(stderr, "mittel: %f %f\n", mgg / k, mg / 1000);
		mg = 0;
	}
    puran2_stop();
	exit(0);

     return ( 0 );
}