Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: 64-Bit random numbers

Author: Vincent Diepeveen

Date: 18:29:18 10/28/03

Go up one level in this thread


On October 28, 2003 at 17:55:14, Reinhard Scharnagl wrote:

>Hi,
>
>because 64-bit random numbers mostly will be split into an address-part
>and a key part, I do not see a need for 64-Bit numbers but concatenate
>two 32-Bit numbers, using only special generated numbers with an equal
>bit distribution (because of a better quasi hamming-distance).

Wrong, i had very bad experiences combining 2 numbers of 32 bits when i had
programmed in a check how many collissions that gave, it exponentially became
more collissions each x million nodes when i did this very buggy combination.

I might be running again a collission test at the supercomputer at 64 processors
or so, if i find the time and even more important figure out a way how to test
collissions in parallel as that's not so easy because there is a continues
overwriting of the same entries by more than a few processors :)

A real 64 bits number generator solves all the problems though, it did for me :)

>If you are not interested in a (german language commented) C++ source,
>you may stop reading here.
>
>Regards, Reinhard.
>
>A) HEADER-FILE
>
>//==========================================================
>// PROJEKT: Tool.lib
>//----------------------------------------------------------
>// MODUL  : CRandom (als SINGLETON gekapselt)
>// ZWECK  : allgemein nützliche statische Zufalls-Funktionen
>// AUTOREN: RS, Reinhard Scharnagl, München
>//----------------------------------------------------------
>// DETAILS: Diese Klasse umfasst die wichtigsten und ge-
>//          bräuchlichsten Funktionen eines Pseudo-Zufalls-
>//          zahlen-Generators. Konkret handelt es sich hier
>//          um einen binär kongruenten Generator.
>//----------------------------------------------------------
>// CHRONIK: RS, 08-Okt-2003, überarbeitetes Modul begonnen
>//==========================================================
>
>// --- technische Rekursionssperre (Start) ---
>#ifndef X_RandomH
>#define X_RandomH
>
>//===========================
>// Klasse CRandom (Singleton)
>//===========================
>
>class CRandom {
>
>private: // --- geschützte Typen und Informationen ---
>
>  // Konstanten und Aufzählungen
>  enum ERandom {
>    // die Hälfte möglicher Bits in einem <unsigned>
>    eHASH_BITS = 16,
>    // größte positive Primzahl in einem <unsigned>
>    eMODUL =  0xFFFFFFFB,
>    // ein gut geeigneter Kongruenz-Prim-Faktor
>    eFAKTOR = 0x3FB,
>    // der zu eFAKTOR gehörige Hilfs-Quotient
>    eQUOT = (unsigned)eMODUL / eFAKTOR,
>    // der zu eFAKTOR gehörige Hilfs-Rest
>    eREST = (unsigned)eMODUL % eFAKTOR
>  };
>
>private: // --- geschützte statische Eigenschaften ---
>
>  // die zuletzt erzeugte interne Zufallszahl
>  static unsigned Seed;
>
>public: // --- öffentliche statische Eigenschaften ---
>
>  // das einzige (konstante) Singleton-Objekt
>  static const CRandom TheRandomBox;
>
>private: // --- geschützte Methoden ---
>
>  // Konstruktoren und Destruktoren
>  CRandom() {};  // wg. Singleton private
>  ~CRandom() {}; // wg. Singleton private
>
>public: // --- öffentliche statische Methoden ---
>
>  // setzt (Zeit-) zufällige Startzahl für Generator
>  static unsigned Randomize(void);
>  // setzt positive <int> Startzahl für Generator
>  static unsigned SetSeed(unsigned _uNewSeed);
>
>  // holt <unsigned> Zufallszahl aus (0, eMODUL)
>  static unsigned GetRandom(void);
>  // holt <unsigned> Zufallszahl aus [0, uLimit)
>  static unsigned GetRandom(unsigned _uLimit);
>  // holt Fließkommazahl aus [0.0, rLimit)
>  static double GetRandom(double _rLimit);
>
>  // holt <int> Zufallszahl aus [0, iLimit)
>  inline static int GetRandom(int _iLimit)
>  { return (int)GetRandom(
>     (unsigned)((_iLimit > 0) ? _iLimit : 0));
>  };
>
>  // ermittelt Anzahl gesetzter Bits in <unsigned> Zahl
>  static int CountBits(unsigned _iHash);
>  // liefert positive Spezial-Zufallszahlen für Hashing
>  static int GetHash(void);
>};
>
>// --- technische Rekursionssperre (Ende) ---
>#endif
>
>B) IMPLEMENTATION-FILE
>
>//==========================================================
>// PROJEKT: Tool.lib
>// MODUL  : CRandom (SINGLETON)
>// DETAILS: --> Header-Datei
>//==========================================================
>
>// --- technische Optimierung ---
>#pragma hdrstop
>
>// --- System-Includes ---
>#include <time.h>
>#include <limits.h>
>
>// --- Projekt-Includes ---
>#include "Random.h"
>
>// --- technische Optimierung (Borland) ---
>#ifdef __BCPLUSPLUS__
>#pragma package(smart_init)
>#endif
>
>//===========================
>// Klasse CRandom (Singleton)
>//===========================
>
>// --- statische Klassenvariablen ---
>
>/* die zuletzt erzeugte interne Zufallszahl */
>unsigned CRandom::Seed = 0;
>
>// --- öffentliche statische Eigenschaften ---
>
>// das einzige (konstante) Singleton-Objekt
>const CRandom CRandom::TheRandomBox;
>
>// --- öffentliche statische Methoden ---
>
>// setzt Startzahl aus (0, eMODUL) für Generator
>unsigned CRandom::SetSeed(unsigned _uNewSeed)
>{
>  // auf den Bereich (0, eMODUL) bringen
>  while (!_uNewSeed || _uNewSeed >= (unsigned)eMODUL) {
>    _uNewSeed -= (unsigned)eMODUL;
>  }
>
>  // und übergreifend abspeichern im Seed
>  return (Seed = _uNewSeed);
>}
>
>// setzt (Zeit-) zufällige Startzahl für Generator
>unsigned CRandom::Randomize(void)
>{
>  // ermittle eine Startzahl aus der Systemzeit
>  time_t lSecondsFrom1970;
>  time(&lSecondsFrom1970);
>
>  // setze deren <unsigned>-Teil als Startwert ein
>  return SetSeed((unsigned)lSecondsFrom1970);
>}
>
>// holt <unsigned> Zufallszahl aus (0, eMODUL)
>unsigned CRandom::GetRandom(void)
>{
>  unsigned uNew, uDiv, uMod;
>
>  // Overflow-vermeidendes Errechnen von:
>  // iSeed := (eFAKTOR * iSeed) mod eMODUL,
>  // wobei ein Zero-Seed geliftet wird.
>  uNew = (Seed != 0) ? Seed : (unsigned)eMODUL;
>  uDiv = uNew / eQUOT;
>  uMod = uNew % eQUOT;
>  uNew = eFAKTOR * uMod - eREST * uDiv;
>
>  // neue interne Zufallszahl merken
>  return SetSeed(uNew);
>}
>
>// holt <unsigned> Zufallszahl aus [0, uLimit)
>unsigned CRandom::GetRandom(unsigned _uLimit)
>{
>  // unmögliche Forderungen ignorieren
>  if (_uLimit <= 1 || _uLimit >= eMODUL)
>    return 0;
>
>  // iterative gleichverteilte Erzeugung
>  for (;;) {
>    // neuen Kandidaten testen
>    unsigned uAntwort = GetRandom();
>    // Gleichverteilung sicherstellen
>    if (uAntwort < (eMODUL - (eMODUL-1) % _uLimit))
>      return uAntwort % _uLimit;
>  }
>}
>
>// holt Fließkommazahl aus [0.0, rLimit)
>double CRandom::GetRandom(double _rLimit)
>{
>  // unmögliche Forderungen ignorieren
>  if (_rLimit <= 0.0)
>    return 0.0;
>
>  // transformiere auf gewünschtes Intervall
>  return (double)((GetRandom()-1)>>1) * _rLimit / INT_MAX;
>}
>
>// ermittelt Anzahl gesetzter Bits in <int> Zahl
>int CRandom::CountBits(unsigned _uHash)
>{
>  // initialisiere Bit-Zaehler
>  int iBitCount = 0;
>
>  // verarbeite von unten her alle Testzahl-Bits
>  do {
>    // zaehle den Wert des letzten Bits und
>    iBitCount += (int)(_uHash & 1);
>  // schifte, bis kein gesetztes Bit mehr da ist
>  } while (_uHash >>= 1);
>
>  // antworte mit gefundener Bit-Anzahl
>  return iBitCount;
>}
>
>// liefert positive Spezial-Zufallszahlen für Hashing:
>// liefert eine positive Zufallszahl, die als Binärzahl
>// genau eHASH_BITS Einsen hat (für XOR Overlay Zahlen)
>int CRandom::GetHash(void)
>{
>  int iAntwort;
>  // erzeuge positive Zufallszahl
>  do {
>    iAntwort = (int)GetRandom();
>    // negative Zufallszahl erhalten?
>    if (iAntwort < 0) {
>      // dann eben komplementieren
>      iAntwort = ~iAntwort;
>    }
>    // bis deren Bit-Anzahl exakt stimmt
>  } while (CountBits((unsigned)iAntwort) != eHASH_BITS);
>
>  return iAntwort;
>}



This page took 0.02 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.