On Mon, Feb 16, 2009 at 3:33 AM, Don <nos...@nospam.com> wrote: > Bill Baxter wrote: >> >> On Mon, Feb 16, 2009 at 2:33 AM, Don Clugston <nos...@nospam.com> wrote: >>> >>> Andrei Alexandrescu wrote: >>>> >>>> Don wrote: >>>>> >>>>> Andrei Alexandrescu wrote: >>>>>> >>>>>> auto rng = Random(unpredictableSeed); >>>>>> auto a = 0.0, b = 1.0; >>>>>> auto x1 = uniform!("[]")(rng, a, b); >>>>>> auto x2 = uniform!("[)")(rng, a, b); >>>>>> auto x3 = uniform!("(]")(rng, a, b); >>>>>> auto x4 = uniform!("()")(rng, a, b); >>>>> >>>>> This is a general issue applying to any numeric range. I've been giving >>>>> the issue of numeric ranges some thought, and I have begun an >>>>> implementation >>>>> of a general abstraction. >>>>> Any open range can be converted into a closed range, but the converse >>>>> does not apply. So any implementation will be using "[]" internally. >>>>> >>>>> -range("[)", a, b) == range("(]", -b, -a) >>>>> range("[)", a, b) == range("[]", a, predecessor(b)) >>>>> range("()", a, b) == range("[]", successor(a), predecessor(b)) >>>>> >>>>> >>>>> There's a couple of difficult situations involving floating-point >>>>> numbers. >>>>> * "[)" has the uncomfortable property that (-2,-1, rng) includes -2 >>>>> but >>>>> not -1, whereas (1, 2, rng) includes 1 but not 2. >>>>> >>>>> * any floating point range which includes 0 is difficult, because there >>>>> are so many numbers which are almost zero. The probability of getting a >>>>> zero >>>>> for an 80-bit real is so small that you probably wouldn't encounter it >>>>> in >>>>> your lifetime. I think this weakens arguments based on analogy with the >>>>> integer case. >>>>> >>>>> However, it is much easier to make an unbiased rng for [1,2) than for >>>>> [1,2] or (1,2) (since the number of members in the range is even). >>>> >>>> So what would you recommend? [a, b) for floats and [a, b] for ints, or >>>> [a, >>>> b) for everything? >>>> >>>> Andrei >>> >>> I'm leaning towards [a,b) for everything (consistency with arrays), but >>> I'd >>> want to know what the reasoning of the boost/c++0x guys was. >> >> How do you create a random uint that can take on any of uint's values >> with [a,b)? That's the main reason I can think of to go with [a,b] >> for integral types. With floats it's never useful to use the entire >> value range. >> >> --bb > > I think that is the primary argument. BUT: > * You _can_ still use "[]" in that case. > * I also think it'd be worth having a "create a random n-byte number", as > well, which would be the main use for a full uint random number.
I guess I'd find it more useful to have a function that gave a random value of a given type, like random_value!(short). That way you get the signed/unsigned specification automatically. But both could be useful. > * If you're creating a number in the range 0..uint.max+1, you're going to > have to be careful in lots of places. You can't get that number from an > array length, for example. > * I think that hard-core scientific/mathematical users are the main users of > the more esoteric cases, and can be expected to get it right (and have no > problem with the "[]","()","(]"... notation. I think that what's important > for the default is that be correct and obvious for as many cases as > possible. > > The strength of "[)" is that if we can say "ALL ranges in D are [) unless > otherwise stated by the user", it's hard to ever justify breaking that > convention. That sounds reasonable to me. As long as there's an easy way to also create a random number that covers an entire range of a given type (perhaps limited to integral types). --bb