6 ms·
How do randomize in [1,2)? You might as well just generate numbers from [0, 2^53) or [0, 2^24) and divide. If you didn't do that on the way to generating in [
by SamReidHughes 10y ago
How do randomize in [1,2)? You might as well just generate numbers from [0, 2^53) or [0, 2^24) and divide.
If you didn't do that on the way to generating in [1,2), you're going to have fine-grained non-uniformity anyway.
- Dylan16807 10y ago>How do randomize in [1,2)? 0x3f800000 + 23 random bits
- SamReidHughes 10y agoWell. That'll do it. Probably no slower than the integer to float conversion too. It gets you multiples of 2^-52 instead of 2^-53 though.
- strainer 10y agoI see your talking 64 bit floats there which is my habit too. Having only 24 bit mantissa float32s seem insufficient for producing practically uniform variates - the missing 2^24th can be spotted averaging just a billion or so of them. I dont know if it has been improved recently but last year Chrome's Math.random was only putting 32 bits into its float64 - the missing four-billionth can be suggested from the average of a few hundred billion variates.
- SamReidHughes 10y agoYeah, I really think a better way is to imagine generating a uniform real and rounding -- generating [0,1) instead of [0,1] is just sick. If you do rand() * k + n you can get [n, n+k] anyway, so it's not a good primitive to get a half-open interval with. You can generate an integer n in [1, 2^25], then take (n >> 1) * (1 / (float)(1 << 24)) to get a pretty good [0,1].
- mark-r 10y agoFor a 64-bit floating point number, the difference between [0,1) and [0,1] is for all practical purposes nonexistent. The chances of getting 1.0 exactly are so low that you can't build a test to know if it's excluded or not. For a 32-bit floating point number it's more of a problem, but your application would have to be extremely demanding to detect the difference.
- strainer 10y agoA rough calculation, a float64 rng which might reasonably supply billions of rnds an hour for simulations, would have a fair risk of hitting '1.0' every million hours of use, which means its important for production quality code to not run that risk. A prng called Alea works with floating point arithmetic to generate rnds securely confined to [0,1] using a 'subtract with carry' scheme. It involves this kind of arrangement: state=state*something+carry carry=floor(state) return state-carry //this is 0<1 Its very similar to linear congruential generator where top bits are masked away, in this case they are 'floored' off and fed back into the state. Alea seems to generate high quality rands and works extremely quickly in javascript engines by avoiding integer math. My rnd utility module uses a similar algorithm. There may be a note of caution whether floating point math is standardised enough to use for a seedable prng, but so far my machines and phone have agreed in tests. http://strainer.github.io/Fdrandom.js/ http://strainer.github.io/Fdrandom.js/
- mark-r 10y agoMy argument was for the other direction, using [0,1) when you actually want [0,1]. I agree that if 1.0 would cause a problem in your code you should use a rng that avoids it. All of the floating point random number generators I'm familiar with deliver [0,1).
- strainer 10y agoInteresting, I assumed java and javascripts behaviour were common. I dont recall seeing this notation before either [0,1) maybe i will now %)
- dnautics 10y agof() = (rand() + 1.0) - 1.0 and pray that your compiler isn't clever! Or you can actually randomize the fraction bits.