1 /* Test file for mpfr_set_q.
2
3 Copyright 2000-2023 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramba 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 https://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 "mpfr-test.h"
24
25 #ifndef MPFR_USE_MINI_GMP
26
27 static void
check(long int n,long int d,mpfr_rnd_t rnd,const char * ys)28 check (long int n, long int d, mpfr_rnd_t rnd, const char *ys)
29 {
30 mpq_t q;
31 mpfr_t x, t;
32 int inexact, compare;
33 mpfr_flags_t flags, ex_flags;
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 mpfr_clear_flags ();
40 inexact = mpfr_set_q (x, q, rnd);
41 flags = __gmpfr_flags;
42
43 /* check values */
44 if (mpfr_cmp_str1 (x, ys))
45 {
46 printf ("Error for q = %ld/%ld and rnd = %s\n", n, d,
47 mpfr_print_rnd_mode (rnd));
48 printf ("correct result is %s, mpfr_set_q gives ", ys);
49 mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
50 putchar ('\n');
51 exit (1);
52 }
53
54 /* check inexact flag */
55 if (mpfr_mul_ui (t, x, (d < 0) ? (-d) : d, rnd))
56 {
57 printf ("t <- x * d should be exact\n");
58 exit (1);
59 }
60 compare = mpfr_cmp_si (t, n);
61 if (! SAME_SIGN (inexact, compare))
62 {
63 printf ("Wrong ternary value for q = %ld/%ld and rnd = %s:\n"
64 "expected %d or equivalent, got %d\n",
65 n, d, mpfr_print_rnd_mode (rnd), compare, inexact);
66 exit (1);
67 }
68
69 ex_flags = compare == 0 ? 0 : MPFR_FLAGS_INEXACT;
70 if (flags != ex_flags)
71 {
72 printf ("Wrong flags for q = %ld/%ld and rnd = %s:\n",
73 n, d, mpfr_print_rnd_mode (rnd));
74 printf ("Expected flags:");
75 flags_out (ex_flags);
76 printf ("Got flags: ");
77 flags_out (flags);
78 exit (1);
79 }
80
81 mpfr_clear (x);
82 mpfr_clear (t);
83 mpq_clear (q);
84 }
85
86 static void
check0(void)87 check0 (void)
88 {
89 mpq_t y;
90 mpfr_t x;
91 int inexact;
92 int r;
93
94 /* Check for +0 */
95 mpfr_init (x);
96 mpq_init (y);
97 mpq_set_si (y, 0, 1);
98 RND_LOOP (r)
99 {
100 mpfr_clear_flags ();
101 inexact = mpfr_set_q (x, y, (mpfr_rnd_t) r);
102 if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact ||
103 __gmpfr_flags != 0)
104 {
105 printf("mpfr_set_q(x,0) failed for %s\n",
106 mpfr_print_rnd_mode ((mpfr_rnd_t) r));
107 exit(1);
108 }
109 }
110 mpfr_clear (x);
111 mpq_clear (y);
112 }
113
114 static void
check_nan_inf_mpq(void)115 check_nan_inf_mpq (void)
116 {
117 mpfr_t mpfr_value, mpfr_cmp;
118 mpq_t mpq_value;
119 int status;
120
121 mpfr_init2 (mpfr_value, MPFR_PREC_MIN);
122 mpq_init (mpq_value);
123 mpq_set_si (mpq_value, 0, 0);
124 mpz_set_si (mpq_denref (mpq_value), 0);
125
126 status = mpfr_set_q (mpfr_value, mpq_value, MPFR_RNDN);
127
128 if ((status != 0) || (!MPFR_IS_NAN (mpfr_value)))
129 {
130 mpfr_init2 (mpfr_cmp, MPFR_PREC_MIN);
131 mpfr_set_nan (mpfr_cmp);
132 printf ("mpfr_set_q with a NAN mpq value returned a wrong value :\n"
133 " expected ");
134 mpfr_dump (mpfr_cmp);
135 printf (" got ");
136 mpfr_dump (mpfr_value);
137 printf (" ternary value is %d\n", status);
138 exit (1);
139 }
140
141 mpq_set_si (mpq_value, -1, 0);
142 mpz_set_si (mpq_denref (mpq_value), 0);
143
144 status = mpfr_set_q (mpfr_value, mpq_value, MPFR_RNDN);
145
146 if ((status != 0) || (!MPFR_IS_INF (mpfr_value)) ||
147 (MPFR_SIGN(mpfr_value) != mpq_sgn(mpq_value)))
148 {
149 mpfr_init2 (mpfr_cmp, MPFR_PREC_MIN);
150 mpfr_set_inf (mpfr_cmp, -1);
151 printf ("mpfr_set_q with a -INF mpq value returned a wrong value :\n"
152 " expected ");
153 mpfr_dump (mpfr_cmp);
154 printf (" got ");
155 mpfr_dump (mpfr_value);
156 printf (" ternary value is %d\n", status);
157 exit (1);
158 }
159
160 mpq_clear (mpq_value);
161 mpfr_clear (mpfr_value);
162 }
163
164 int
main(void)165 main (void)
166 {
167 tests_start_mpfr ();
168
169 check(-1647229822, 40619231, MPFR_RNDZ, "-4.055295438754120596e1");
170 check(-148939696, 1673285490, MPFR_RNDZ, "-8.9010331404953485501e-2");
171 check(-441322590, 273662545, MPFR_RNDZ, "-1.6126525096812205362");
172 check(-1631156895, 1677687197, MPFR_RNDU, "-9.722652100563177191e-1");
173 check(2141332571, 3117601, MPFR_RNDZ, "6.8685267004982347316e2");
174 check(75504803, 400207282, MPFR_RNDU, "1.8866424074712365155e-1");
175 check(643562308, 23100894, MPFR_RNDD, "2.7858762002890447462e1");
176 check(632549085, 1831935802, MPFR_RNDN, "3.4528998467600230393e-1");
177 check (1, 1, MPFR_RNDN, "1.0");
178
179 check0();
180
181 check_nan_inf_mpq ();
182
183 tests_end_mpfr ();
184 return 0;
185 }
186
187 #else
188
189 int
main(void)190 main (void)
191 {
192 return 77;
193 }
194
195 #endif
196