xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tset_q.c (revision fdd524d4ccd2bb0c6f67401e938dabf773eb0372)
1 /* Test file for mpfr_set_q.
2 
3 Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramel projects, INRIA.
5 
6 This file is part of the GNU MPFR Library.
7 
8 The GNU MPFR Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12 
13 The GNU MPFR Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16 License for more details.
17 
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 51 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 
28 static void
29 check (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 
73 static void
74 check0 (void)
75 {
76   mpq_t y;
77   mpfr_t x;
78   int inexact;
79   int r;
80 
81   /* Check for +0 */
82   mpfr_init (x);
83   mpq_init (y);
84   mpq_set_si (y, 0, 1);
85   for (r = 0; r < MPFR_RND_MAX; r++)
86     {
87       inexact = mpfr_set_q(x, y, (mpfr_rnd_t) r);
88       if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact)
89         {
90           printf("mpfr_set_q(x,0) failed for %s\n",
91                  mpfr_print_rnd_mode ((mpfr_rnd_t) r));
92           exit(1);
93         }
94     }
95   mpfr_clear (x);
96   mpq_clear (y);
97 }
98 
99 static void
100 check_nan_inf_mpq (void)
101 {
102   mpfr_t mpfr_value, mpfr_cmp;
103   mpq_t mpq_value;
104   int status;
105 
106   mpfr_init2 (mpfr_value, MPFR_PREC_MIN);
107   mpq_init (mpq_value);
108   mpq_set_si (mpq_value, 0, 0);
109   mpz_set_si (mpq_denref (mpq_value), 0);
110 
111   status = mpfr_set_q (mpfr_value, mpq_value, MPFR_RNDN);
112 
113   if ((status != 0) || (!MPFR_IS_NAN (mpfr_value)))
114     {
115       mpfr_init2 (mpfr_cmp, MPFR_PREC_MIN);
116       mpfr_set_nan (mpfr_cmp);
117       printf ("mpfr_set_q with a NAN mpq value returned a wrong value :\n"
118               " waiting for ");
119       mpfr_print_binary (mpfr_cmp);
120       printf (" got ");
121       mpfr_print_binary (mpfr_value);
122       printf ("\n trinary value is %d\n", status);
123       exit (1);
124     }
125 
126   mpq_set_si (mpq_value, -1, 0);
127   mpz_set_si (mpq_denref (mpq_value), 0);
128 
129   status = mpfr_set_q (mpfr_value, mpq_value, MPFR_RNDN);
130 
131   if ((status != 0) || (!MPFR_IS_INF (mpfr_value)) ||
132       (MPFR_SIGN(mpfr_value) != mpq_sgn(mpq_value)))
133     {
134       mpfr_init2 (mpfr_cmp, MPFR_PREC_MIN);
135       mpfr_set_inf (mpfr_cmp, -1);
136       printf ("mpfr_set_q with a -INF mpq value returned a wrong value :\n"
137               " waiting for ");
138       mpfr_print_binary (mpfr_cmp);
139       printf (" got ");
140       mpfr_print_binary (mpfr_value);
141       printf ("\n trinary value is %d\n", status);
142       exit (1);
143     }
144 
145   mpq_clear (mpq_value);
146   mpfr_clear (mpfr_value);
147 }
148 
149 int
150 main (void)
151 {
152   tests_start_mpfr ();
153 
154   check(-1647229822, 40619231, MPFR_RNDZ, "-4.055295438754120596e1");
155   check(-148939696, 1673285490, MPFR_RNDZ, "-8.9010331404953485501e-2");
156   check(-441322590, 273662545, MPFR_RNDZ, "-1.6126525096812205362");
157   check(-1631156895, 1677687197, MPFR_RNDU, "-9.722652100563177191e-1");
158   check(2141332571, 3117601, MPFR_RNDZ, "6.8685267004982347316e2");
159   check(75504803, 400207282, MPFR_RNDU, "1.8866424074712365155e-1");
160   check(643562308, 23100894, MPFR_RNDD, "2.7858762002890447462e1");
161   check(632549085, 1831935802, MPFR_RNDN, "3.4528998467600230393e-1");
162   check (1, 1, MPFR_RNDN, "1.0");
163 
164   check0();
165 
166   check_nan_inf_mpq ();
167 
168   tests_end_mpfr ();
169   return 0;
170 }
171