# 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;
+}
_______________________________________________________
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