added some more random generator functions (from glib)
authorHolger Schemel <info@artsoft.org>
Mon, 8 Apr 2024 23:44:39 +0000 (01:44 +0200)
committerHolger Schemel <info@artsoft.org>
Mon, 8 Apr 2024 23:44:39 +0000 (01:44 +0200)
src/game_bd/bd_random.c
src/game_bd/bd_random.h

index 57fe1c068c87e4710134901391df22da3d83e0fd..fc7998cbdb936718bac7321286d647c7e1722bfa 100644 (file)
@@ -387,6 +387,9 @@ gd_rand_int (GdRand *rand)
   return y;
 }
 
+// transform [0..2^32] -> [0..1]
+#define GD_RAND_DOUBLE_TRANSFORM 2.3283064365386962890625e-10
+
 /**
  * gd_rand_int_range:
  * @rand_: a #GdRand
@@ -435,6 +438,52 @@ gd_rand_int_range (GdRand *rand, int begin, int end)
   return begin + random;
 }
 
+/**
+ * gd_rand_double:
+ * @rand_: a #GRand
+ *
+ * Returns the next random #double from @rand_ equally distributed over
+ * the range [0..1).
+ *
+ * Returns: a random number
+ */
+double
+gd_rand_double (GdRand *rand)
+{
+  /* We set all 52 bits after the point for this, not only the first
+     32. That's why we need two calls to gd_rand_int */
+  double retval = gd_rand_int(rand) * GD_RAND_DOUBLE_TRANSFORM;
+  retval = (retval + gd_rand_int(rand)) * GD_RAND_DOUBLE_TRANSFORM;
+
+  /* The following might happen due to very bad rounding luck, but
+   * actually this should be more than rare, we just try again then */
+  if (retval >= 1.0)
+    return gd_rand_double (rand);
+
+  return retval;
+}
+
+/**
+ * gd_rand_double_range:
+ * @rand_: a #GRand
+ * @begin: lower closed bound of the interval
+ * @end: upper open bound of the interval
+ *
+ * Returns the next random #double from @rand_ equally distributed over
+ * the range [@begin..@end).
+ *
+ * Returns: a random number
+ */
+double
+gd_rand_double_range (GdRand *rand, double begin, double end)
+{
+  double r;
+
+  r = gd_rand_double(rand);
+
+  return r * end - (r - 1) * begin;
+}
+
 static GdRand *
 get_global_random (void)
 {
@@ -447,6 +496,32 @@ get_global_random (void)
   return global_random;
 }
 
+/**
+ * gd_random_boolean:
+ *
+ * Returns a random #gboolean.
+ * This corresponds to an unbiased coin toss.
+ *
+ * Returns: a random #gboolean
+ */
+/**
+ * gd_random_int:
+ *
+ * Return a random #guint32 equally distributed over the range
+ * [0..2^32-1].
+ *
+ * Returns: a random number
+ */
+unsigned int
+gd_random_int (void)
+{
+  unsigned int result;
+
+  result = gd_rand_int(get_global_random());
+
+  return result;
+}
+
 /**
  * gd_random_int_range:
  * @begin: lower closed bound of the interval
@@ -466,3 +541,40 @@ gd_random_int_range (int begin, int end)
 
   return result;
 }
+
+/**
+ * gd_random_double:
+ *
+ * Returns a random #double equally distributed over the range [0..1).
+ *
+ * Returns: a random number
+ */
+double
+gd_random_double (void)
+{
+  double result;
+
+  result = gd_rand_double(get_global_random());
+
+  return result;
+}
+
+/**
+ * gd_random_double_range:
+ * @begin: lower closed bound of the interval
+ * @end: upper open bound of the interval
+ *
+ * Returns a random #double equally distributed over the range
+ * [@begin..@end).
+ *
+ * Returns: a random number
+ */
+double
+gd_random_double_range (double begin, double end)
+{
+  double result;
+
+  result = gd_rand_double_range(get_global_random(), begin, end);
+
+  return result;
+}
index 14cd10c66b2cb8c432b901961ad8974c664a0f0f..ec6c503fa3ad28f064e167200207acc21c40782b 100644 (file)
@@ -57,9 +57,15 @@ void         gd_rand_set_seed_array(GdRand *rand_, const unsigned int *seed, uns
 #define      gd_rand_boolean(rand_) ((gd_rand_int (rand_) & (1 << 15)) != 0)
 unsigned int gd_rand_int(GdRand *rand_);
 int          gd_rand_int_range(GdRand *rand_, int begin, int end);
+double       gd_rand_double(GdRand *rand_);
+double       gd_rand_double_range(GdRand *rand_, double begin, double end);
 
 void         gd_random_set_seed(unsigned int seed);
+#define      gd_random_boolean() ((gd_random_int () & (1 << 15)) != 0)
 unsigned int gd_random_int(void);
 int          gd_random_int_range(int begin, int end);
 
+double       gd_random_double(void);
+double       gd_random_double_range(double  begin, double  end);
+
 #endif // BD_RANDOM_H