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