1/* Test file for mpz_set_fr / mpfr_get_z.
2
3Copyright 2004, 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
28static void
29check_diff (void)
30{
31  int inex;
32  mpfr_t x;
33  mpz_t  z;
34  mpfr_exp_t emin;
35
36  mpz_init   (z);
37  mpfr_init2 (x, 2);
38
39  mpfr_set_ui (x, 2047, MPFR_RNDU);
40  mpz_set_fr (z, x, MPFR_RNDN);
41  if (mpz_cmp_ui (z, 2048) != 0)
42    {
43      printf ("get_z RU 2048 failed\n");
44      exit (1);
45    }
46
47  mpfr_set_prec (x, 6);
48  mpfr_set_str (x, "17.5", 10, MPFR_RNDN);
49  inex = mpfr_get_z (z, x, MPFR_RNDN);
50  if (inex <= 0 || mpz_cmp_ui (z, 18) != 0)
51    {
52      printf ("get_z RN 17.5 failed\n");
53      exit (1);
54    }
55
56  /* save default emin */
57  emin = mpfr_get_emin ();;
58
59  mpfr_set_emin (17);
60  mpfr_set_ui (x, 0, MPFR_RNDN);
61  inex = mpfr_get_z (z, x, MPFR_RNDN);
62  if (inex != 0 || mpz_cmp_ui (z, 0) != 0)
63    {
64      printf ("get_z 0 failed\n");
65      exit (1);
66    }
67
68  /* restore default emin */
69  mpfr_set_emin (emin);
70
71  mpfr_clear (x);
72  mpz_clear  (z);
73}
74
75static void
76check_one (mpz_ptr z)
77{
78  int    inex;
79  int    sh, neg;
80  mpfr_t f;
81  mpz_t  got;
82
83  mpfr_init2 (f, MAX( mpz_sizeinbase (z, 2), MPFR_PREC_MIN) );
84  mpz_init (got);
85
86  for (sh = -2*GMP_NUMB_BITS ; sh < 2*GMP_NUMB_BITS ; sh++)
87    {
88      for (neg = 0; neg <= 1; neg++)
89        {
90          mpz_neg (z, z);
91          mpfr_set_z (f, z, MPFR_RNDN);
92
93          if (sh < 0)
94            {
95              mpz_tdiv_q_2exp (z, z, -sh);
96              mpfr_div_2exp (f, f, -sh, MPFR_RNDN);
97            }
98          else
99            {
100              mpz_mul_2exp (z, z, sh);
101              mpfr_mul_2exp (f, f, sh, MPFR_RNDN);
102            }
103
104          inex = mpfr_get_z (got, f, MPFR_RNDZ);
105
106          if (mpz_cmp (got, z) != 0)
107            {
108              printf ("Wrong result for shift=%d\n", sh);
109              printf ("     f "); mpfr_dump (f);
110              printf ("   got "); mpz_dump (got);
111              printf ("  want "); mpz_dump (z);
112              exit (1);
113            }
114          if (! SAME_SIGN (inex, - mpfr_cmp_z (f, z)))
115            {
116              printf ("Wrong inexact value for shift=%d\n", sh);
117              printf ("    f "); mpfr_dump (f);
118              printf ("  got %+d\n", inex);
119              printf (" want %+d\n", -mpfr_cmp_z (f, z));
120              exit (1);
121            }
122        }
123    }
124
125  mpfr_clear (f);
126  mpz_clear (got);
127}
128
129static void
130check (void)
131{
132  mpz_t  z;
133
134  mpz_init (z);
135
136  mpz_set_ui (z, 0L);
137  check_one (z);
138
139  mpz_set_si (z, 123L);
140  check_one (z);
141
142  mpz_rrandomb (z, RANDS, 2*GMP_NUMB_BITS);
143  check_one (z);
144
145  mpz_rrandomb (z, RANDS, 5*GMP_NUMB_BITS);
146  check_one (z);
147
148  mpz_clear (z);
149}
150
151static void
152special (void)
153{
154  int inex;
155  mpfr_t x;
156  mpz_t z;
157  int i;
158  mpfr_exp_t e;
159
160  mpfr_init2 (x, 2);
161  mpz_init (z);
162
163  for (i = -1; i <= 1; i++)
164    {
165      if (i != 0)
166        mpfr_set_nan (x);
167      else
168        mpfr_set_inf (x, i);
169      mpfr_clear_flags ();
170      inex = mpfr_get_z (z, x, MPFR_RNDN);
171      if (!mpfr_erangeflag_p () || inex != 0 || mpz_cmp_ui (z, 0) != 0)
172        {
173          printf ("special() failed on mpfr_get_z for i = %d\n", i);
174          exit (1);
175        }
176      mpfr_clear_flags ();
177      e = mpfr_get_z_2exp (z, x);
178      if (!mpfr_erangeflag_p () || e != __gmpfr_emin ||
179          mpz_cmp_ui (z, 0) != 0)
180        {
181          printf ("special() failed on mpfr_get_z_2exp for i = %d\n", i);
182          exit (1);
183        }
184    }
185
186  mpfr_clear (x);
187  mpz_clear (z);
188}
189
190int
191main (void)
192{
193  tests_start_mpfr ();
194
195  check ();
196  check_diff ();
197  special ();
198
199  tests_end_mpfr ();
200  return 0;
201}
202