Re: [Linux-ha-dev] [PATCH] Low: add cl_rand_from_intervall(a, b) helper

2010-10-04 Thread Dejan Muhamedagic
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/


[Linux-ha-dev] [PATCH] Low: add cl_rand_from_intervall(a, b) helper

2010-09-28 Thread Lars Ellenberg
# 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.hTue Sep 28 13:12:33 2010 +0200
+++ b/include/clplumbing/cl_random.hTue 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. */
+intget_next_random(void);
 
-unsigned int   cl_randseed(void);
-intget_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
+intcl_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;
+}
___
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/