www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

hash.cpp (1655B)


      1 #include "all_includes.hh"
      2 
      3 int random_seed() {
      4 	static bool initialized = false;
      5 	if (!initialized) {
      6 		initialized = true;
      7 		srand(time(NULL));
      8 	}
      9 	return rand();
     10 }
     11 
     12 // Ce hash donne des bons résultats sur tous les bits de l'entier
     13 // généré (pas d'artefacts, répartition homogène des 0 et des 1).
     14 unsigned int hash2(unsigned int a, unsigned int b) {
     15 	unsigned int h = 1;
     16 	int i;
     17 	for (i = 0; i < 32; i+=8) {
     18 		a = a*h + 1;
     19 		b = b*h + 1;
     20 		// marche aussi avec 65521.
     21 		h = (h << 6) + (h << 16) - h + ((a >> i) & 0xff); // h * 65599 + ieme octet de a
     22 		h = (h << 6) + (h << 16) - h + ((b >> i) & 0xff); // h * 65599 + ieme octet de b
     23 	}
     24 	return h;
     25 }
     26 
     27 float floatInRange(int seed, int n, float a, float b) {
     28 	// 24 bits de précision, ça devrait suffire pour la plupart des utilisations.
     29 	return (float)(hash2(seed, n) & 0xffffff) / (float)(0x1000000) * (b-a) + a;
     30 }
     31 
     32 bool proba(int seed, int n, float proba) {
     33 	return floatInRange(seed, n, 0, 1) < proba;
     34 }
     35 
     36 unsigned int float2uint(float f) {
     37 	// TODO : il y a plein de problèmes avec cette conversion :
     38 	// 1) Il y a plusieurs représentations possibles pour le même float,
     39 	//    donc si on re-split un objet 10 minutes après et qu'on n'a pas
     40 	//    la même représentation, on n'aura pas la même entropie pour les hash.
     41 	// 2) On ne peut pas faire juste fi.f = f; return fi.ui; car si
     42 	//    sizeof(int) > sizeof(float), on lira des saletés.
     43 	// 3) De toute façon, tout ça est principalement du "undefined behaviour".
     44 	FloatUIntUnion fi;
     45 	for (unsigned int i = 0; i < sizeof(fi); i++) {
     46 		// effacer la structure.
     47 		reinterpret_cast<char*>(&fi)[i] = 0;
     48 	}
     49 	fi.f = f;
     50 	return fi.ui;
     51 }