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/

Reply via email to