resetting manifest requested domain to floor
[platform/upstream/mpc.git] / tests / random.c
1 /* random.c -- Handle seed for random numbers.
2
3 // Copyright (C) 2008, 2009, 2010, 2011 INRIA
4
5 This file is part of GNU MPC.
6
7 GNU MPC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU Lesser General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11
12 GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15 more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with this program. If not, see http://www.gnu.org/licenses/ .
19 */
20
21 /* Put test_start at the beginning of your test function and
22    test_end at the end.
23    These are an adaptation of those of MPFR. */
24
25 #include "config.h"
26 #include <stdlib.h>
27 #include "mpc-tests.h"
28
29
30 #ifdef TIME_WITH_SYS_TIME
31 # include <sys/time.h>
32 # include <time.h>
33 #else
34 # ifdef HAVE_SYS_TIME_H
35 #  include <sys/time.h>
36 # else
37 #  include <time.h>
38 # endif
39 #endif
40
41 gmp_randstate_t  rands;
42 static char      rands_initialized;
43
44 void
45 test_start (void)
46 {
47   char *environment_seed;
48   unsigned long seed;
49
50   if (rands_initialized)
51     {
52       fprintf (stderr,
53                "Put test_start at the beginning of your test function.\n");
54       exit (1);
55     }
56
57   gmp_randinit_default (rands);
58   rands_initialized = 1;
59
60   environment_seed = getenv ("GMP_CHECK_RANDOMIZE");
61   if (environment_seed == NULL)
62       gmp_randseed_ui (rands, 0xfac11e);
63   else
64     {
65       seed = (unsigned long int) atoi (environment_seed);
66       if (seed == 0 || seed == 1)
67         {
68 #if defined HAVE_GETTIMEOFDAY
69           struct timeval  tv;
70           gettimeofday (&tv, NULL);
71           seed = (unsigned long int) (tv.tv_sec + tv.tv_usec);
72 #else
73           time_t  tv;
74           time (&tv);
75           seed = (unsigned long int) tv;
76 #endif
77           gmp_randseed_ui (rands, seed);
78           printf ("Seed GMP_CHECK_RANDOMIZE=%lu "
79                   "(include this in bug reports)\n", seed);
80         }
81       else
82         {
83           printf ("Re-seeding with GMP_CHECK_RANDOMIZE=%lu\n", seed);
84           gmp_randseed_ui (rands, seed);
85         }
86     }
87 }
88
89 void
90 test_end (void)
91 {
92   if (rands_initialized)
93     {
94       rands_initialized = 0;
95       gmp_randclear (rands);
96     }
97   mpfr_free_cache ();
98 }
99
100 /* Set z to a non zero value random value with absolute values of Re(z) and
101    Im(z) either zero (but not both in the same time) or otherwise greater than
102    or equal to 2^{emin-1} and less than 2^emax.
103    Each part is negative with probability equal to NEGATIVE_PROBABILITY / 256.
104    The result has one zero part (but never the two of them) with probability
105    equal to ZERO_PROBABILITY / 256.
106 */
107 void
108 test_default_random (mpc_ptr z, mpfr_exp_t emin, mpfr_exp_t emax,
109                      unsigned int negative_probability,
110                      unsigned int zero_probability)
111 {
112   const unsigned long range = (unsigned long int) (emax - emin) + 1;
113   unsigned long r;
114
115   if (!rands_initialized)
116     {
117       fprintf (stderr,
118                "Put test_start at the beginning of your test function.\n");
119       exit (1);
120     }
121
122   do
123     {
124       mpc_urandom (z, rands);
125     } while (mpfr_zero_p (mpc_realref (z)) || mpfr_zero_p (mpc_imagref (z)));
126
127   if (zero_probability > 256)
128     zero_probability = 256;
129   r = gmp_urandomb_ui (rands, 19);
130   if ((r & 0x1FF) < zero_probability
131       || ((r >> 9) & 0x1FF) < zero_probability)
132     {
133       int zero_re_p = (r & 0x1FF) < zero_probability;
134       int zero_im_p = ((r >> 9) & 0x1FF) < zero_probability;
135
136       if (zero_re_p && zero_im_p)
137         {
138           /* we just want one zero part. */
139           zero_re_p = (r >> 18) & 1;
140           zero_im_p = !zero_re_p;
141         }
142       if (zero_re_p)
143         mpfr_set_ui (mpc_realref (z), 0, GMP_RNDN);
144       if (zero_im_p)
145         mpfr_set_ui (mpc_imagref (z), 0, GMP_RNDN);
146     }
147   if (!mpfr_zero_p (mpc_realref (z)))
148     mpfr_set_exp (mpc_realref (z), (mpfr_exp_t) gmp_urandomm_ui (rands, range) + emin);
149
150   if (!mpfr_zero_p (mpc_imagref (z)))
151     mpfr_set_exp (mpc_imagref (z), (mpfr_exp_t) gmp_urandomm_ui (rands, range) + emin);
152
153   if (negative_probability > 256)
154     negative_probability = 256;
155   r = gmp_urandomb_ui (rands, 16);
156   if ((r & 0xFF) < negative_probability)
157     mpfr_neg (mpc_realref (z), mpc_realref (z), GMP_RNDN);
158   if (((r>>8) & 0xFF) < negative_probability)
159     mpfr_neg (mpc_imagref (z), mpc_imagref (z), GMP_RNDN);
160 }