Blame glib/tests/rand.c

Packit ae235b
/* Unit tests for grand
Packit ae235b
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
Packit ae235b
 *
Packit ae235b
 * This work is provided "as is"; redistribution and modification
Packit ae235b
 * in whole or in part, in any medium, physical or electronic is
Packit ae235b
 * permitted without restriction.
Packit ae235b
 *
Packit ae235b
 * This work is distributed in the hope that it will be useful,
Packit ae235b
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit ae235b
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Packit ae235b
 *
Packit ae235b
 * In no event shall the authors or contributors be liable for any
Packit ae235b
 * direct, indirect, incidental, special, exemplary, or consequential
Packit ae235b
 * damages (including, but not limited to, procurement of substitute
Packit ae235b
 * goods or services; loss of use, data, or profits; or business
Packit ae235b
 * interruption) however caused and on any theory of liability, whether
Packit ae235b
 * in contract, strict liability, or tort (including negligence or
Packit ae235b
 * otherwise) arising in any way out of the use of this software, even
Packit ae235b
 * if advised of the possibility of such damage.
Packit ae235b
 */
Packit ae235b
Packit ae235b
#include "glib.h"
Packit ae235b
Packit ae235b
/* Outputs tested against the reference implementation mt19937ar.c from
Packit ae235b
 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
Packit ae235b
 */
