## digitalmars.D.learn - Should uniform(-real.max, real.max) be inf?

- Magnus Lie Hetland <magnus hetland.org> Mar 01 2012
- Magnus Lie Hetland <magnus hetland.org> Mar 01 2012
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> Mar 01 2012
- Magnus Lie Hetland <magnus hetland.org> Mar 02 2012
- Magnus Lie Hetland <magnus hetland.org> Mar 02 2012

What's the preferred way of generating a random floating-point number in the range of a given floating-point type? We have uniform!T() for integral types, but nothing similar for floats? And uniform(-real.max, real.max) (possibly tweaking the limits) seems to only return inf, which isn't terribly helpful. What's the standard thing to do here? I could just use uniform(cast(T) -1, cast(T) 1)*T.max I guess (for some floating-point type T). Seems to work fine, at least. Am I missing the obvious way to do it? -- Magnus Lie Hetland http://hetland.org

Mar 01 2012

On 2012-03-01 10:52:49 +0000, Magnus Lie Hetland said:I could just use uniform(cast(T) -1, cast(T) 1)*T.max I guess (for some floating-point type T). Seems to work fine, at least.

Aaactually, not so much. The output here seems to get about the same exponent as T.max. Which isn't all that surprising, I guess. (Then again, most floating-point numbers *are* pretty large ;-) So ... any suggestions? -- Magnus Lie Hetland http://hetland.org

Mar 01 2012

On 03/01/2012 02:52 AM, Magnus Lie Hetland wrote:What's the preferred way of generating a random floating-point number in the range of a given floating-point type? We have uniform!T() for integral types, but nothing similar for floats? And uniform(-real.max, real.max) (possibly tweaking the limits) seems to only return inf, which isn't terribly helpful. What's the standard thing to do here? I could just use uniform(cast(T) -1, cast(T) 1)*T.max I guess (for some floating-point type T). Seems to work fine, at least. Am I missing the obvious way to do it?

I recommend reading this page: http://dlang.org/d-floating-point.html Especially the ASCII graph there is very interesting. The number of distinct values between T.min_normal and 1 are equal to the distinct values between 1 and T.max. Since there are also sub-normal values between 0 and T.min_normal, it may make sense to use the range [T.min_normal, 1) and scale the result from there. But I haven't tested whether the distinct values in that range are equally distributed. Ali

Mar 01 2012

On 2012-03-01 16:34:23 +0000, Ali Çehreli said:I recommend reading this page: http://dlang.org/d-floating-point.html

Thanks.Especially the ASCII graph there is very interesting. The number of distinct values between T.min_normal and 1 are equal to the distinct values between 1 and T.max .

Ah -- right.Since there are also sub-normal values between 0 and T.min_normal, it may make sense to use the range [T.min_normal, 1) and scale the result from there.

Hm. Seems reasonable.But I haven't tested whether the distinct values in that range are equally distributed.

At the moment, I'm just using this for test-case generation, so anything close to a reasonable approximation is fine :) However: Perhaps it would be useful with a uniform!real() or the like in Phobos? Or is that (because of the vagaries of FP) a weird thing to do, inviting misunderstandings and odd behavior? Perhaps it's been left out for a reason? (Sounds sort of likely ;-) -- Magnus Lie Hetland http://hetland.org

Mar 02 2012

On 2012-03-01 16:34:23 +0000, Ali Çehreli said:Since there are also sub-normal values between 0 and T.min_normal, it may make sense to use the range [T.min_normal, 1) and scale the result from there. But I haven't tested whether the distinct values in that range are equally distributed.

I get similar results now that I did when I started with the range from -1 to 1, but I'm guessing it's my brain that's a little slow. I was perplexed that (for float) almost all the numbers had an exponent of 38, while only a few had 37, and none had anything else (in my limited tests). Buuuut that's just the problem with (at least my) "common sense" and exponentials/logarithms. There are, of course, ten times as many numbers with an exponent of 38 as there are with an exponent of 37 (and so on, down the line; c.f., the incompressibility lemma etc.). For testing, I might want some small numbers, too -- perhaps I should just generate the mantissa and exponent separately (maybe even throwing in some NaNs and Infs etc.) :) Thanks for your help, though. -- Magnus Lie Hetland http://hetland.org

Mar 02 2012