1 /* Generic test file for functions with one mpfr_t argument and an integer. 2 3 Copyright 2005-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 /* 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 34 static void 35 test_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