1/* Test file for mpfr_get_q. 2 3Copyright 2017-2023 Free Software Foundation, Inc. 4Contributed by the AriC and Caramba projects, INRIA. 5 6This file is part of the GNU MPFR Library. 7 8The GNU MPFR Library is free software; you can redistribute it and/or modify 9it under the terms of the GNU Lesser General Public License as published by 10the Free Software Foundation; either version 3 of the License, or (at your 11option) any later version. 12 13The GNU MPFR Library is distributed in the hope that it will be useful, but 14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16License for more details. 17 18You should have received a copy of the GNU Lesser General Public License 19along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 23#include "mpfr-test.h" 24 25#ifndef MPFR_USE_MINI_GMP 26 27static void 28special (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 75static void 76random_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 */ 105static void 106check_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 135static void 136coverage (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 158int 159main (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 175int 176main (void) 177{ 178 return 77; 179} 180 181#endif /* MPFR_USE_MINI_GMP */ 182