-4

Is there a fast way to randomly choose between two numbers in C ? It seems that functions like rand() take too long. Are they necessary ?

mark4rd
  • 225
  • 3
  • 11
  • 3
    It's proven hard to generate very random numbers actually. So the answer to this question depends on, how random do you want it? – user3528438 Apr 09 '16 at 18:09
  • 2
    and how fast do you want it? – Weather Vane Apr 09 '16 at 18:09
  • 4
    If `RAND_MAX` is `32767` (such as MSVC) a single call to `rand()` will give you 15 coin flips. – Weather Vane Apr 09 '16 at 18:11
  • 4
    "Random"...https://xkcd.com/221/ – nalzok Apr 09 '16 at 18:15
  • Thank you for the comments! My goal is to create a function that chooses with probability as close as possible to 50% one out of two numbers and as fast as possible. – mark4rd Apr 09 '16 at 18:16
  • 1
    @mark4rd that would require specialized hardware and be very expensive. – Martin James Apr 09 '16 at 18:23
  • Unless you have access to a hardware generator it will be a trade-off. The more (apparently) random the algorithm, the longer the simulation will take. But remember, after 10 trillion real world dice rolls, the difference will probably ;) **not** be `<= 1` – Weather Vane Apr 09 '16 at 18:23
  • I'd reword this to. How can I use rand and choose between two numbers so that I don't waste the extra bits that rand produces. – Harry Apr 09 '16 at 18:46
  • If I reword the question as you suggest I would limit myself in using rand(), which is the exact opposite of the purpose of this question. I try to find an alternative to rand, something that it is faster. If someone can prove that there is nothing better than that , then that would fit the answer. From Spencer Doak's answer I can see that there exist alternatives (https://software.intel.com/en-us/articles/fast-random-number-generator-on-the-intel-pentiumr-4-processor/) . But all these generate numbers and I was wondering if choosing between two numbers could be a smaller problem. – mark4rd Apr 09 '16 at 19:26
  • You should add something about suitability ie do you need truly random data or will a pseudo random generator do? Some tests will require a real number generator, some don't. – Harry Apr 09 '16 at 22:57
  • As far as I know there is no truly random data generator in C, all are pseudo random. I am trying to write a function that works similarly as flipping a coin, or as close it can get . So that would be either a random generator that generates only two numbers , or a function that chooses one number out of two "randomly" . The goal is to create something fast. I already have implementations using rand() and fastrand() but I am looking for something faster if exists. – mark4rd Apr 09 '16 at 23:31
  • 1
    I prefer the [Xorshift](https://en.wikipedia.org/wiki/Xorshift) family of generators. For one-bit output, use a cache word, and the number of bits left in the cache word, rather than just picking one bit out of each random number, as using just one bit out of each number generated may not be as random as using the entire number. – Nominal Animal Apr 09 '16 at 23:56
  • @Nominal Animal That is very interesting, thank you! Probably it is what I need. – mark4rd Apr 10 '16 at 00:36
  • `rand` takes too long (!?). – Jabberwocky Apr 10 '16 at 10:40

1 Answers1

1

Try this:

// 0=heads; 1=tails;
int flipCoin(){
    return 1; // Chosen by a fair coin toss.
              // Guaranteed to be random.
}

Just kidding. I had to toss that in.


Anyway, back to the topic, the real issue here is what quality do you want/need? If quality is not all too important, so you just need a very fast PRNG, then you may want to try something like this:

static unsigned int g_seed;

//Used to seed the generator.           
inline void fast_srand( int seed ){
   g_seed = seed;

}

//fastrand routine returns one integer, similar output value range as C lib.

inline int fastrand(){

  g_seed = (214013*g_seed+2531011);

  return (g_seed>>16)&0x7FFF;

}

int flipCoin(){
    return fastRand()%2;
}

And obviously you will need to seed the "fastrand" generator.

Credit: This code comes from Asis' answer on this question: Faster than rand()?.

Spencer D
  • 3,203
  • 2
  • 22
  • 40
  • 1
    This is a [linear congruential pseudorandom number generator](https://en.wikipedia.org/wiki/Linear_congruential_generator), which do not have terribly good randomness properties. I prefer the [Xorshift](https://en.wikipedia.org/wiki/Xorshift) family of [linear feedback shift register pseudorandom number generators](https://en.wikipedia.org/wiki/Linear_feedback_shift_registers) myself. – Nominal Animal Apr 09 '16 at 23:53
  • @NominalAnimal, thanks for identifying the RNG scheme implemented in this design. I had no idea what kind of RNG it was :P I'll have to look into that other PRNG method you linked to. – Spencer D Apr 11 '16 at 18:28