tget_z.c revision 1.1.1.3.4.1 1 1.1 mrg /* Test file for mpz_set_fr / mpfr_get_z.
2 1.1 mrg
3 1.1.1.3.4.1 christos Copyright 2004, 2006-2018 Free Software Foundation, Inc.
4 1.1.1.3 mrg Contributed by the AriC and Caramba projects, INRIA.
5 1.1 mrg
6 1.1 mrg This file is part of the GNU MPFR Library.
7 1.1 mrg
8 1.1 mrg The GNU MPFR Library is free software; you can redistribute it and/or modify
9 1.1 mrg it under the terms of the GNU Lesser General Public License as published by
10 1.1 mrg the Free Software Foundation; either version 3 of the License, or (at your
11 1.1 mrg option) any later version.
12 1.1 mrg
13 1.1 mrg The GNU MPFR Library is distributed in the hope that it will be useful, but
14 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 1.1 mrg License for more details.
17 1.1 mrg
18 1.1 mrg You should have received a copy of the GNU Lesser General Public License
19 1.1 mrg along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
20 1.1 mrg http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 1.1 mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22 1.1 mrg
23 1.1 mrg #include "mpfr-test.h"
24 1.1 mrg
25 1.1 mrg static void
26 1.1 mrg check_diff (void)
27 1.1 mrg {
28 1.1 mrg int inex;
29 1.1 mrg mpfr_t x;
30 1.1 mrg mpz_t z;
31 1.1 mrg mpfr_exp_t emin;
32 1.1 mrg
33 1.1 mrg mpz_init (z);
34 1.1 mrg mpfr_init2 (x, 2);
35 1.1 mrg
36 1.1 mrg mpfr_set_ui (x, 2047, MPFR_RNDU);
37 1.1 mrg mpz_set_fr (z, x, MPFR_RNDN);
38 1.1 mrg if (mpz_cmp_ui (z, 2048) != 0)
39 1.1 mrg {
40 1.1 mrg printf ("get_z RU 2048 failed\n");
41 1.1 mrg exit (1);
42 1.1 mrg }
43 1.1 mrg
44 1.1 mrg mpfr_set_prec (x, 6);
45 1.1 mrg mpfr_set_str (x, "17.5", 10, MPFR_RNDN);
46 1.1 mrg inex = mpfr_get_z (z, x, MPFR_RNDN);
47 1.1 mrg if (inex <= 0 || mpz_cmp_ui (z, 18) != 0)
48 1.1 mrg {
49 1.1 mrg printf ("get_z RN 17.5 failed\n");
50 1.1 mrg exit (1);
51 1.1 mrg }
52 1.1 mrg
53 1.1 mrg /* save default emin */
54 1.1 mrg emin = mpfr_get_emin ();;
55 1.1 mrg
56 1.1 mrg mpfr_set_emin (17);
57 1.1 mrg mpfr_set_ui (x, 0, MPFR_RNDN);
58 1.1 mrg inex = mpfr_get_z (z, x, MPFR_RNDN);
59 1.1 mrg if (inex != 0 || mpz_cmp_ui (z, 0) != 0)
60 1.1 mrg {
61 1.1 mrg printf ("get_z 0 failed\n");
62 1.1 mrg exit (1);
63 1.1 mrg }
64 1.1 mrg
65 1.1 mrg /* restore default emin */
66 1.1 mrg mpfr_set_emin (emin);
67 1.1 mrg
68 1.1 mrg mpfr_clear (x);
69 1.1 mrg mpz_clear (z);
70 1.1 mrg }
71 1.1 mrg
72 1.1 mrg static void
73 1.1 mrg check_one (mpz_ptr z)
74 1.1 mrg {
75 1.1.1.3.4.1 christos mpfr_exp_t emin, emax;
76 1.1 mrg int inex;
77 1.1 mrg int sh, neg;
78 1.1 mrg mpfr_t f;
79 1.1.1.3.4.1 christos mpz_t got, ex, t;
80 1.1.1.3.4.1 christos
81 1.1.1.3.4.1 christos emin = mpfr_get_emin ();
82 1.1.1.3.4.1 christos emax = mpfr_get_emax ();
83 1.1 mrg
84 1.1.1.3.4.1 christos mpfr_init2 (f, MAX (mpz_sizeinbase (z, 2), MPFR_PREC_MIN));
85 1.1 mrg mpz_init (got);
86 1.1.1.3.4.1 christos mpz_init (ex);
87 1.1.1.3.4.1 christos mpz_init (t);
88 1.1 mrg
89 1.1 mrg for (sh = -2*GMP_NUMB_BITS ; sh < 2*GMP_NUMB_BITS ; sh++)
90 1.1 mrg {
91 1.1.1.3.4.1 christos inex = mpfr_set_z (f, z, MPFR_RNDN); /* exact */
92 1.1.1.3.4.1 christos MPFR_ASSERTN (inex == 0);
93 1.1.1.3.4.1 christos
94 1.1.1.3.4.1 christos inex = sh < 0 ?
95 1.1.1.3.4.1 christos mpfr_div_2exp (f, f, -sh, MPFR_RNDN) :
96 1.1.1.3.4.1 christos mpfr_mul_2exp (f, f, sh, MPFR_RNDN);
97 1.1.1.3.4.1 christos MPFR_ASSERTN (inex == 0);
98 1.1.1.3.4.1 christos
99 1.1 mrg for (neg = 0; neg <= 1; neg++)
100 1.1 mrg {
101 1.1.1.3.4.1 christos int rnd;
102 1.1 mrg
103 1.1.1.3.4.1 christos /* Test (-1)^neg * z * 2^sh */
104 1.1 mrg
105 1.1.1.3.4.1 christos RND_LOOP_NO_RNDF (rnd)
106 1.1 mrg {
107 1.1.1.3.4.1 christos int ex_inex, same;
108 1.1.1.3.4.1 christos int d, fi, e;
109 1.1.1.3.4.1 christos mpfr_flags_t flags[3] = { 0, MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE,
110 1.1.1.3.4.1 christos MPFR_FLAGS_ALL }, ex_flags, gt_flags;
111 1.1.1.3.4.1 christos
112 1.1.1.3.4.1 christos if (neg)
113 1.1.1.3.4.1 christos mpz_neg (ex, z);
114 1.1.1.3.4.1 christos else
115 1.1.1.3.4.1 christos mpz_set (ex, z);
116 1.1.1.3.4.1 christos
117 1.1.1.3.4.1 christos if (sh < 0)
118 1.1.1.3.4.1 christos switch (rnd)
119 1.1.1.3.4.1 christos {
120 1.1.1.3.4.1 christos case MPFR_RNDN:
121 1.1.1.3.4.1 christos mpz_set_si (t, neg ? -1 : 1);
122 1.1.1.3.4.1 christos mpz_mul_2exp (t, t, -sh - 1);
123 1.1.1.3.4.1 christos mpz_add (ex, ex, t);
124 1.1.1.3.4.1 christos /* d = mpz_divisible_2exp_p (ex, -sh); */
125 1.1.1.3.4.1 christos d = mpz_scan1 (ex, 0) >= -sh;
126 1.1.1.3.4.1 christos mpz_tdiv_q_2exp (ex, ex, -sh);
127 1.1.1.3.4.1 christos if (d && mpz_tstbit (ex, 0) != 0) /* even rounding */
128 1.1.1.3.4.1 christos {
129 1.1.1.3.4.1 christos if (neg)
130 1.1.1.3.4.1 christos mpz_add_ui (ex, ex, 1);
131 1.1.1.3.4.1 christos else
132 1.1.1.3.4.1 christos mpz_sub_ui (ex, ex, 1);
133 1.1.1.3.4.1 christos }
134 1.1.1.3.4.1 christos break;
135 1.1.1.3.4.1 christos case MPFR_RNDZ:
136 1.1.1.3.4.1 christos mpz_tdiv_q_2exp (ex, ex, -sh);
137 1.1.1.3.4.1 christos break;
138 1.1.1.3.4.1 christos case MPFR_RNDU:
139 1.1.1.3.4.1 christos mpz_cdiv_q_2exp (ex, ex, -sh);
140 1.1.1.3.4.1 christos break;
141 1.1.1.3.4.1 christos case MPFR_RNDD:
142 1.1.1.3.4.1 christos mpz_fdiv_q_2exp (ex, ex, -sh);
143 1.1.1.3.4.1 christos break;
144 1.1.1.3.4.1 christos case MPFR_RNDA:
145 1.1.1.3.4.1 christos if (neg)
146 1.1.1.3.4.1 christos mpz_fdiv_q_2exp (ex, ex, -sh);
147 1.1.1.3.4.1 christos else
148 1.1.1.3.4.1 christos mpz_cdiv_q_2exp (ex, ex, -sh);
149 1.1.1.3.4.1 christos break;
150 1.1.1.3.4.1 christos default:
151 1.1.1.3.4.1 christos MPFR_ASSERTN (0);
152 1.1.1.3.4.1 christos }
153 1.1.1.3.4.1 christos else
154 1.1.1.3.4.1 christos mpz_mul_2exp (ex, ex, sh);
155 1.1.1.3.4.1 christos
156 1.1.1.3.4.1 christos ex_inex = - mpfr_cmp_z (f, ex);
157 1.1.1.3.4.1 christos ex_inex = VSIGN (ex_inex);
158 1.1.1.3.4.1 christos
159 1.1.1.3.4.1 christos for (fi = 0; fi < numberof (flags); fi++)
160 1.1.1.3.4.1 christos for (e = 0; e < 2; e++)
161 1.1.1.3.4.1 christos {
162 1.1.1.3.4.1 christos if (e)
163 1.1.1.3.4.1 christos {
164 1.1.1.3.4.1 christos mpfr_exp_t ef;
165 1.1.1.3.4.1 christos
166 1.1.1.3.4.1 christos if (MPFR_IS_ZERO (f))
167 1.1.1.3.4.1 christos break;
168 1.1.1.3.4.1 christos ef = MPFR_GET_EXP (f);
169 1.1.1.3.4.1 christos set_emin (ef);
170 1.1.1.3.4.1 christos set_emax (ef);
171 1.1.1.3.4.1 christos }
172 1.1.1.3.4.1 christos ex_flags = __gmpfr_flags = flags[fi];
173 1.1.1.3.4.1 christos if (ex_inex != 0)
174 1.1.1.3.4.1 christos ex_flags |= MPFR_FLAGS_INEXACT;
175 1.1.1.3.4.1 christos inex = mpfr_get_z (got, f, (mpfr_rnd_t) rnd);
176 1.1.1.3.4.1 christos inex = VSIGN (inex);
177 1.1.1.3.4.1 christos gt_flags = __gmpfr_flags;
178 1.1.1.3.4.1 christos set_emin (emin);
179 1.1.1.3.4.1 christos set_emax (emax);
180 1.1.1.3.4.1 christos same = SAME_SIGN (inex, ex_inex);
181 1.1.1.3.4.1 christos
182 1.1.1.3.4.1 christos if (mpz_cmp (got, ex) != 0 ||
183 1.1.1.3.4.1 christos !same || gt_flags != ex_flags)
184 1.1.1.3.4.1 christos {
185 1.1.1.3.4.1 christos printf ("Error in check_one for sh=%d, fi=%d, %s%s\n",
186 1.1.1.3.4.1 christos sh, fi,
187 1.1.1.3.4.1 christos mpfr_print_rnd_mode ((mpfr_rnd_t) rnd),
188 1.1.1.3.4.1 christos e ? ", reduced exponent range" : "");
189 1.1.1.3.4.1 christos printf (" f = "); mpfr_dump (f);
190 1.1.1.3.4.1 christos printf ("expected "); mpz_out_str (stdout, 10, ex);
191 1.1.1.3.4.1 christos printf ("\n got "); mpz_out_str (stdout, 10, got);
192 1.1.1.3.4.1 christos printf ("\nExpected inex ~ %d, got %d (%s)\n",
193 1.1.1.3.4.1 christos ex_inex, inex, same ? "OK" : "wrong");
194 1.1.1.3.4.1 christos printf ("Flags:\n");
195 1.1.1.3.4.1 christos printf (" in"); flags_out (flags[fi]);
196 1.1.1.3.4.1 christos printf ("expected"); flags_out (ex_flags);
197 1.1.1.3.4.1 christos printf (" got"); flags_out (gt_flags);
198 1.1.1.3.4.1 christos exit (1);
199 1.1.1.3.4.1 christos }
200 1.1.1.3.4.1 christos }
201 1.1 mrg }
202 1.1.1.3.4.1 christos
203 1.1.1.3.4.1 christos mpfr_neg (f, f, MPFR_RNDN);
204 1.1 mrg }
205 1.1 mrg }
206 1.1 mrg
207 1.1 mrg mpfr_clear (f);
208 1.1 mrg mpz_clear (got);
209 1.1.1.3.4.1 christos mpz_clear (ex);
210 1.1.1.3.4.1 christos mpz_clear (t);
211 1.1 mrg }
212 1.1 mrg
213 1.1 mrg static void
214 1.1 mrg check (void)
215 1.1 mrg {
216 1.1 mrg mpz_t z;
217 1.1 mrg
218 1.1 mrg mpz_init (z);
219 1.1 mrg
220 1.1 mrg mpz_set_ui (z, 0L);
221 1.1 mrg check_one (z);
222 1.1 mrg
223 1.1.1.3.4.1 christos mpz_set_si (z, 17L);
224 1.1.1.3.4.1 christos check_one (z);
225 1.1.1.3.4.1 christos
226 1.1 mrg mpz_set_si (z, 123L);
227 1.1 mrg check_one (z);
228 1.1 mrg
229 1.1 mrg mpz_rrandomb (z, RANDS, 2*GMP_NUMB_BITS);
230 1.1 mrg check_one (z);
231 1.1 mrg
232 1.1 mrg mpz_rrandomb (z, RANDS, 5*GMP_NUMB_BITS);
233 1.1 mrg check_one (z);
234 1.1 mrg
235 1.1 mrg mpz_clear (z);
236 1.1 mrg }
237 1.1 mrg
238 1.1 mrg static void
239 1.1 mrg special (void)
240 1.1 mrg {
241 1.1 mrg int inex;
242 1.1 mrg mpfr_t x;
243 1.1 mrg mpz_t z;
244 1.1.1.3.4.1 christos int i, fi;
245 1.1.1.3.4.1 christos int rnd;
246 1.1 mrg mpfr_exp_t e;
247 1.1.1.3.4.1 christos mpfr_flags_t flags[3] = { 0, MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE,
248 1.1.1.3.4.1 christos MPFR_FLAGS_ALL }, ex_flags, gt_flags;
249 1.1 mrg
250 1.1 mrg mpfr_init2 (x, 2);
251 1.1 mrg mpz_init (z);
252 1.1 mrg
253 1.1.1.3.4.1 christos RND_LOOP (rnd)
254 1.1.1.3.4.1 christos for (i = -1; i <= 1; i++)
255 1.1.1.3.4.1 christos for (fi = 0; fi < numberof (flags); fi++)
256 1.1 mrg {
257 1.1.1.3.4.1 christos ex_flags = flags[fi] | MPFR_FLAGS_ERANGE;
258 1.1.1.3.4.1 christos if (i != 0)
259 1.1.1.3.4.1 christos mpfr_set_nan (x);
260 1.1.1.3.4.1 christos else
261 1.1.1.3.4.1 christos mpfr_set_inf (x, i);
262 1.1.1.3.4.1 christos __gmpfr_flags = flags[fi];
263 1.1.1.3.4.1 christos inex = mpfr_get_z (z, x, (mpfr_rnd_t) rnd);
264 1.1.1.3.4.1 christos gt_flags = __gmpfr_flags;
265 1.1.1.3.4.1 christos if (gt_flags != ex_flags || inex != 0 || mpz_cmp_ui (z, 0) != 0)
266 1.1.1.3.4.1 christos {
267 1.1.1.3.4.1 christos printf ("special() failed on mpfr_get_z"
268 1.1.1.3.4.1 christos " for %s, i = %d, fi = %d\n",
269 1.1.1.3.4.1 christos mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), i, fi);
270 1.1.1.3.4.1 christos printf ("Expected z = 0, inex = 0,");
271 1.1.1.3.4.1 christos flags_out (ex_flags);
272 1.1.1.3.4.1 christos printf ("Got z = ");
273 1.1.1.3.4.1 christos mpz_out_str (stdout, 10, z);
274 1.1.1.3.4.1 christos printf (", inex = %d,", inex);
275 1.1.1.3.4.1 christos flags_out (gt_flags);
276 1.1.1.3.4.1 christos exit (1);
277 1.1.1.3.4.1 christos }
278 1.1.1.3.4.1 christos __gmpfr_flags = flags[fi];
279 1.1.1.3.4.1 christos e = mpfr_get_z_2exp (z, x);
280 1.1.1.3.4.1 christos gt_flags = __gmpfr_flags;
281 1.1.1.3.4.1 christos if (gt_flags != ex_flags || e != __gmpfr_emin ||
282 1.1.1.3.4.1 christos mpz_cmp_ui (z, 0) != 0)
283 1.1.1.3.4.1 christos {
284 1.1.1.3.4.1 christos printf ("special() failed on mpfr_get_z_2exp"
285 1.1.1.3.4.1 christos " for %s, i = %d, fi = %d\n",
286 1.1.1.3.4.1 christos mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), i, fi);
287 1.1.1.3.4.1 christos printf ("Expected z = 0, e = %" MPFR_EXP_FSPEC "d,",
288 1.1.1.3.4.1 christos (mpfr_eexp_t) __gmpfr_emin);
289 1.1.1.3.4.1 christos flags_out (ex_flags);
290 1.1.1.3.4.1 christos printf ("Got z = ");
291 1.1.1.3.4.1 christos mpz_out_str (stdout, 10, z);
292 1.1.1.3.4.1 christos printf (", e = %" MPFR_EXP_FSPEC "d,", (mpfr_eexp_t) e);
293 1.1.1.3.4.1 christos flags_out (gt_flags);
294 1.1.1.3.4.1 christos exit (1);
295 1.1.1.3.4.1 christos }
296 1.1 mrg }
297 1.1 mrg
298 1.1 mrg mpfr_clear (x);
299 1.1 mrg mpz_clear (z);
300 1.1 mrg }
301 1.1 mrg
302 1.1 mrg int
303 1.1 mrg main (void)
304 1.1 mrg {
305 1.1 mrg tests_start_mpfr ();
306 1.1 mrg
307 1.1 mrg check ();
308 1.1 mrg check_diff ();
309 1.1 mrg special ();
310 1.1 mrg
311 1.1 mrg tests_end_mpfr ();
312 1.1 mrg return 0;
313 1.1 mrg }
314