1 /* Test file for mpfr_nrandom
2
3 Copyright 2011-2023 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramba projects, INRIA.
5
6 This file is part of the GNU MPFR Library.
7
8 The GNU MPFR Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12
13 The GNU MPFR Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
20 https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22
23 #include "mpfr-test.h"
24
25 static void
test_special(mpfr_prec_t p)26 test_special (mpfr_prec_t p)
27 {
28 mpfr_t x;
29 int inexact;
30
31 mpfr_init2 (x, p);
32
33 inexact = mpfr_nrandom (x, RANDS, MPFR_RNDN);
34 if (inexact == 0)
35 {
36 printf ("Error: mpfr_nrandom() returns a zero ternary value.\n");
37 exit (1);
38 }
39
40 mpfr_clear (x);
41 }
42
43 #define NRES 10
44
45 static const char *res[NRES] = {
46 "-2.07609e2d96da78b2d6bea3ab30d4359222a82f8a35e4e4464303ad4808f57458@0",
47 "1.a4650a963ab9f266ed009ee96c8788f6b88212f5f2a4d4aef65db2a9e57c44bc@-1",
48 "c.0b3cda7f370a36febed972dbb47f2503f7e08a651edbf12d0303d968257841b0@-1",
49 "-7.4dffd19868c4bc2ec5b6c8311e0f190e1c97b575b7fdabec897e5de2a1d802b8@-1",
50 "1.40f6204ded71a4346ed17094863347b8c735e62712cc0b4d0c5402ee310d9714@0",
51 "-3.09fd2a1fc234e23bfa048dbf1e7850ac6cbea2514a0f3ce011e964d9f331cbcc@-1",
52 "-1.104e769aadb5fce5a7ad1c546e91b889829a76920c7cc7ac4cbd12009451ce90@0",
53 "3.0a08181e342b02187463c0025f895b41ddb7076c5bf157e3b898e9248baf4ad4@-1",
54 "-d.44fda7a51276b722ebc88dd016b7d9d7ea5ba682282a42cdef6948312e5dcf70@-1",
55 "1.5bf69aff31bb3e6430cc263fdd45ef2c70a779984e764524bc35a9cb4a430dd0@0" };
56
57 /* If checkval is true, check the obtained results by using a fixed seed
58 for reproducibility. */
59 static void
test_nrandom(long nbtests,mpfr_prec_t prec,mpfr_rnd_t rnd,int verbose,int checkval)60 test_nrandom (long nbtests, mpfr_prec_t prec, mpfr_rnd_t rnd,
61 int verbose, int checkval)
62 {
63 gmp_randstate_t s;
64 mpfr_t *t;
65 int i, inexact;
66
67 if (checkval)
68 {
69 gmp_randinit_default (s);
70 gmp_randseed_ui (s, 17);
71 nbtests = NRES;
72 }
73
74 t = (mpfr_t *) tests_allocate (nbtests * sizeof (mpfr_t));
75
76 for (i = 0; i < nbtests; ++i)
77 mpfr_init2 (t[i], prec);
78
79 for (i = 0; i < nbtests; i++)
80 {
81 inexact = mpfr_nrandom (t[i], checkval ? s : RANDS, MPFR_RNDN);
82
83 if (checkval && mpfr_cmp_str (t[i], res[i], 16, MPFR_RNDN) != 0)
84 {
85 printf ("Unexpected value in test_nrandom().\n"
86 "Expected %s\n"
87 "Got ", res[i]);
88 mpfr_out_str (stdout, 16, 0, t[i], MPFR_RNDN);
89 printf ("\n");
90 exit (1);
91 }
92
93 if (inexact == 0)
94 {
95 /* one call in the loop pretended to return an exact number! */
96 printf ("Error: mpfr_nrandom() returns a zero ternary value.\n");
97 exit (1);
98 }
99 }
100
101 #if defined(HAVE_STDARG) && !defined(MPFR_USE_MINI_GMP)
102 if (verbose)
103 {
104 mpfr_t av, va, tmp;
105
106 mpfr_init2 (av, prec);
107 mpfr_init2 (va, prec);
108 mpfr_init2 (tmp, prec);
109
110 mpfr_set_ui (av, 0, MPFR_RNDN);
111 mpfr_set_ui (va, 0, MPFR_RNDN);
112 for (i = 0; i < nbtests; ++i)
113 {
114 mpfr_add (av, av, t[i], MPFR_RNDN);
115 mpfr_sqr (tmp, t[i], MPFR_RNDN);
116 mpfr_add (va, va, tmp, MPFR_RNDN);
117 }
118 mpfr_div_ui (av, av, nbtests, MPFR_RNDN);
119 mpfr_div_ui (va, va, nbtests, MPFR_RNDN);
120 mpfr_sqr (tmp, av, MPFR_RNDN);
121 mpfr_sub (va, va, av, MPFR_RNDN);
122
123 mpfr_printf ("Average = %.5Rf\nVariance = %.5Rf\n", av, va);
124 mpfr_clear (av);
125 mpfr_clear (va);
126 mpfr_clear (tmp);
127 }
128 #endif /* HAVE_STDARG */
129
130 for (i = 0; i < nbtests; ++i)
131 mpfr_clear (t[i]);
132 tests_free (t, nbtests * sizeof (mpfr_t));
133 if (checkval)
134 gmp_randclear (s);
135 return;
136 }
137
138
139 int
main(int argc,char * argv[])140 main (int argc, char *argv[])
141 {
142 long nbtests;
143 int verbose;
144
145 tests_start_mpfr ();
146
147 verbose = 0;
148 nbtests = 10;
149 if (argc > 1)
150 {
151 /* Number of values in argument. Note that the mpfr_clear loop above
152 is in O(n^2) until the FIXME for tests_memory_find() in memory.c
153 is resolved (the search in tests_memory_find() is in O(n), while
154 it could be in almost constant time). */
155 long a = atol (argv[1]);
156 verbose = 1;
157 if (a != 0)
158 nbtests = a;
159 }
160
161 test_nrandom (nbtests, 420, MPFR_RNDN, verbose, 0);
162
163 #ifndef MPFR_USE_MINI_GMP
164 /* The random generator in mini-gmp is not deterministic. */
165 test_nrandom (0, 256, MPFR_RNDN, 0, 1);
166 #endif /* MPFR_USE_MINI_GMP */
167
168 test_special (2);
169 test_special (42000);
170
171 tests_end_mpfr ();
172 return 0;
173 }
174