Computer: Algorithm
Random number salvage   (0)  [vote for, against]
get something back from wasted bits

True random numbers are actually quite hard to generate in bulk. Generally, 'raw' random bits are created using a hardware device then heavily filtered to get rid of bias and any other non-randomness.

To generate a random number in a range which isn't a power-of-two from random bits, the only valid method involves repeatedly generating a random number in a power-of-two range, discarding the result if it exceeds the maximum.

For example, to generate an integer in the inclusive range 0..4 (5 possibilities), three random bits would be taken to generate an integer in the range 0..7. If the resultant number was 5,6 or 7 this would be discarded and the method repeated.
Obviously this is wasteful, as several repeats may be made before an in-range number is created.

Where there is more than one value in the 'reject' range, there is an opportunity to salvage some data from discarded results.
The range-limited random number generator simply needs to keep track of the maximum extent of the excess, and apply additional random bits to make up the range.

In the above case, a three-value range is available from rejected numbers: 5..7. Subtracting the minimum and adding an extra bit gives a six-value range (0..5), which is enough for another attempt. Note that this has a single reject value - no further salvage is possible so a full three-bit value must be generated for a third attempt.

By my calculations on average the default method uses about 4.8 bits per number while the salvaging method uses 3.6 bits per number for the example range. I think that's a pretty decent saving, although obviously the saving varies depending on the range required, being best at 2^n+1 and nothing at all for 2^n-1.
-- Loris, May 28 2011

HotBits http://www.fourmilab.ch/hotbits/
Genuine random numbers, generated by radioactive decay [Loris, May 28 2011]

What about mapping the random number to the range? So for example multiplying the random number by 5/8 and then rounding or truncating to get an integer.

I'm guessing there's a problem with my solution.
-- xaviergisz, May 28 2011


That method is commonly used, [xaviergist], but it's even more wasteful, since you have to generate extra bits to avoid rounding errors.

(Picky) True random numbers are impossible to generate, because on average, their size is infinite.

//To generate a random number which isn't a power-of-two from random bits// You mean whose range isn't a power of two, right? That one confused me for a bit.
-- spidermother, May 28 2011


Yep wasteful and it also wouldn't work properly. Some random numbers would have a two-to-one mapping, whereas others would only have a one-to-one mapping. Thus some numbers would get mapped twice as frequently.
-- xaviergisz, May 28 2011


Hi Loris, I always thought the general random number generation process went more in the style of
1) Generate a table of random bits from a given seed
2) Take the nth bit-pattern and interpret as a floating point number between 0 and 1.
3) Scale to required proportions.

But that could be due to it being presented like that in a couple of languages, rather than being how they do it in hardware.

e.g. For a random number between 1 and 6 in BASIC
x = INT(RND(seed)*6)+1
And in Java , the second part is done for you, depending on the type/size of number you want, leaving
int throw = generator.nextInt(6) + 1;

But I see you're talking about doing this in hardware (I think the above is generally implemented as algorithmic pseudo-random numbers) but that same scaling method could be applied, depending on the range of numbers you want to spit out.
-- zen_tom, May 28 2011


That's what I meant by extra bits, above. A random number between 1 and 6 requires only 3 bits, but the floating point number typically has 32 bits.
-- spidermother, May 28 2011


Yes, that's pretty much it.
If you have copious random bits, you can use many, and scale the result to the desired range. However this does have an issue in that there will be an excess for some numbers due to the mapping. It may not be much, but it's an issue for all the things you want very good random numbers for.

Pseudo-random number generators are good at generating the many bits necessary for this, but they're not random enough for some purposes. Hardware RNGs can produce very good randomness, but they're relatively slow - of the order of hundreds or thousands of random bytes per second (Hotbits, for example, reportedly generates ~100 bytes per second).

The actual randomness getter is the only part for which hardware is needed. Typically they're written to a file and used as needed (each bit can only be used once). I'm not proposing any additional hardware for the processing, merely an algorithm to eke out a number of random bits to go further.

////To generate a random number which isn't a power-of-two from random bits// You mean whose range isn't a power of two, right? That one confused me for a bit.//
Um, yes. I'll fix that.
-- Loris, May 28 2011



random, halfbakery