1 /* Handle seed for random numbers.
3 Copyright (C) 2008, 2009 Philippe Th\'eveny, Paul Zimmermann, Andreas Enge
5 This file is part of the MPC Library.
7 The MPC Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or (at your
10 option) any later version.
12 The MPC Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with the MPC Library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20 MA 02111-1307, USA. */
22 /* Put test_start at the beginning of your test function and
24 These are an adaptation of those of MPFR. */
28 #include "mpc-tests.h"
32 #ifdef TIME_WITH_SYS_TIME
33 # include <sys/time.h>
36 # ifdef HAVE_SYS_TIME_H
37 # include <sys/time.h>
43 gmp_randstate_t rands;
44 char rands_initialized;
49 char *environment_seed;
52 tests_memory_start ();
54 if (rands_initialized)
57 "Put test_start at the beginning of your test function.\n");
61 gmp_randinit_default (rands);
62 rands_initialized = 1;
64 environment_seed = getenv ("GMP_CHECK_RANDOMIZE");
65 if (environment_seed == NULL)
66 gmp_randseed_ui (rands, 0xfac11e);
69 seed = atoi (environment_seed);
70 if (seed == 0 || seed == 1)
74 gettimeofday (&tv, NULL);
75 seed = tv.tv_sec + tv.tv_usec;
81 gmp_randseed_ui (rands, seed);
82 printf ("Seed GMP_CHECK_RANDOMIZE=%lu "
83 "(include this in bug reports)\n", seed);
87 printf ("Re-seeding with GMP_CHECK_RANDOMIZE=%lu\n", seed);
88 gmp_randseed_ui (rands, seed);
96 if (rands_initialized)
98 rands_initialized = 0;
99 gmp_randclear (rands);
105 /* Set z to a non zero value random value with absolute values of Re(z) and
106 Im(z) either zero (but not both in the same time) or otherwise greater than
107 or equal to 2^{emin-1} and less than 2^emax.
108 Each part is negative with probability equal to NEGATIVE_PROBABILITY / 256.
109 The result has one zero part (but never the two of them) with probability
110 equal to ZERO_PROBABILITY / 256.
113 test_default_random (mpc_ptr z, mp_exp_t emin, mp_exp_t emax,
114 unsigned int negative_probability,
115 unsigned int zero_probability)
117 const unsigned long range = (long)emax - (long)emin + 1;
120 if (!rands_initialized)
123 "Put test_start at the beginning of your test function.\n");
129 mpc_urandom (z, rands);
130 } while (mpfr_zero_p (MPC_RE (z)) || mpfr_zero_p (MPC_IM (z)));
132 if (zero_probability > 256)
133 zero_probability = 256;
134 r = gmp_urandomb_ui (rands, 19);
135 if ((r & 0x1FF) < zero_probability
136 || ((r >> 9) & 0x1FF) < zero_probability)
138 int zero_re_p = (r & 0x1FF) < zero_probability;
139 int zero_im_p = ((r >> 9) & 0x1FF) < zero_probability;
141 if (zero_re_p && zero_im_p)
143 /* we just want one zero part. */
144 zero_re_p = (r >> 18) & 1;
145 zero_im_p = !zero_re_p;
148 mpfr_set_ui (MPC_RE (z), 0, GMP_RNDN);
150 mpfr_set_ui (MPC_IM (z), 0, GMP_RNDN);
152 if (!mpfr_zero_p (MPC_RE (z)))
153 mpfr_set_exp (MPC_RE (z), (mp_exp_t) gmp_urandomm_ui (rands, range) + emin);
155 if (!mpfr_zero_p (MPC_IM (z)))
156 mpfr_set_exp (MPC_IM (z), (mp_exp_t) gmp_urandomm_ui (rands, range) + emin);
158 if (negative_probability > 256)
159 negative_probability = 256;
160 r = gmp_urandomb_ui (rands, 16);
161 if ((r & 0xFF) < negative_probability)
162 mpfr_neg (MPC_RE (z), MPC_RE (z), GMP_RNDN);
163 if (((r>>8) & 0xFF) < negative_probability)
164 mpfr_neg (MPC_IM (z), MPC_IM (z), GMP_RNDN);