xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tnrandom.c (revision ba125506a622fe649968631a56eba5d42ff57863)
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