(root)/
glib-2.79.0/
glib/
tests/
rand.c
       1  /* Unit tests for grand
       2   * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
       3   *
       4   * SPDX-License-Identifier: LicenseRef-old-glib-tests
       5   *
       6   * This work is provided "as is"; redistribution and modification
       7   * in whole or in part, in any medium, physical or electronic is
       8   * permitted without restriction.
       9   *
      10   * This work is distributed in the hope that it will be useful,
      11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      13   *
      14   * In no event shall the authors or contributors be liable for any
      15   * direct, indirect, incidental, special, exemplary, or consequential
      16   * damages (including, but not limited to, procurement of substitute
      17   * goods or services; loss of use, data, or profits; or business
      18   * interruption) however caused and on any theory of liability, whether
      19   * in contract, strict liability, or tort (including negligence or
      20   * otherwise) arising in any way out of the use of this software, even
      21   * if advised of the possibility of such damage.
      22   */
      23  
      24  #include "glib.h"
      25  
      26  /* Outputs tested against the reference implementation mt19937ar.c from
      27   * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
      28   */
      29  
      30  /* Tests for a simple seed, first number is the seed */
      31  const guint32 first_numbers[] = 
      32  {
      33    0x7a7a7a7a,
      34    0xfdcc2d54,
      35    0x3a279ceb,
      36    0xc4d39c33,
      37    0xf31895cd,
      38    0x46ca0afc,
      39    0x3f5484ff,
      40    0x54bc9557,
      41    0xed2c24b1,
      42    0x84062503,
      43    0x8f6404b3,
      44    0x599a94b3,
      45    0xe46d03d5,
      46    0x310beb78,
      47    0x7bee5d08,
      48    0x760d09be,
      49    0x59b6e163,
      50    0xbf6d16ec,
      51    0xcca5fb54,
      52    0x5de7259b,
      53    0x1696330c,
      54  };
      55  
      56  /* array seed */
      57  const guint32 seed_array[] =
      58  {
      59    0x6553375f,
      60    0xd6b8d43b,
      61    0xa1e7667f,
      62    0x2b10117c
      63  };
      64  
      65  /* tests for the array seed */
      66  const guint32 array_outputs[] =
      67  {
      68    0xc22b7dc3,
      69    0xfdecb8ae,
      70    0xb4af0738,
      71    0x516bc6e1,
      72    0x7e372e91,
      73    0x2d38ff80,
      74    0x6096494a,
      75    0xd162d5a8,
      76    0x3c0aaa0d,
      77    0x10e736ae
      78  };
      79  
      80  static void
      81  test_rand (void)
      82  {
      83    guint n;
      84    guint ones;
      85    double proportion;
      86    GRand *rand;
      87    GRand *copy;
      88  
      89    rand = g_rand_new_with_seed (first_numbers[0]);
      90  
      91    for (n = 1; n < G_N_ELEMENTS (first_numbers); n++)
      92      g_assert_cmpuint (first_numbers[n], ==, g_rand_int (rand));
      93  
      94    g_rand_set_seed (rand, 2);
      95    g_rand_set_seed_array (rand, seed_array, G_N_ELEMENTS (seed_array));
      96  
      97    for (n = 0; n < G_N_ELEMENTS (array_outputs); n++)
      98      g_assert_cmpuint (array_outputs[n], ==, g_rand_int (rand));
      99  
     100    copy = g_rand_copy (rand);
     101    for (n = 0; n < 100; n++)
     102      g_assert_cmpuint (g_rand_int (copy), ==, g_rand_int (rand));
     103  
     104    for (n = 1; n < 100000; n++)
     105      {
     106        gint32 i;
     107        gdouble d;
     108        gboolean b;
     109  
     110        i = g_rand_int_range (rand, 8,16);
     111        g_assert_cmpint (i, >=, 8);
     112        g_assert_cmpint (i, <, 16);
     113        
     114        i = g_random_int_range (8,16);
     115        g_assert_cmpint (i, >=, 8);
     116        g_assert_cmpint (i, <, 16);
     117  
     118        d = g_rand_double (rand);
     119        g_assert_cmpfloat (d, >=, 0.0);
     120        g_assert_cmpfloat (d, <, 1.0);
     121  
     122        d = g_random_double ();
     123        g_assert_cmpfloat (d, >=, 0.0);
     124        g_assert_cmpfloat (d, <, 1.0);
     125  
     126        d = g_rand_double_range (rand, -8, 32);
     127        g_assert_cmpfloat (d, >=, -8.0);
     128        g_assert_cmpfloat (d, <, 32.0);
     129   
     130        d = g_random_double_range (-8, 32);
     131        g_assert_cmpfloat (d, >=, -8.0);
     132        g_assert_cmpfloat (d, <, 32.0);
     133   
     134        b = g_random_boolean ();
     135        g_assert_true (b == TRUE || b  == FALSE);
     136   
     137        b = g_rand_boolean (rand);
     138        g_assert_true (b == TRUE || b  == FALSE);
     139      }
     140  
     141    /* Statistical sanity check, count the number of ones
     142     * when getting random numbers in range [0,3) and see
     143     * that it must be semi-close to 0.25 with a VERY large
     144     * probability */
     145    ones = 0;
     146    for (n = 1; n < 100000; n++)
     147      {
     148        if (g_random_int_range (0, 4) == 1)
     149          ones ++;
     150      }
     151  
     152    proportion = (double)ones / (double)100000;
     153    /* 0.025 is overkill, but should suffice to test for some unreasonability */
     154    g_assert_cmpfloat (ABS (proportion - 0.25), <, 0.025);
     155  
     156    g_rand_free (rand);
     157    g_rand_free (copy);
     158  }
     159  
     160  static void
     161  test_double_range (void)
     162  {
     163    gdouble d;
     164  
     165    g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=502560");
     166  
     167    d = g_random_double_range (-G_MAXDOUBLE, G_MAXDOUBLE);
     168  
     169    g_assert_cmpfloat (-G_MAXDOUBLE, <=, d);
     170    g_assert_cmpfloat (d, <, G_MAXDOUBLE);
     171  }
     172  
     173  int
     174  main (int   argc,
     175        char *argv[])
     176  {
     177    g_test_init (&argc, &argv, NULL);
     178  
     179    g_test_add_func ("/rand/test-rand", test_rand);
     180    g_test_add_func ("/rand/double-range", test_double_range);
     181  
     182    return g_test_run();
     183  }