[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-ha-dev
Subject:    [Linux-ha-dev] [PATCH] Low: add cl_rand_from_intervall(a, b) helper
From:       Lars Ellenberg <lars.ellenberg () linbit ! com>
Date:       2010-09-28 15:01:13
Message-ID: 94f4ee6025502c7ef710.1285686073 () soda ! linbit
[Download RAW message or body]

# HG changeset patch
# User Lars Ellenberg <lars@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/
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic