1/* Test file for mpfr_set_f.
2
3Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
4Contributed by the AriC and Caramel 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#include <limits.h> /* for ULONG_MAX */
26
27#include "mpfr-test.h"
28
29int
30main (void)
31{
32  mpfr_t x, u;
33  mpf_t y, z;
34  mpfr_exp_t emax;
35  unsigned long k, pr;
36  int r, inexact;
37
38  tests_start_mpfr ();
39
40  mpf_init (y);
41  mpf_init (z);
42
43  mpf_set_d (y, 0.0);
44
45  /* check prototype of mpfr_init_set_f */
46  mpfr_init_set_f (x, y, MPFR_RNDN);
47  mpfr_set_prec (x, 100);
48  mpfr_set_f (x, y, MPFR_RNDN);
49
50  mpf_urandomb (y, RANDS, 10 * GMP_NUMB_BITS);
51  mpfr_set_f (x, y, RND_RAND ());
52
53  /* bug found by Jean-Pierre Merlet */
54  mpfr_set_prec (x, 256);
55  mpf_set_prec (y, 256);
56  mpfr_init2 (u, 256);
57  mpfr_set_str (u,
58                "7.f10872b020c49ba5e353f7ced916872b020c49ba5e353f7ced916872b020c498@2",
59                16, MPFR_RNDN);
60  mpf_set_str (y, "2033033E-3", 10); /* avoid 2033.033 which is
61                                        locale-sensitive */
62  mpfr_set_f (x, y, MPFR_RNDN);
63  if (mpfr_cmp (x, u))
64    {
65      printf ("mpfr_set_f failed for y=2033033E-3\n");
66      exit (1);
67    }
68  mpf_set_str (y, "-2033033E-3", 10); /* avoid -2033.033 which is
69                                         locale-sensitive */
70  mpfr_set_f (x, y, MPFR_RNDN);
71  mpfr_neg (u, u, MPFR_RNDN);
72  if (mpfr_cmp (x, u))
73    {
74      printf ("mpfr_set_f failed for y=-2033033E-3\n");
75      exit (1);
76    }
77
78  mpf_set_prec (y, 300);
79  mpf_set_str (y, "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111", -2);
80  mpf_mul_2exp (y, y, 600);
81  mpfr_set_prec (x, 300);
82  mpfr_set_f (x, y, MPFR_RNDN);
83  if (mpfr_check (x) == 0)
84    {
85      printf ("Error in mpfr_set_f: corrupted result\n");
86      mpfr_dump (x);
87      exit (1);
88    }
89  MPFR_ASSERTN(mpfr_cmp_ui_2exp (x, 1, 901) == 0);
90
91  /* random values */
92  for (k = 1; k <= 1000; k++)
93    {
94      pr = 2 + (randlimb () & 255);
95      mpf_set_prec (z, pr);
96      mpf_urandomb (z, RANDS, z->_mp_prec);
97      mpfr_set_prec (u, ((pr / GMP_NUMB_BITS + 1) * GMP_NUMB_BITS));
98      mpfr_set_f (u, z, MPFR_RNDN);
99      if (mpfr_cmp_f (u , z) != 0)
100        {
101          printf ("Error in mpfr_set_f:\n");
102          printf ("mpf (precision=%lu)=", pr);
103          mpf_out_str (stdout, 16, 0, z);
104          printf ("\nmpfr(precision=%lu)=",
105                  ((pr / GMP_NUMB_BITS + 1) * GMP_NUMB_BITS));
106          mpfr_out_str (stdout, 16, 0, u, MPFR_RNDN);
107          putchar ('\n');
108          exit (1);
109        }
110      mpfr_set_prec (x, pr);
111      mpfr_set_f (x, z, MPFR_RNDN);
112      mpfr_sub (u, u, x, MPFR_RNDN);
113      mpfr_abs (u, u, MPFR_RNDN);
114      if (mpfr_cmp_ui_2exp (u, 1, -pr - 1) > 0)
115        {
116          printf ("Error in mpfr_set_f: precision=%lu\n", pr);
117          printf ("mpf =");
118          mpf_out_str (stdout, 16, 0, z);
119          printf ("\nmpfr=");
120          mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN);
121          putchar ('\n');
122          exit (1);
123        }
124    }
125
126  /* Check for +0 */
127  mpfr_set_prec (x, 53);
128  mpf_set_prec (y, 53);
129  mpf_set_ui (y, 0);
130  for (r = 0 ; r < MPFR_RND_MAX ; r++)
131    {
132      int i;
133      for (i = -1; i <= 1; i++)
134        {
135          if (i)
136            mpfr_set_si (x, i, MPFR_RNDN);
137          inexact = mpfr_set_f (x, y, (mpfr_rnd_t) r);
138          if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact)
139            {
140              printf ("mpfr_set_f(x,0) failed for %s, i = %d\n",
141                      mpfr_print_rnd_mode ((mpfr_rnd_t) r), i);
142              exit (1);
143            }
144        }
145    }
146
147  /* coverage test */
148  mpf_set_prec (y, 2);
149  mpfr_set_prec (x, 3 * mp_bits_per_limb);
150  mpf_set_ui (y, 1);
151  for (r = 0; r < mp_bits_per_limb; r++)
152    {
153      mpfr_urandomb (x, RANDS); /* to fill low limbs with random data */
154      inexact = mpfr_set_f (x, y, MPFR_RNDN);
155      MPFR_ASSERTN(inexact == 0 && mpfr_cmp_ui_2exp (x, 1, r) == 0);
156      mpf_mul_2exp (y, y, 1);
157    }
158
159  mpf_set_ui (y, 1);
160  mpf_mul_2exp (y, y, ULONG_MAX);
161  mpfr_set_f (x, y, MPFR_RNDN);
162  mpfr_set_ui (u, 1, MPFR_RNDN);
163  mpfr_mul_2ui (u, u, ULONG_MAX, MPFR_RNDN);
164  if (!mpfr_equal_p (x, u))
165    {
166      printf ("Error: mpfr_set_f (x, y, MPFR_RNDN) for y = 2^ULONG_MAX\n");
167      exit (1);
168    }
169
170  emax = mpfr_get_emax ();
171
172  /* For mpf_mul_2exp, emax must fit in an unsigned long! */
173  if (emax >= 0 && emax <= ULONG_MAX)
174    {
175      mpf_set_ui (y, 1);
176      mpf_mul_2exp (y, y, emax);
177      mpfr_set_f (x, y, MPFR_RNDN);
178      mpfr_set_ui_2exp (u, 1, emax, MPFR_RNDN);
179      if (!mpfr_equal_p (x, u))
180        {
181          printf ("Error: mpfr_set_f (x, y, MPFR_RNDN) for y = 2^emax\n");
182          exit (1);
183        }
184    }
185
186  /* For mpf_mul_2exp, emax - 1 must fit in an unsigned long! */
187  if (emax >= 1 && emax - 1 <= ULONG_MAX)
188    {
189      mpf_set_ui (y, 1);
190      mpf_mul_2exp (y, y, emax - 1);
191      mpfr_set_f (x, y, MPFR_RNDN);
192      mpfr_set_ui_2exp (u, 1, emax - 1, MPFR_RNDN);
193      if (!mpfr_equal_p (x, u))
194        {
195          printf ("Error: mpfr_set_f (x, y, MPFR_RNDN) for y = 2^(emax-1)\n");
196          exit (1);
197        }
198    }
199
200  mpfr_clear (x);
201  mpfr_clear (u);
202  mpf_clear (y);
203  mpf_clear (z);
204
205  tests_end_mpfr ();
206  return 0;
207}
208