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 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 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 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 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 190 main (void) 191 { 192 return 77; 193 } 194 195 #endif 196