1/* Test file for mpfr_set_q. 2 3Copyright 2000-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 28check (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 86static void 87check0 (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 114static void 115check_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 164int 165main (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 189int 190main (void) 191{ 192 return 77; 193} 194 195#endif 196