xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tset_q.c (revision ba125506a622fe649968631a56eba5d42ff57863)
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