-
Why are we using lemire's method to get [0,s) when we can just public ulong NextUInt64(ulong maxValue)
{
UInt128 randomProduct = (UInt128)maxValue * NextUInt64();
return (ulong)(randomProduct >> 64);
} for example |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
The change was originally to avoid division, Lemire claims in his paper quote "Though arbitrary integer divisions are relatively expensive on common processors, bit shifts are less expensive, often requiring just one cycle" (https://arxiv.org/pdf/1805.10941.pdf section 4). So if we are getting random number in range, Lemire looks at Java's approach and many other languages, noted for example Java simply use modulo (%) if the generated random number is greater than the range specified (range being [0,s) where generated number x > s) But if we where to multiply random number with range, get the full result (UINT64 * UINT64 = UINT128), get the significant bit and cast back we get a value that's in [0,s) with probability of the values in this range being equal In other words why is rejection necessary, how is |
Beta Was this translation helpful? Give feedback.
-
This is impossible if one only makes one random |
Beta Was this translation helpful? Give feedback.
This is impossible if one only makes one random
ulong
and attempts to map it onto [0,s), because however one maps it, the probability of resulting in any particular integer in [0,s) is an integer times 2^(-64), so can never be exactly 1/s unless s is a power of 2.