Re: Suggestion: Change the specification for grand in glib



Sebastian Wilhelmi <wilhelmi ira uka de> writes:

> We could call it 'begin' and 'end' just like the STL parameters, if that would
> help. but calling them lower_closed_bound and upper_open_bound seems a bit
> odd. 

I agree.

> Come on, this is silly. Firstly case 0 will happen in 4294967295 of 4294967296
> cases not to talk about the cases 1 and 2 (I think, it is more probable, that
> the world collapses, than to see the case 2). And if it does, nobody needs the
> higher accuracy of the number. Actually it could harm, because it provides a
> better granularity, than the user might expect. 
> 
> I mean, if you return an integer in [0,32^2-1] you are not returning less
> information, if the first bits are zero. Even if double allows you to return
> more bits, if the first ones after the point are zero, it doesn't seem to make
> any sense to really do that. 

If the application for g_rand_double is g_rand_double_range or
g_rand_int_range you are correct. But in simulations where we test on
really low probabilities it is important that g_rand_double works near
0.0.  But in that case we do not need all 53 bits of accuracy.

If you whant to spare one test then the following could be used:

gdouble
g_rand_double (GRand* rand)
{
  gdouble transform = G_RAND_DOUBLE_TRANSFORM;
  guint32 r1 = g_rand_int (rand);
  gdouble r2 = g_rand_int (rand);

  if (r1 < 1<<20)
    {
      while (r1 == 0)
        {
          transform *= G_RAND_DOUBLE_TRANSFORM;
          r1 = g_rand_int (rand);
        }
      r2 += g_rand_int (rand) * G_RAND_DOUBLE_TRANSFORM;
    }

  return (r2 * G_RAND_DOUBLE_TRANSFORM + r1) * transform;
}

The following version should be sufficient:

gdouble
g_rand_double (GRand* rand)
{
  gdouble transform = G_RAND_DOUBLE_TRANSFORM;
  guint32 r1 = g_rand_int (rand);

  while (r1 == 0)
    {
      transform *= G_RAND_DOUBLE_TRANSFORM;
      r1 = g_rand_int (rand);
    }

  return (g_rand_int (rand) * G_RAND_DOUBLE_TRANSFORM + r1) * transform;
}

Or even simpler without the loop:

gdouble
g_rand_double (GRand* rand)
{
  guint32 r1 = g_rand_int (rand);

  if (r1 == 0)
    return (g_rand_int (rand) * G_RAND_DOUBLE_TRANSFORM + g_rand_int (rand)) 
      * (G_RAND_DOUBLE_TRANSFORM * G_RAND_DOUBLE_TRANSFORM)
  else
    return (g_rand_int (rand) * G_RAND_DOUBLE_TRANSFORM + r1) 
      * G_RAND_DOUBLE_TRANSFORM;
}

Sverre Hvammen Johansen




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]