#ifndef CGAL_RANDOM_INTEGER_H #define CGAL_RANDOM_INTEGER_H #include #include #include // type "man {rand, random, drand48}" for C functions that produce // random numbers //extern "C" int getpid(); //extern "C" int srandom(unsigned); //extern "C" long random(); CGAL_BEGIN_NAMESPACE // powers of 2 from 2^0 to 2^53 double P2[54]={1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 2048.0, 4096.0, 8192.0, 16384.0, 32768.0, 65536.0, 131072.0, 262144.0, 524288.0, 1048576.0, 2097152.0, 4194304.0, 8388608.0, 16777216.0, 33554432.0, 67108864.0, 134217728.0, 268435456.0, 536870912.0, 1073741824.0, 2147483648.0, 4294967296.0, 8589934592.0, 17179869184.0, 34359738368.0, 68719476736.0, 137438953472.0, 274877906944.0, 549755813888.0, 1099511627776.0, 2199023255552.0, 4398046511104.0, 8796093022208.0, 17592186044416.0, 35184372088832.0, 70368744177664.0, 140737488355328.0, 281474976710656.0, 562949953421312.0, 1125899906842624.0, 2251799813685248.0, 4503599627370496.0, 9007199254740992.0}; // set the random number generator seed void set_seed(unsigned int seed) { srandom(seed); } // return random integer of b bits double random_integer(int b, bool allow_negative = true) { double value; if (b > 27) { value = ((int)random()) % ((int)P2[27]); value += ( ((int)random()) % ((int)P2[b - 27]) ) * P2[27]; } else { value = ((int)random()) % (int)P2[b]; } if ( allow_negative ) { value *= ( ((int) random()) % 2 == 0 ) ? 1 : -1; } return value; } template double random_integer(Random& r, unsigned int b, bool allow_negative = true) { // returns random integers in the range [0, 2^b - 1). // b is required to be at least 1 and at most 52 // and if allow_negative is true then the range includes negative // numbers as well and becomes: [-2^b + 1, 2^b - 1). CGAL_precondition( b >= 0 && b <= 52 ); if ( b == 0 ) { return 0; } double M = pow(2.0,b); CGAL::Gmpz z; if ( allow_negative ) { z = r.get_double(-M, M); } else { z = r.get_double(0, M); } return CGAL::to_double(z); } template double random_even_integer(Random& r, unsigned int b, bool allow_negative = true) { // returns random even integers in the range [0, 2^b - 1). // b is required to be at least 1 and at most 52 // and if allow_negative is true then the range includes negative // numbers as well and becomes: [-2^b + 1, 2^b - 1). CGAL_precondition( b >= 0 && b <= 52 ); if ( b == 0 ) { return 0; } double M = pow(2.0,b); CGAL::Gmpz z; CGAL::Gmpz two(2); do { if ( allow_negative ) { z = r.get_double(-M, M); } else { z = r.get_double(0, M); } } while ( z % two != 0 ); return CGAL::to_double(z); } CGAL_END_NAMESPACE #endif // CGAL_RANDOM_INTEGER_H