Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Well. 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.


I 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.


Yeah, 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].


For 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.


A 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/


My 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).


Interesting, I assumed java and javascripts behaviour were common. I dont recall seeing this notation before either [0,1) maybe i will now %)


I usually use C++ or Python, so I had to look up the others.

From Java: "Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0."

From Javascript: "Return a random number between 0 (inclusive) and 1 (exclusive)"

So yes, all 4 are consistent in not including 1.0 in the range of random real numbers. I'd call that common.

For more on the notation see https://en.wikipedia.org/wiki/Interval_(mathematics)#Includi...


Apologies I wasn't following properly, and thanks for the interval math pointer.


I ended up just doing a one op conversion. Multiply by a manually eked factor which is the maximum value which the maximum-source-value can be multiplied by and not make 1. That just minimises the gap at the end of the unit interval which is caused by the limited resolution. I judged its not possible to get too close to 1, so just found the biggest float factor which doesn't get to 1. If that last 0.9999... value has a larger chance of occurring than any of the lesser, that seems good to me for numerical purposes as it hides the shortfall of not being able to express 1< There will be irregularities in the meaning of the least significant bits anyway due to rounding 'noise'




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: