1/* Test file for mpfr_const_log2.
2
3Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4Contributed by the Arenaire and Cacao projects, INRIA.
5
6This file is part of the GNU MPFR Library.
7
8The GNU MPFR Library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as published by
10the Free Software Foundation; either version 3 of the License, or (at your
11option) any later version.
12
13The GNU MPFR Library is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16License for more details.
17
18You should have received a copy of the GNU Lesser General Public License
19along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22
23#include <stdio.h>
24#include <stdlib.h>
25
26#include "mpfr-test.h"
27
28/* tlog2 [prec] [rnd] [0 = no print] */
29
30static void
31check (mpfr_prec_t p0, mpfr_prec_t p1)
32{
33  mpfr_t x, y, z;
34  mpfr_rnd_t rnd;
35  int dif;
36
37  mpfr_init (x);
38  mpfr_init (y);
39  mpfr_init2 (z, p1 + 10);
40  mpfr_const_log2 (z, MPFR_RNDN);
41  mpfr_clear_cache (__gmpfr_cache_const_log2);
42
43  for (; p0<=p1; p0++)
44    {
45      mpfr_set_prec (x, p0);
46      mpfr_set_prec (y, p0);
47        {
48          rnd = RND_RAND ();
49          mpfr_const_log2 (x, rnd);
50          mpfr_set (y, z, rnd);
51          if ((dif = mpfr_cmp (x, y))
52              && mpfr_can_round (z, mpfr_get_prec(z), MPFR_RNDN,
53                                                 rnd, p0))
54            {
55              printf ("mpfr_const_log2 fails for prec=%u, rnd=%s Diff=%d\n",
56                      (unsigned int) p0, mpfr_print_rnd_mode (rnd), dif);
57              printf ("expected "), mpfr_dump (y);
58              printf ("got      "), mpfr_dump (x);
59              exit (1);
60            }
61        }
62    }
63
64  mpfr_clear (x);
65  mpfr_clear (y);
66  mpfr_clear (z);
67}
68
69static void
70check_large (void)
71{
72  mpfr_t x, y;
73  mpfr_init2 (x, 25000);
74  mpfr_init2 (y, 26000);
75  (mpfr_const_log2) (x, MPFR_RNDN); /* First one ! */
76  (mpfr_const_log2) (y, MPFR_RNDN); /* Then the other - cache - */
77  mpfr_prec_round (y, 25000, MPFR_RNDN);
78  if (mpfr_cmp (x, y))
79    {
80      printf ("const_log2: error for large prec\n");
81      exit (1);
82    }
83
84  /* worst-case with 15 successive ones after last bit,
85     to exercise can_round loop */
86  mpfr_set_prec (x, 26249);
87  mpfr_const_log2 (x, MPFR_RNDZ);
88
89  mpfr_clears (x, y, (mpfr_ptr) 0);
90}
91
92static void
93check_cache (void)
94{
95  mpfr_t x;
96  int i;
97
98  mpfr_init2 (x, 195);
99  mpfr_free_cache ();
100  i = mpfr_const_log2 (x, MPFR_RNDN);
101  if (i == 0)
102    {
103      printf("Error for log2. Invalid ternary value (1).\n");
104      exit (1);
105    }
106  mpfr_set_prec (x, 194);
107  i = mpfr_const_log2 (x, MPFR_RNDN);
108  if (i == 0)
109    {
110      printf("Error for log2. Invalid ternary value (2).\n");
111      exit (1);
112    }
113
114  mpfr_free_cache ();
115  mpfr_set_prec (x, 9);
116  mpfr_const_log2 (x, MPFR_RNDN);
117  mpfr_set_prec (x, 8);
118  mpfr_const_log2 (x, MPFR_RNDN);
119  if (mpfr_cmp_str (x, "0.10110001E0", 2, MPFR_RNDN))
120    {
121      printf("Error for log2. Wrong rounding.\n");
122      exit (1);
123    }
124
125  mpfr_clear (x);
126}
127
128/* Wrapper for tgeneric */
129static int
130my_const_log2 (mpfr_ptr x, mpfr_srcptr y, mpfr_rnd_t r)
131{
132  return mpfr_const_log2 (x, r);
133}
134
135#define RAND_FUNCTION(x) mpfr_set_ui ((x), 0, MPFR_RNDN)
136#define TEST_FUNCTION my_const_log2
137#include "tgeneric.c"
138
139int
140main (int argc, char *argv[])
141{
142  mpfr_t x;
143  int p;
144  mpfr_rnd_t rnd;
145
146  tests_start_mpfr ();
147
148  p = (argc>1) ? atoi(argv[1]) : 53;
149  rnd = (argc>2) ? (mpfr_rnd_t) atoi(argv[2]) : MPFR_RNDZ;
150
151  mpfr_init (x);
152
153  check (2, 1000);
154
155  /* check precision of 2 bits */
156  mpfr_set_prec (x, 2);
157  mpfr_const_log2 (x, MPFR_RNDN);
158  if (mpfr_cmp_ui_2exp(x, 3, -2)) /* 3*2^-2 */
159    {
160      printf ("mpfr_const_log2 failed for prec=2, rnd=MPFR_RNDN\n"
161              "expected 0.75, got ");
162      mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN);
163      putchar('\n');
164      exit (1);
165    }
166
167  if (argc>=2)
168    {
169      mpfr_set_prec (x, p);
170      mpfr_const_log2 (x, rnd);
171      printf ("log(2)=");
172      mpfr_out_str (stdout, 10, 0, x, rnd);
173      puts ("");
174    }
175
176  mpfr_set_prec (x, 53);
177  mpfr_const_log2 (x, MPFR_RNDZ);
178  if (mpfr_cmp_str1 (x, "6.9314718055994530941e-1") )
179    {
180      printf ("mpfr_const_log2 failed for prec=53\n");
181      exit (1);
182    }
183
184  mpfr_set_prec (x, 32);
185  mpfr_const_log2 (x, MPFR_RNDN);
186  if (mpfr_cmp_str1 (x, "0.69314718060195446"))
187    {
188      printf ("mpfr_const_log2 failed for prec=32\n");
189      exit (1);
190    }
191
192  mpfr_clear(x);
193
194  check_large();
195  check_cache ();
196
197  test_generic (2, 200, 1);
198
199  tests_end_mpfr ();
200  return 0;
201}
202