1/* Generic test file for functions with one mpfr_t argument and an integer. 2 3Copyright 2005-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/* define INTEGER_TYPE to what we want */ 24#ifndef INTEGER_TYPE 25# define INTEGER_TYPE mp_limb_t 26#endif 27#ifndef RAND_FUNCTION 28# define RAND_FUNCTION(x) mpfr_urandomb ((x), RANDS) 29#endif 30#ifndef INT_RAND_FUNCTION 31# define INT_RAND_FUNCTION() (INTEGER_TYPE) randlimb () 32#endif 33 34static void 35test_generic_ui (mpfr_prec_t p0, mpfr_prec_t p1, unsigned int N) 36{ 37 mpfr_prec_t prec, yprec; 38 mpfr_t x, y, z, t; 39 INTEGER_TYPE u; 40 mpfr_rnd_t rnd; 41 int inexact, compare, compare2; 42 unsigned int n; 43 44 mpfr_init (x); 45 mpfr_init (y); 46 mpfr_init (z); 47 mpfr_init (t); 48 49 /* generic test */ 50 for (prec = p0; prec <= p1; prec++) 51 { 52 mpfr_set_prec (x, prec); 53 mpfr_set_prec (z, prec); 54 mpfr_set_prec (t, prec); 55 yprec = prec + 10; 56 57 for (n = 0; n <= N; n++) 58 { 59 if (n > 1 || prec < p1) 60 RAND_FUNCTION (x); 61 else 62 { 63 /* Special cases tested in precision p1 if n <= 1. */ 64 mpfr_set_si (x, n == 0 ? 1 : -1, MPFR_RNDN); 65 mpfr_set_exp (x, mpfr_get_emin ()); 66 } 67 if (n < 2 || n > 3 || prec < p1) 68 u = INT_RAND_FUNCTION (); 69 else 70 { 71 /* Special cases tested in precision p1 if n = 2 or 3. */ 72 if ((INTEGER_TYPE) -1 < 0) /* signed, type long assumed */ 73 u = n == 2 ? LONG_MIN : LONG_MAX; 74 else /* unsigned */ 75 u = n == 2 ? 0 : -1; 76 } 77 rnd = RND_RAND_NO_RNDF (); 78 mpfr_set_prec (y, yprec); 79 compare = TEST_FUNCTION (y, x, u, rnd); 80 if (mpfr_can_round (y, yprec, rnd, rnd, prec)) 81 { 82 mpfr_set (t, y, rnd); 83 inexact = TEST_FUNCTION (z, x, u, rnd); 84 if (mpfr_cmp (t, z)) 85 { 86 printf ("results differ for x="); 87 mpfr_out_str (stdout, 2, prec, x, MPFR_RNDN); 88 printf ("\nu=%lu", (unsigned long) u); 89 printf (" prec=%lu rnd_mode=%s\n", 90 (unsigned long ) prec, mpfr_print_rnd_mode (rnd)); 91#ifdef TEST_FUNCTION_NAME 92 printf ("Function: %s\n", TEST_FUNCTION_NAME); 93#endif 94 printf ("got "); 95 mpfr_dump (z); 96 printf ("expected "); 97 mpfr_dump (t); 98 printf ("approx "); 99 mpfr_dump (y); 100 exit (1); 101 } 102 compare2 = mpfr_cmp (t, y); 103 /* if rounding to nearest, cannot know the sign of t - f(x) 104 because of composed rounding: y = o(f(x)) and t = o(y) */ 105 if (compare * compare2 >= 0) 106 compare = compare + compare2; 107 else 108 compare = inexact; /* cannot determine sign(t-f(x)) */ 109 if (! SAME_SIGN (inexact, compare) && rnd != MPFR_RNDF) 110 { 111 printf ("Wrong inexact flag for rnd=%s: expected %d, got %d" 112 "\n", mpfr_print_rnd_mode (rnd), compare, inexact); 113 printf ("x = "); mpfr_dump (x); 114 printf ("u = %lu\n", (unsigned long) u); 115 printf ("y = "); mpfr_dump (y); 116 printf ("t = "); mpfr_dump (t); 117 exit (1); 118 } 119 } 120 } 121 } 122 123 mpfr_clear (x); 124 mpfr_clear (y); 125 mpfr_clear (z); 126 mpfr_clear (t); 127} 128 129#undef RAND_FUNCTION 130#undef INTEGER_TYPE 131#undef TEST_FUNCTION 132#undef TEST_FUNCTION_NAME 133#undef test_generic_ui 134#undef INT_RAND_FUNCTION 135