xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tconst_log2.c (revision ba125506a622fe649968631a56eba5d42ff57863)
1 /* Test file for mpfr_const_log2.
2 
3 Copyright 1999, 2001-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 /* tlog2 [prec] [rnd] [0 = no print] */
26 
27 static void
check(mpfr_prec_t p0,mpfr_prec_t p1)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
check_large(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
check_cache(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
my_const_log2(mpfr_ptr x,mpfr_srcptr y,mpfr_rnd_t r)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 static void
exercise_Ziv(void)154 exercise_Ziv (void)
155 {
156   mpfr_t x, y;
157   int inex;
158 
159   mpfr_init2 (x, 92);
160   mpfr_init2 (y, 92);
161   inex = mpfr_const_log2 (x, MPFR_RNDN);
162   mpfr_set_str_binary (y, "0.1011000101110010000101111111011111010001110011110111100110101011110010011110001110110011101");
163   MPFR_ASSERTN(mpfr_equal_p (x, y));
164   MPFR_ASSERTN(inex > 0);
165   mpfr_clear (x);
166   mpfr_clear (y);
167 }
168 
169 int
main(int argc,char * argv[])170 main (int argc, char *argv[])
171 {
172   mpfr_t x;
173   int p;
174   mpfr_rnd_t rnd;
175 
176   tests_start_mpfr ();
177 
178   p = (argc>1) ? atoi(argv[1]) : 53;
179   rnd = (argc>2) ? (mpfr_rnd_t) atoi(argv[2]) : MPFR_RNDN;
180 
181   mpfr_init (x);
182 
183   /* increase the 2nd argument to say 300000 to perform the exhaustive search
184      in src/const_log2.c */
185   check (MPFR_PREC_MIN, 1000);
186 
187   /* check precision of 2 bits */
188   mpfr_set_prec (x, 2);
189   mpfr_const_log2 (x, MPFR_RNDN);
190   if (mpfr_cmp_ui_2exp(x, 3, -2)) /* 3*2^-2 */
191     {
192       printf ("mpfr_const_log2 failed for prec=2, rnd=MPFR_RNDN\n"
193               "expected 0.75, got ");
194       mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN);
195       putchar('\n');
196       exit (1);
197     }
198 
199   if (argc >= 2)
200     {
201       mpfr_set_prec (x, p);
202       mpfr_const_log2 (x, rnd);
203       mpfr_out_str (stdout, 10, 0, x, rnd);
204       puts ("");
205     }
206 
207   exercise_Ziv ();
208 
209   mpfr_set_prec (x, 53);
210   mpfr_const_log2 (x, MPFR_RNDZ);
211   if (mpfr_cmp_str1 (x, "6.9314718055994530941e-1") )
212     {
213       printf ("mpfr_const_log2 failed for prec=53\n");
214       exit (1);
215     }
216 
217   mpfr_set_prec (x, 32);
218   mpfr_const_log2 (x, MPFR_RNDN);
219   if (mpfr_cmp_str1 (x, "0.69314718060195446"))
220     {
221       printf ("mpfr_const_log2 failed for prec=32\n");
222       exit (1);
223     }
224 
225   mpfr_clear (x);
226 
227   check_large ();
228   check_cache ();
229 
230   test_generic (MPFR_PREC_MIN, 200, 1);
231 
232   tests_end_mpfr ();
233   return 0;
234 }
235