1/* tset -- Test file for mpc_set_x and mpc_set_x_x functions.
2
3Copyright (C) 2009, 2010, 2011 INRIA
4
5This file is part of GNU MPC.
6
7GNU MPC is free software; you can redistribute it and/or modify it under
8the terms of the GNU Lesser General Public License as published by the
9Free Software Foundation; either version 3 of the License, or (at your
10option) any later version.
11
12GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
15more details.
16
17You should have received a copy of the GNU Lesser General Public License
18along with this program. If not, see http://www.gnu.org/licenses/ .
19*/
20
21#include "config.h"
22#include <limits.h> /* for LONG_MAX */
23
24#ifdef HAVE_INTTYPES_H
25# include <inttypes.h> /* for intmax_t */
26#else
27# ifdef HAVE_STDINT_H
28#  include <stdint.h>
29# endif
30#endif
31
32#ifdef HAVE_COMPLEX_H
33# include <complex.h>
34#endif
35
36#ifdef HAVE_LOCALE_H
37#include <locale.h>
38#endif
39
40#include "mpc-tests.h"
41
42#define PRINT_ERROR(function_name, precision, a)                \
43  do {                                                          \
44    printf ("Error in "function_name" for prec = %lu\n",        \
45            (unsigned long int) precision);                     \
46    MPC_OUT(a);                                                     \
47    exit (1);                                                   \
48  } while (0)
49
50/* test MPC_SET_X_Y through some functions */
51static int
52mpc_set_ui_fr (mpc_ptr z, unsigned long int a, mpfr_srcptr b, mpc_rnd_t rnd)
53  MPC_SET_X_Y (ui, fr, z, a, b, rnd)
54
55static int
56mpc_set_fr_ui (mpc_ptr z, mpfr_srcptr a, unsigned long int b, mpc_rnd_t rnd)
57  MPC_SET_X_Y (fr, ui, z, a, b, rnd)
58
59static int
60mpc_set_f_si (mpc_ptr z, mpf_t a, long int b, mpc_rnd_t rnd)
61  MPC_SET_X_Y (f, si, z, a, b, rnd)
62
63
64static void
65check_set (void)
66{
67  long int lo;
68  mpz_t mpz;
69  mpq_t mpq;
70  mpf_t mpf;
71  mpfr_t fr;
72  mpc_t x, z;
73  mpfr_prec_t prec;
74
75  mpz_init (mpz);
76  mpq_init (mpq);
77  mpf_init2 (mpf, 1000);
78  mpfr_init2 (fr, 1000);
79  mpc_init2 (x, 1000);
80  mpc_init2 (z, 1000);
81
82  mpz_set_ui (mpz, 0x4217);
83  mpq_set_si (mpq, -1, 0x4321);
84  mpf_set_q (mpf, mpq);
85
86  for (prec = 2; prec <= 1000; prec++)
87    {
88      unsigned long int u = (unsigned long int) prec;
89
90      mpc_set_prec (z, prec);
91      mpfr_set_prec (fr, prec);
92
93      lo = -prec;
94
95      mpfr_set_d (fr, 1.23456789, GMP_RNDN);
96
97      mpc_set_d (z, 1.23456789, MPC_RNDNN);
98      if (mpfr_cmp (mpc_realref(z), fr) != 0 || mpfr_cmp_si (mpc_imagref(z), 0) != 0)
99        PRINT_ERROR ("mpc_set_d", prec, z);
100
101#if defined HAVE_COMPLEX_H
102      mpc_set_dc (z, I*1.23456789+1.23456789, MPC_RNDNN);
103      if (mpfr_cmp (mpc_realref(z), fr) != 0 || mpfr_cmp (mpc_imagref(z), fr) != 0)
104        PRINT_ERROR ("mpc_set_c", prec, z);
105#endif
106
107      mpc_set_ui (z, u, MPC_RNDNN);
108      if (mpfr_cmp_ui (mpc_realref(z), u) != 0
109          || mpfr_cmp_ui (mpc_imagref(z), 0) != 0)
110        PRINT_ERROR ("mpc_set_ui", prec, z);
111
112      mpc_set_d_d (z, 1.23456789, 1.23456789, MPC_RNDNN);
113      if (mpfr_cmp (mpc_realref(z), fr) != 0 || mpfr_cmp (mpc_imagref(z), fr) != 0)
114        PRINT_ERROR ("mpc_set_d_d", prec, z);
115
116      mpc_set_si (z, lo, MPC_RNDNN);
117      if (mpfr_cmp_si (mpc_realref(z), lo) != 0 || mpfr_cmp_ui (mpc_imagref(z), 0) != 0)
118        PRINT_ERROR ("mpc_set_si", prec, z);
119
120      mpfr_set_ld (fr, 1.23456789L, GMP_RNDN);
121
122      mpc_set_ld_ld (z, 1.23456789L, 1.23456789L, MPC_RNDNN);
123      if (mpfr_cmp (mpc_realref(z), fr) != 0 || mpfr_cmp (mpc_imagref(z), fr) != 0)
124        PRINT_ERROR ("mpc_set_ld_ld", prec, z);
125
126#if defined HAVE_COMPLEX_H
127      mpc_set_ldc (z, I*1.23456789L+1.23456789L, MPC_RNDNN);
128      if (mpfr_cmp (mpc_realref(z), fr) != 0 || mpfr_cmp (mpc_imagref(z), fr) != 0)
129        PRINT_ERROR ("mpc_set_lc", prec, z);
130#endif
131      mpc_set_ui_ui (z, u, u, MPC_RNDNN);
132      if (mpfr_cmp_ui (mpc_realref(z), u) != 0
133          || mpfr_cmp_ui (mpc_imagref(z), u) != 0)
134        PRINT_ERROR ("mpc_set_ui_ui", prec, z);
135
136      mpc_set_ld (z, 1.23456789L, MPC_RNDNN);
137      mpfr_clear_flags ();
138      if (mpfr_cmp (mpc_realref(z), fr) != 0
139          || mpfr_cmp_ui (mpc_imagref(z), 0) != 0
140          || mpfr_erangeflag_p())
141        PRINT_ERROR ("mpc_set_ld", prec, z);
142
143      mpc_set_prec (x, prec);
144      mpfr_set_ui(fr, 1, GMP_RNDN);
145      mpfr_div_ui(fr, fr, 3, GMP_RNDN);
146      mpfr_set(mpc_realref(x), fr, GMP_RNDN);
147      mpfr_set(mpc_imagref(x), fr, GMP_RNDN);
148
149      mpc_set (z, x, MPC_RNDNN);
150      mpfr_clear_flags (); /* mpc_cmp set erange flag when an operand is a
151                              NaN */
152      if (mpc_cmp (z, x) != 0 || mpfr_erangeflag_p())
153        {
154          printf ("Error in mpc_set for prec = %lu\n",
155                  (unsigned long int) prec);
156          MPC_OUT(z);
157          MPC_OUT(x);
158          exit (1);
159        }
160
161      mpc_set_si_si (z, lo, lo, MPC_RNDNN);
162      if (mpfr_cmp_si (mpc_realref(z), lo) != 0
163          || mpfr_cmp_si (mpc_imagref(z), lo) != 0)
164        PRINT_ERROR ("mpc_set_si_si", prec, z);
165
166      mpc_set_fr (z, fr, MPC_RNDNN);
167      mpfr_clear_flags ();
168      if (mpfr_cmp (mpc_realref(z), fr) != 0
169          || mpfr_cmp_ui (mpc_imagref(z), 0) != 0
170          || mpfr_erangeflag_p())
171        PRINT_ERROR ("mpc_set_fr", prec, z);
172
173      mpfr_set_z (fr, mpz, GMP_RNDN);
174      mpc_set_z_z (z, mpz, mpz, MPC_RNDNN);
175      mpfr_clear_flags ();
176      if (mpfr_cmp (mpc_realref(z), fr) != 0
177          || mpfr_cmp (mpc_imagref(z), fr) != 0
178          || mpfr_erangeflag_p())
179        PRINT_ERROR ("mpc_set_z_z", prec, z);
180
181      mpc_set_fr_fr (z, fr, fr, MPC_RNDNN);
182      mpfr_clear_flags ();
183      if (mpfr_cmp (mpc_realref(z), fr) != 0
184          || mpfr_cmp (mpc_imagref(z), fr) != 0
185          || mpfr_erangeflag_p())
186        PRINT_ERROR ("mpc_set_fr_fr", prec, z);
187
188      mpc_set_z (z, mpz, MPC_RNDNN);
189      mpfr_clear_flags ();
190      if (mpfr_cmp (mpc_realref(z), fr) != 0
191          || mpfr_cmp_ui (mpc_imagref(z), 0) != 0
192          || mpfr_erangeflag_p())
193        PRINT_ERROR ("mpc_set_z", prec, z);
194
195      mpfr_set_q (fr, mpq, GMP_RNDN);
196      mpc_set_q_q (z, mpq, mpq, MPC_RNDNN);
197      mpfr_clear_flags ();
198      if (mpfr_cmp (mpc_realref(z), fr) != 0
199          || mpfr_cmp (mpc_imagref(z), fr) != 0
200          || mpfr_erangeflag_p())
201        PRINT_ERROR ("mpc_set_q_q", prec, z);
202
203      mpc_set_ui_fr (z, u, fr, MPC_RNDNN);
204      mpfr_clear_flags ();
205      if (mpfr_cmp_ui (mpc_realref (z), u) != 0
206          || mpfr_cmp (mpc_imagref (z), fr) != 0
207          || mpfr_erangeflag_p ())
208        PRINT_ERROR ("mpc_set_ui_fr", prec, z);
209
210      mpc_set_fr_ui (z, fr, u, MPC_RNDNN);
211      mpfr_clear_flags ();
212      if (mpfr_cmp (mpc_realref (z), fr) != 0
213          || mpfr_cmp_ui (mpc_imagref (z), u) != 0
214          || mpfr_erangeflag_p())
215        PRINT_ERROR ("mpc_set_fr_ui", prec, z);
216
217      mpc_set_q (z, mpq, MPC_RNDNN);
218      mpfr_clear_flags ();
219      if (mpfr_cmp (mpc_realref(z), fr) != 0
220          || mpfr_cmp_ui (mpc_imagref(z), 0) != 0
221          || mpfr_erangeflag_p())
222        PRINT_ERROR ("mpc_set_q", prec, z);
223
224      mpfr_set_f (fr, mpf, GMP_RNDN);
225      mpc_set_f_f (z, mpf, mpf, MPC_RNDNN);
226      mpfr_clear_flags ();
227      if (mpfr_cmp (mpc_realref(z), fr) != 0
228          || mpfr_cmp (mpc_imagref(z), fr) != 0
229          || mpfr_erangeflag_p())
230        PRINT_ERROR ("mpc_set_f_f", prec, z);
231
232      mpc_set_f (z, mpf, MPC_RNDNN);
233      mpfr_clear_flags ();
234      if (mpfr_cmp (mpc_realref(z), fr) != 0
235          || mpfr_cmp_ui (mpc_imagref(z), 0) != 0
236          || mpfr_erangeflag_p())
237        PRINT_ERROR ("mpc_set_f", prec, z);
238
239      mpc_set_f_si (z, mpf, lo, MPC_RNDNN);
240      mpfr_clear_flags ();
241      if (mpfr_cmp (mpc_realref (z), fr) != 0
242          || mpfr_cmp_si (mpc_imagref (z), lo) != 0
243          || mpfr_erangeflag_p ())
244        PRINT_ERROR ("mpc_set_f", prec, z);
245
246      mpc_set_nan (z);
247      if (!mpfr_nan_p (mpc_realref(z)) || !mpfr_nan_p (mpc_imagref(z)))
248        PRINT_ERROR ("mpc_set_nan", prec, z);
249
250#ifdef _MPC_H_HAVE_INTMAX_T
251      {
252        uintmax_t uim = (uintmax_t) prec;
253        intmax_t im = (intmax_t) prec;
254
255        mpc_set_uj (z, uim, MPC_RNDNN);
256        if (mpfr_cmp_ui (mpc_realref(z), u) != 0
257            || mpfr_cmp_ui (mpc_imagref(z), 0) != 0)
258          PRINT_ERROR ("mpc_set_uj", prec, z);
259
260        mpc_set_sj (z, im, MPC_RNDNN);
261        if (mpfr_cmp_ui (mpc_realref(z), u) != 0
262            || mpfr_cmp_ui (mpc_imagref(z), 0) != 0)
263          PRINT_ERROR ("mpc_set_sj (1)", prec, z);
264
265        mpc_set_uj_uj (z, uim, uim, MPC_RNDNN);
266        if (mpfr_cmp_ui (mpc_realref(z), u) != 0
267            || mpfr_cmp_ui (mpc_imagref(z), u) != 0)
268          PRINT_ERROR ("mpc_set_uj_uj", prec, z);
269
270        mpc_set_sj_sj (z, im, im, MPC_RNDNN);
271        if (mpfr_cmp_ui (mpc_realref(z), u) != 0
272            || mpfr_cmp_ui (mpc_imagref(z), u) != 0)
273          PRINT_ERROR ("mpc_set_sj_sj (1)", prec, z);
274
275        im = LONG_MAX;
276        if (sizeof (intmax_t) == 2 * sizeof (unsigned long))
277          im = 2 * im * im + 4 * im + 1; /* gives 2^(2n-1)-1 from 2^(n-1)-1 */
278
279        mpc_set_sj (z, im, MPC_RNDNN);
280        if (mpfr_get_sj (mpc_realref(z), GMP_RNDN) != im ||
281            mpfr_cmp_ui (mpc_imagref(z), 0) != 0)
282          PRINT_ERROR ("mpc_set_sj (2)", im, z);
283
284        mpc_set_sj_sj (z, im, im, MPC_RNDNN);
285        if (mpfr_get_sj (mpc_realref(z), GMP_RNDN) != im ||
286            mpfr_get_sj (mpc_imagref(z), GMP_RNDN) != im)
287          PRINT_ERROR ("mpc_set_sj_sj (2)", im, z);
288      }
289#endif /* _MPC_H_HAVE_INTMAX_T */
290
291#if defined HAVE_COMPLEX_H
292      {
293        double _Complex c = 1.0 - 2.0*I, d;
294        long double _Complex lc = c, ld;
295
296         mpc_set_dc (z, c, MPC_RNDNN);
297         if ((d = mpc_get_dc (z, MPC_RNDNN)) != c)
298           {
299             printf ("expected (%f,%f)\n", creal (c), cimag (c));
300             printf ("got      (%f,%f)\n", creal (d), cimag (d));
301             PRINT_ERROR ("mpc_get_dc", prec, z);
302           }
303         mpc_set_ldc (z, lc, MPC_RNDNN);
304         if ((ld = mpc_get_ldc (z, MPC_RNDNN)) != lc)
305           {
306             printf ("expected (%Lf,%Lf)\n", creall (lc), cimagl (lc));
307             printf ("got      (%Lf,%Lf)\n", creall (ld), cimagl (ld));
308             PRINT_ERROR ("mpc_get_ldc", prec, z);
309           }
310      }
311#endif
312    }
313
314  mpz_clear (mpz);
315  mpq_clear (mpq);
316  mpf_clear (mpf);
317  mpfr_clear (fr);
318  mpc_clear (x);
319  mpc_clear (z);
320}
321
322static void
323check_set_str (mpfr_exp_t exp_max)
324{
325  mpc_t expected;
326  mpc_t got;
327  char *str;
328
329  mpfr_prec_t prec;
330  mpfr_exp_t exp_min;
331  int base;
332
333  mpc_init2 (expected, 1024);
334  mpc_init2 (got, 1024);
335
336  exp_min = mpfr_get_emin ();
337  if (exp_max <= 0)
338    exp_max = mpfr_get_emax ();
339  else if (exp_max > mpfr_get_emax ())
340    exp_max = mpfr_get_emax();
341  if (-exp_max > exp_min)
342    exp_min = - exp_max;
343
344  for (prec = 2; prec < 1024; prec += 7)
345    {
346      mpc_set_prec (got, prec);
347      mpc_set_prec (expected, prec);
348
349      base = 2 + (int) gmp_urandomm_ui (rands, 35);
350         /* uses external variable rands from random.c */
351
352      mpfr_set_nan (mpc_realref (expected));
353      mpfr_set_inf (mpc_imagref (expected), prec % 2 - 1);
354      str = mpc_get_str (base, 0, expected, MPC_RNDNN);
355      if (mpfr_nan_p (mpc_realref (got)) == 0
356          || mpfr_cmp (mpc_imagref (got), mpc_imagref (expected)) != 0)
357        {
358          printf ("Error: mpc_set_str o mpc_get_str != Id\n"
359                  "in base %u with str=\"%s\"\n", base, str);
360          MPC_OUT (expected);
361          printf ("     ");
362          MPC_OUT (got);
363          exit (1);
364        }
365      mpc_free_str (str);
366
367      test_default_random (expected, exp_min, exp_max, 128, 25);
368      str = mpc_get_str (base, 0, expected, MPC_RNDNN);
369      if (mpc_set_str (got, str, base, MPC_RNDNN) == -1
370          || mpc_cmp (got, expected) != 0)
371        {
372          printf ("Error: mpc_set_str o mpc_get_str != Id\n"
373                  "in base %u with str=\"%s\"\n", base, str);
374          MPC_OUT (expected);
375          printf ("     ");
376          MPC_OUT (got);
377          exit (1);
378        }
379      mpc_free_str (str);
380    }
381
382#ifdef HAVE_SETLOCALE
383  {
384    /* Check with ',' as a decimal point */
385    char *old_locale;
386
387    old_locale = setlocale (LC_ALL, "de_DE");
388    if (old_locale != NULL)
389      {
390        str = mpc_get_str (10, 0, expected, MPC_RNDNN);
391        if (mpc_set_str (got, str, 10, MPC_RNDNN) == -1
392            || mpc_cmp (got, expected) != 0)
393          {
394            printf ("Error: mpc_set_str o mpc_get_str != Id\n"
395                    "with str=\"%s\"\n", str);
396            MPC_OUT (expected);
397            printf ("     ");
398            MPC_OUT (got);
399            exit (1);
400          }
401        mpc_free_str (str);
402
403        setlocale (LC_ALL, old_locale);
404      }
405  }
406#endif /* HAVE_SETLOCALE */
407
408  /* the real part has a zero exponent in base ten (fixed in r439) */
409  mpc_set_prec (expected, 37);
410  mpc_set_prec (got, 37);
411  mpc_set_str (expected, "921FC04EDp-35  ", 16, GMP_RNDN);
412  str = mpc_get_str (10, 0, expected, MPC_RNDNN);
413  if (mpc_set_str (got, str, 10, MPC_RNDNN) == -1
414      || mpc_cmp (got, expected) != 0)
415    {
416      printf ("Error: mpc_set_str o mpc_get_str != Id\n"
417              "with str=\"%s\"\n", str);
418      MPC_OUT (expected);
419      printf ("     ");
420      MPC_OUT (got);
421      exit (1);
422    }
423  mpc_free_str (str);
424
425  str = mpc_get_str (1, 0, expected, MPC_RNDNN);
426  if (str != NULL)
427    {
428      printf ("Error: mpc_get_str with base==1 should fail\n");
429      exit (1);
430    }
431
432  mpc_clear (expected);
433  mpc_clear (got);
434}
435
436int
437main (void)
438{
439  test_start ();
440
441  check_set ();
442  check_set_str (1024);
443
444  test_end ();
445
446  return 0;
447}
448