Now that brother jdalbec has shown us the way...
...I observe that the values can be calculated directly from the bit pattern -- right shifting trailing zeros off, and then oring/anding new R's for each '1'/'0', shifting right until have shifted at total of 'n' times, where the denominator is 2**n.
This leads to a minor variation on the theme of constructing a Perl expression to do this. Which takes the bits in reverse order. Taken in this order, the operations want to be executed left to right, so only need to add brackets to cope with the higher precedence of &.
Taken in the forward order brackets are required to ensure that where there is a mix of operations, those at the back end of the expression are done first. This may, or may not, be obvious. (Though within groups of things ored together the order is irrelevant, and similarly groups of things anded together.)
I don't know if this is any simpler, but I wrote it and got it working, so here you are...
FWIW, on my machine (64bit modest Semperon) I benchmarked the code to create values directly from the bit-pattern against an anonymous subroutine built by eval. The subroutine was faster, but only by 75% -- so I guess the running time is dominated by rand. I was using a denominator of 2**33, which mapped a probability of 0.1 to:
sub { ((((((((R | R) & R & R | R | R) & R & R | R | R) & R & R | R | R)
& R & R | R | R) & R & R | R | R) & R & R | R | R) & R & R | R | R) & R & R & R }
Easy when you know how :-)
In passing, I discovered that the built-in rand wasn't up to much on my 32-bit machine :-(
|