Packit ae235b
Packit ae235b
/* Tests for a simple seed, first number is the seed */
Packit ae235b
const guint32 first_numbers[] = 
Packit ae235b
{
Packit ae235b
  0x7a7a7a7a,
Packit ae235b
  0xfdcc2d54,
Packit ae235b
  0x3a279ceb,
Packit ae235b
  0xc4d39c33,
Packit ae235b
  0xf31895cd,
Packit ae235b
  0x46ca0afc,
Packit ae235b
  0x3f5484ff,
Packit ae235b
  0x54bc9557,
Packit ae235b
  0xed2c24b1,
Packit ae235b
  0x84062503,
Packit ae235b
  0x8f6404b3,
Packit ae235b
  0x599a94b3,
Packit ae235b
  0xe46d03d5,
Packit ae235b
  0x310beb78,
Packit ae235b
  0x7bee5d08,
Packit ae235b
  0x760d09be,
Packit ae235b
  0x59b6e163,
Packit ae235b
  0xbf6d16ec,
Packit ae235b
  0xcca5fb54,
Packit ae235b
  0x5de7259b,
Packit ae235b
  0x1696330c,
Packit ae235b
};
Packit ae235b
Packit ae235b
/* array seed */
Packit ae235b
const guint32 seed_array[] =
Packit ae235b
{
Packit ae235b
  0x6553375f,
Packit ae235b
  0xd6b8d43b,
Packit ae235b
  0xa1e7667f,
Packit ae235b
  0x2b10117c
Packit ae235b
};
Packit ae235b
Packit ae235b
/* tests for the array seed */
Packit ae235b
const guint32 array_outputs[] =
Packit ae235b
{
Packit ae235b
  0xc22b7dc3,
Packit ae235b
  0xfdecb8ae,
Packit ae235b
  0xb4af0738,
Packit ae235b
  0x516bc6e1,
Packit ae235b
  0x7e372e91,
Packit ae235b
  0x2d38ff80,
Packit ae235b
  0x6096494a,
Packit ae235b
  0xd162d5a8,
Packit ae235b
  0x3c0aaa0d,
Packit ae235b
  0x10e736ae
Packit ae235b
};
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_rand (void)
Packit ae235b
{
Packit ae235b
  guint n;
Packit ae235b
  guint ones;
Packit ae235b
  double proportion;
Packit ae235b
  GRand *rand;
Packit ae235b
  GRand *copy;
Packit ae235b
Packit ae235b
  rand = g_rand_new_with_seed (first_numbers[0]);
Packit ae235b
Packit ae235b
  for (n = 1; n < G_N_ELEMENTS (first_numbers); n++)
Packit ae235b
    g_assert (first_numbers[n] == g_rand_int (rand));
Packit ae235b
Packit ae235b
  g_rand_set_seed (rand, 2);
Packit ae235b
  g_rand_set_seed_array (rand, seed_array, G_N_ELEMENTS (seed_array));
Packit ae235b
Packit ae235b
  for (n = 0; n < G_N_ELEMENTS (array_outputs); n++)
Packit ae235b
    g_assert (array_outputs[n] == g_rand_int (rand));
Packit ae235b
Packit ae235b
  copy = g_rand_copy (rand);
Packit ae235b
  for (n = 0; n < 100; n++)
Packit ae235b
    g_assert (g_rand_int (copy) == g_rand_int (rand));
Packit ae235b
Packit ae235b
  for (n = 1; n < 100000; n++)
Packit ae235b
    {
Packit ae235b
      gint32 i;
Packit ae235b
      gdouble d;
Packit ae235b
      gboolean b;
Packit ae235b
Packit ae235b
      i = g_rand_int_range (rand, 8,16);
Packit ae235b
      g_assert (i >= 8 && i < 16);
Packit ae235b
      
Packit ae235b
      i = g_random_int_range (8,16);
Packit ae235b
      g_assert (i >= 8 && i < 16);
Packit ae235b
Packit ae235b
      d = g_rand_double (rand);
Packit ae235b
      g_assert (d >= 0 && d < 1);
Packit ae235b
Packit ae235b
      d = g_random_double ();
Packit ae235b
      g_assert (d >= 0 && d < 1);
Packit ae235b
Packit ae235b
      d = g_rand_double_range (rand, -8, 32);
Packit ae235b
      g_assert (d >= -8 && d < 32);
Packit ae235b
 
Packit ae235b
      d = g_random_double_range (-8, 32);
Packit ae235b
      g_assert (d >= -8 && d < 32);
Packit ae235b
 
Packit ae235b
      b = g_random_boolean ();
Packit ae235b
      g_assert (b == TRUE || b  == FALSE);
Packit ae235b
 
Packit ae235b
      b = g_rand_boolean (rand);
Packit ae235b
      g_assert (b == TRUE || b  == FALSE);     
Packit ae235b
    }
Packit ae235b
Packit ae235b
  /* Statistical sanity check, count the number of ones
Packit ae235b
   * when getting random numbers in range [0,3) and see
Packit ae235b
   * that it must be semi-close to 0.25 with a VERY large
Packit ae235b
   * probability */
Packit ae235b
  ones = 0;
Packit ae235b
  for (n = 1; n < 100000; n++)
Packit ae235b
    {
Packit ae235b
      if (g_random_int_range (0, 4) == 1)
Packit ae235b
        ones ++;
Packit ae235b
    }
Packit ae235b
Packit ae235b
  proportion = (double)ones / (double)100000;
Packit ae235b
  /* 0.025 is overkill, but should suffice to test for some unreasonability */
Packit ae235b
  g_assert (ABS (proportion - 0.25) < 0.025);
Packit ae235b
Packit ae235b
  g_rand_free (rand);
Packit ae235b
  g_rand_free (copy);
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
test_double_range (void)
Packit ae235b
{
Packit ae235b
  gdouble d;
Packit ae235b
Packit ae235b
  g_test_bug ("502560");
Packit ae235b
Packit ae235b
  d = g_random_double_range (-G_MAXDOUBLE, G_MAXDOUBLE);
Packit ae235b
Packit ae235b
  g_assert (-G_MAXDOUBLE <= d);
Packit ae235b
  g_assert (d < G_MAXDOUBLE);
Packit ae235b
}
Packit ae235b
Packit ae235b
int
Packit ae235b
main (int   argc,
Packit ae235b
      char *argv[])
Packit ae235b
{
Packit ae235b
  g_test_init (&argc, &argv, NULL);
Packit ae235b
  g_test_bug_base ("http://bugzilla.gnome.org/");
Packit ae235b
Packit ae235b
  g_test_add_func ("/rand/test-rand", test_rand);
Packit ae235b
  g_test_add_func ("/rand/double-range", test_double_range);
Packit ae235b
Packit ae235b
  return g_test_run();
Packit ae235b
}