|
From: Daniel J S. <dan...@ie...> - 2010-12-28 23:56:09
|
Ethan Merritt wrote:
> On Tuesday, December 28, 2010, Juhász Péter wrote:
[snip]
> > 2) It is possible to lock the PRNG into a state where the returned
>
>>numbers are not random at all:
>>gnuplot> print rand(0.5)
>>0.999999999450207
>>gnuplot> print rand(0)
>>0.999999999450207
>>gnuplot> print rand(0)
>>0.999999999450207
>>gnuplot> print rand(0)
>>0.999999999450207
>>gnuplot> print rand(0)
>>0.999999999450207
>
>
> Here I agree that the documentation should state that seeds are
> required to be non-zero integers, although it is then tricky to
> explain that the way to set both seed values is
> rand( i + j*{0,1} )
>
> It's fair to consider acceptance of a seed value (0 < seed < 1) as a
> bug, since it will immediately be converted to an integer value 0
> which is not a valid seed. This might be an adequate fix:
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> --- gnuplot/src/specfun.c 2010-10-21 22:28:24.000000000 -0700
> +++ gnuplot-cvs/src/specfun.c 2010-12-28 13:23:20.000000000 -0800
> @@ -1098,7 +1098,7 @@ ranf(struct value *init)
>
> /* Construct new seed values from input parameter */
> /* FIXME: Ideally we should allow all 64 bits of seed to be set */
> - if (real(init) > 0.0) {
> + if (real(init) > 1.0) {
> if (real(init) >= (double)(017777777777UL))
> int_error(NO_CARET,"Illegal seed value");
> if (imag(init) >= (double)(017777777777UL))
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> Note that the FIXME comment is out of date. You can indeed set 64 bits
> of seed by using rand(i + j*{0,1}) as noted above.
The "value" type is double floats for real and imaginary, then? Well, that should hold 32 bits within a 52 bit fractional. (seed1 and seed2 are longs.) A couple odd things however. Why is the limiting value 017777777777UL? Is that some bad way of obtaining the maximum 32 value of 2^32-1, i.e., 4294967295? If not, then it should be
if (real(init) >= (double)(04294967295UL))
int_error(NO_CARET,"Illegal seed value");
if (imag(init) >= (double)(04294967295UL))
int_error(NO_CARET,"Illegal seed value");
And what is with this?
seed1 = (int)real(init);
seed2 = (int)imag(init);
That's a potential bug for compilers in which the default integer is 16 bits. First casting to int and then casting to long could lose something.
Regarding the out of date comment, did it mean that seed1 and seed2 should be 64-bit, i.e., long long?
Dan
|