On Tue, Sep 28, 2010 at 05:01:13PM +0200, Lars Ellenberg wrote: > # HG changeset patch > # User Lars Ellenberg <l...@linbit.com> > # Date 1285682508 -7200 > # Node ID 94f4ee6025502c7ef710775d458ef766c51ad6db > # Parent 066f484922ec549f84ea59c138d4e6cf16b2e14b > Low: add cl_rand_from_intervall(a, b) helper > > There are a few places throughout the (heartbeat) code which want to generate > random ints from a certain interval. > Don't have them all fix the same normalization problems over and over again. > > diff -r 066f484922ec -r 94f4ee602550 include/clplumbing/cl_random.h > --- a/include/clplumbing/cl_random.h Tue Sep 28 13:12:33 2010 +0200 > +++ b/include/clplumbing/cl_random.h Tue Sep 28 16:01:48 2010 +0200 > @@ -18,6 +18,40 @@ > * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > */ > > +#include <stdlib.h> > +unsigned int cl_randseed(void); > +/* Is currently rand() based. > + * Does srand(cl_randseed()) once internally. > + * Assumes mainloop is setup. */ > +int get_next_random(void); > > -unsigned int cl_randseed(void); > -int get_next_random(void); /* Assumes mainloop setup */ > +/* generate some random number in the range [a;b]; > + * typically used to randomly delay messages. */ > +#define HAVE_CL_RAND_FROM_INTERVAL 1 > +static inline > +int cl_rand_from_interval(const int a, const int b) > +{ > + /* > + * Be careful here, you don't know RAND_MAX at coding time, > + * only at compile time. If you think > + * (int)(a + (rand()*(b-a)+(RAND_MAX/2))/RAND_MAX); > + * was correct, think again with RAND_MAX = INT_MAX, > + * which is the case for many rand() implementations nowadays. > + * > + * Don't do modulo, either, as that will skew the distribution, and > + * still has possible wraparounds, or an insufficient input set for too > + * small RAND_MAX. > + * > + * Rather do the whole calculation in 64 bit, which should be correct > + * as long as r, a, b, and RAND_MAX are all int. > + * Of course, if you prefer, you can do it with floating point as well. > + */ > +#if 1 /* use long long */ > + long long r = get_next_random(); > + r = a + (r * (b-a) + RAND_MAX/2)/RAND_MAX; > +#else /* use floating point */ > + int r = get_next_random(); > + r = a + (int)(1.0 / RAND_MAX * r * (b-a) + 0.5); > +#endif > + return r; > +}
Looks good to me. Dejan > _______________________________________________________ > Linux-HA-Dev: Linux-HA-Dev@lists.linux-ha.org > http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev > Home Page: http://linux-ha.org/ _______________________________________________________ Linux-HA-Dev: Linux-HA-Dev@lists.linux-ha.org http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev Home Page: http://linux-ha.org/