1/* Test file for mpfr_set_q.
2
3Copyright 2000, 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
28static void
29check (long int n, long int d, mpfr_rnd_t rnd, const char *ys)
30{
31  mpq_t q;
32  mpfr_t x, t;
33  int inexact, compare;
34
35  mpfr_init2 (x, 53);
36  mpfr_init2 (t, mpfr_get_prec (x) + mp_bits_per_limb);
37  mpq_init (q);
38  mpq_set_si (q, n, d);
39  inexact = mpfr_set_q (x, q, rnd);
40
41  /* check values */
42  if (mpfr_cmp_str1(x, ys))
43    {
44      printf ("Error for q=%ld/%ld and rnd=%s\n", n, d,
45              mpfr_print_rnd_mode (rnd));
46      printf ("correct result is %s, mpfr_set_q gives ", ys);
47      mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN);
48      putchar('\n');
49      exit (1);
50    }
51
52  /* check inexact flag */
53  if (mpfr_mul_ui (t, x, (d < 0) ? (-d) : d, rnd))
54    {
55      printf ("t <- x * d should be exact\n");
56      exit (1);
57    }
58  compare = mpfr_cmp_si (t, n);
59  if (((inexact == 0) && (compare != 0)) ||
60      ((inexact < 0) && (compare >= 0)) ||
61      ((inexact > 0) && (compare <= 0)))
62    {
63      printf ("wrong inexact flag: expected %d, got %d\n", compare,
64              inexact);
65      exit (1);
66    }
67
68  mpfr_clear (x);
69  mpfr_clear (t);
70  mpq_clear (q);
71}
72
73static void check0(void)
74{
75  mpq_t y;
76  mpfr_t x;
77  int inexact;
78  int r;
79
80  /* Check for +0 */
81  mpfr_init (x);
82  mpq_init (y);
83  mpq_set_si (y, 0, 1);
84  for (r = 0; r < MPFR_RND_MAX; r++)
85    {
86      inexact = mpfr_set_q(x, y, (mpfr_rnd_t) r);
87      if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact)
88        {
89          printf("mpfr_set_q(x,0) failed for %s\n",
90                 mpfr_print_rnd_mode ((mpfr_rnd_t) r));
91          exit(1);
92        }
93    }
94  mpfr_clear (x);
95  mpq_clear (y);
96}
97
98int
99main (void)
100{
101  tests_start_mpfr ();
102
103  check(-1647229822, 40619231, MPFR_RNDZ, "-4.055295438754120596e1");
104  check(-148939696, 1673285490, MPFR_RNDZ, "-8.9010331404953485501e-2");
105  check(-441322590, 273662545, MPFR_RNDZ, "-1.6126525096812205362");
106  check(-1631156895, 1677687197, MPFR_RNDU, "-9.722652100563177191e-1");
107  check(2141332571, 3117601, MPFR_RNDZ, "6.8685267004982347316e2");
108  check(75504803, 400207282, MPFR_RNDU, "1.8866424074712365155e-1");
109  check(643562308, 23100894, MPFR_RNDD, "2.7858762002890447462e1");
110  check(632549085, 1831935802, MPFR_RNDN, "3.4528998467600230393e-1");
111  check (1, 1, MPFR_RNDN, "1.0");
112
113  check0();
114
115  tests_end_mpfr ();
116  return 0;
117}
118