1 /* Test file for mpfr_get_q.
2
3 Copyright 2017-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
special(void)28 special (void)
29 {
30 mpfr_t f;
31 mpq_t q;
32
33 mpfr_init2 (f, MPFR_PREC_MIN);
34 mpq_init (q);
35
36 /* check NaN */
37 mpfr_set_nan (f);
38 mpfr_clear_erangeflag ();
39 mpfr_get_q (q, f);
40 MPFR_ASSERTN(mpq_cmp_ui (q, 0, 1) == 0);
41 MPFR_ASSERTN(mpfr_erangeflag_p ());
42
43 /* check +Inf */
44 mpfr_set_inf (f, 1);
45 mpfr_clear_erangeflag ();
46 mpfr_get_q (q, f);
47 MPFR_ASSERTN(mpq_cmp_ui (q, 0, 1) == 0);
48 MPFR_ASSERTN(mpfr_erangeflag_p ());
49
50 /* check -Inf */
51 mpfr_set_inf (f, -1);
52 mpfr_clear_erangeflag ();
53 mpfr_get_q (q, f);
54 MPFR_ASSERTN(mpq_cmp_ui (q, 0, 1) == 0);
55 MPFR_ASSERTN(mpfr_erangeflag_p ());
56
57 /* check +0 */
58 mpfr_set_zero (f, 1);
59 mpfr_clear_erangeflag ();
60 mpfr_get_q (q, f);
61 MPFR_ASSERTN(mpq_cmp_ui (q, 0, 1) == 0);
62 MPFR_ASSERTN(!mpfr_erangeflag_p ());
63
64 /* check -0 */
65 mpfr_set_zero (f, -1);
66 mpfr_clear_erangeflag ();
67 mpfr_get_q (q, f);
68 MPFR_ASSERTN(mpq_cmp_ui (q, 0, 1) == 0);
69 MPFR_ASSERTN(!mpfr_erangeflag_p ());
70
71 mpq_clear (q);
72 mpfr_clear (f);
73 }
74
75 static void
random_tests(void)76 random_tests (void)
77 {
78 mpfr_t f, g;
79 mpq_t q;
80 int inex;
81 mpfr_rnd_t rnd;
82 int i;
83
84 mpfr_init2 (f, MPFR_PREC_MIN + (randlimb() % 100));
85 mpfr_init2 (g, mpfr_get_prec (f));
86 mpq_init (q);
87
88 for (i = 0; i < 1000; i++)
89 {
90 mpfr_urandomb (f, RANDS);
91 mpfr_get_q (q, f);
92 rnd = RND_RAND ();
93 inex = mpfr_set_q (g, q, rnd);
94 MPFR_ASSERTN(inex == 0);
95 MPFR_ASSERTN(mpfr_cmp (f, g) == 0);
96 }
97
98 mpq_clear (q);
99 mpfr_clear (f);
100 mpfr_clear (g);
101 }
102
103 /* Check results are in canonical form.
104 See https://sympa.inria.fr/sympa/arc/mpfr/2017-12/msg00029.html */
105 static void
check_canonical(void)106 check_canonical (void)
107 {
108 mpfr_t x;
109 mpq_t q;
110 mpz_t z;
111
112 mpfr_init2 (x, 53);
113 mpfr_set_ui (x, 3, MPFR_RNDN);
114 mpq_init (q);
115 mpfr_get_q (q, x);
116 /* check the denominator is positive */
117 if (mpz_sgn (mpq_denref (q)) <= 0)
118 {
119 printf ("Error, the denominator of mpfr_get_q should be positive\n");
120 exit (1);
121 }
122 mpz_init (z);
123 mpz_gcd (z, mpq_numref (q), mpq_denref (q));
124 /* check the numerator and denominator are coprime */
125 if (mpz_cmp_ui (z, 1) != 0)
126 {
127 printf ("Error, numerator and denominator of mpfr_get_q should be coprime\n");
128 exit (1);
129 }
130 mpfr_clear (x);
131 mpq_clear (q);
132 mpz_clear (z);
133 }
134
135 static void
coverage(void)136 coverage (void)
137 {
138 mpfr_t x;
139 mpq_t q;
140 mpz_t z;
141
142 mpfr_init2 (x, 5);
143 mpq_init (q);
144 mpz_init (z);
145
146 mpfr_set_ui_2exp (x, 17, 100, MPFR_RNDN);
147 mpfr_get_q (q, x);
148 MPFR_ASSERTN(mpz_cmp_ui (mpq_denref (q), 1) == 0);
149 mpz_set_ui (z, 17);
150 mpz_mul_2exp (z, z, 100);
151 MPFR_ASSERTN(mpz_cmp (mpq_numref (q), z) == 0);
152
153 mpfr_clear (x);
154 mpq_clear (q);
155 mpz_clear (z);
156 }
157
158 int
main(void)159 main (void)
160 {
161 tests_start_mpfr ();
162
163 coverage ();
164 special ();
165 random_tests ();
166
167 check_canonical ();
168
169 tests_end_mpfr ();
170 return 0;
171 }
172
173 #else
174
175 int
main(void)176 main (void)
177 {
178 return 77;
179 }
180
181 #endif /* MPFR_USE_MINI_GMP */
182