xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tconst_log2.c (revision 154bfe8e089c1a0a4e9ed8414f08d3da90949162)
1 /* Test file for mpfr_const_log2.
2 
3 Copyright 1999, 2001-2018 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 http://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 /* tlog2 [prec] [rnd] [0 = no print] */
26 
27 static void
28 check (mpfr_prec_t p0, mpfr_prec_t p1)
29 {
30   mpfr_t x, y, z;
31   int i, inex, inex_ref;
32 
33   mpfr_init (x);
34   mpfr_init (y);
35   mpfr_init2 (z, p1 + 10);
36   mpfr_const_log2 (z, MPFR_RNDN);
37   mpfr_clear_cache (__gmpfr_cache_const_log2);
38 
39   for (; p0 <= p1; p0++)
40     {
41       mpfr_set_prec (x, p0);
42       mpfr_set_prec (y, p0);
43       RND_LOOP_NO_RNDF (i)
44         {
45           mpfr_rnd_t rnd = (mpfr_rnd_t) i;
46           inex = mpfr_const_log2 (x, rnd);
47           inex_ref = mpfr_set (y, z, rnd);
48           if (! mpfr_can_round (z, mpfr_get_prec (z), MPFR_RNDN, rnd, p0))
49             {
50               printf ("increase guard precision in check()\n");
51               exit (1);
52             }
53           if (mpfr_cmp (x, y) || inex != inex_ref)
54             {
55               printf ("mpfr_const_log2 fails for prec=%u, rnd=%s\n",
56                       (unsigned int) p0, mpfr_print_rnd_mode (rnd));
57               printf ("expected "), mpfr_dump (y);
58               printf ("got      "), mpfr_dump (x);
59               printf ("expected inex = %d\n", inex_ref);
60               printf ("got      inex = %d\n", inex);
61               exit (1);
62             }
63         }
64     }
65 
66   mpfr_clear (x);
67   mpfr_clear (y);
68   mpfr_clear (z);
69 }
70 
71 static void
72 check_large (void)
73 {
74   mpfr_t x, y, z;
75 
76   mpfr_init2 (x, 25000);
77   mpfr_init2 (y, 26000);
78   mpfr_init2 (z, 26000);
79   (mpfr_const_log2) (x, MPFR_RNDN); /* First one ! */
80   (mpfr_const_log2) (y, MPFR_RNDN); /* Then the other - cache - */
81   mpfr_set (z, y, MPFR_RNDN);
82   mpfr_prec_round (y, 25000, MPFR_RNDN);
83   if (mpfr_cmp (x, y) != 0)
84     {
85       printf ("const_log2: error for large prec\n");
86       printf ("x = ");
87       mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
88       printf ("\n");
89       printf ("y = ");
90       mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
91       printf ("\n");
92       printf ("z = ");
93       mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN);
94       printf ("\n");
95       exit (1);
96     }
97 
98   /* worst-case with 15 successive ones after last bit,
99      to exercise can_round loop */
100   mpfr_set_prec (x, 26249);
101   mpfr_const_log2 (x, MPFR_RNDZ);
102 
103   mpfr_clears (x, y, z, (mpfr_ptr) 0);
104 }
105 
106 static void
107 check_cache (void)
108 {
109   mpfr_t x;
110   int i;
111 
112   mpfr_init2 (x, 195);
113   mpfr_free_cache ();
114   i = mpfr_const_log2 (x, MPFR_RNDN);
115   if (i == 0)
116     {
117       printf("Error for log2. Invalid ternary value (1).\n");
118       exit (1);
119     }
120   mpfr_set_prec (x, 194);
121   i = mpfr_const_log2 (x, MPFR_RNDN);
122   if (i == 0)
123     {
124       printf("Error for log2. Invalid ternary value (2).\n");
125       exit (1);
126     }
127 
128   mpfr_free_cache ();
129   mpfr_set_prec (x, 9);
130   mpfr_const_log2 (x, MPFR_RNDN);
131   mpfr_set_prec (x, 8);
132   mpfr_const_log2 (x, MPFR_RNDN);
133   if (mpfr_cmp_str (x, "0.10110001E0", 2, MPFR_RNDN))
134     {
135       printf("Error for log2. Wrong rounding.\n");
136       exit (1);
137     }
138 
139   mpfr_clear (x);
140 }
141 
142 /* Wrapper for tgeneric */
143 static int
144 my_const_log2 (mpfr_ptr x, mpfr_srcptr y, mpfr_rnd_t r)
145 {
146   return mpfr_const_log2 (x, r);
147 }
148 
149 #define RAND_FUNCTION(x) mpfr_set_ui ((x), 0, MPFR_RNDN)
150 #define TEST_FUNCTION my_const_log2
151 #include "tgeneric.c"
152 
153 int
154 main (int argc, char *argv[])
155 {
156   mpfr_t x;
157   int p;
158   mpfr_rnd_t rnd;
159 
160   tests_start_mpfr ();
161 
162   p = (argc>1) ? atoi(argv[1]) : 53;
163   rnd = (argc>2) ? (mpfr_rnd_t) atoi(argv[2]) : MPFR_RNDN;
164 
165   mpfr_init (x);
166 
167   /* increase the 2nd argument to say 300000 to perform the exhaustive search
168      in src/const_log2.c */
169   check (MPFR_PREC_MIN, 1000);
170 
171   /* check precision of 2 bits */
172   mpfr_set_prec (x, 2);
173   mpfr_const_log2 (x, MPFR_RNDN);
174   if (mpfr_cmp_ui_2exp(x, 3, -2)) /* 3*2^-2 */
175     {
176       printf ("mpfr_const_log2 failed for prec=2, rnd=MPFR_RNDN\n"
177               "expected 0.75, got ");
178       mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN);
179       putchar('\n');
180       exit (1);
181     }
182 
183   if (argc >= 2)
184     {
185       mpfr_set_prec (x, p);
186       mpfr_const_log2 (x, rnd);
187       mpfr_out_str (stdout, 10, 0, x, rnd);
188       puts ("");
189     }
190 
191   mpfr_set_prec (x, 53);
192   mpfr_const_log2 (x, MPFR_RNDZ);
193   if (mpfr_cmp_str1 (x, "6.9314718055994530941e-1") )
194     {
195       printf ("mpfr_const_log2 failed for prec=53\n");
196       exit (1);
197     }
198 
199   mpfr_set_prec (x, 32);
200   mpfr_const_log2 (x, MPFR_RNDN);
201   if (mpfr_cmp_str1 (x, "0.69314718060195446"))
202     {
203       printf ("mpfr_const_log2 failed for prec=32\n");
204       exit (1);
205     }
206 
207   mpfr_clear (x);
208 
209   check_large ();
210   check_cache ();
211 
212   test_generic (MPFR_PREC_MIN, 200, 1);
213 
214   tests_end_mpfr ();
215   return 0;
216 }
217