1/* tinternals -- Test for internals. 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 MPFR_NEED_LONGLONG_H 24#include "mpfr-test.h" 25 26static void 27test_int_ceil_log2 (void) 28{ 29 int i; 30 int val[16] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 }; 31 32 for (i = 1; i < 17; i++) 33 { 34 if (MPFR_INT_CEIL_LOG2 (i) != val[i-1]) 35 { 36 printf ("Error 1 in test_int_ceil_log2 for i = %d\n", i); 37 exit (1); 38 } 39 if (MPFR_INT_CEIL_LOG2 (i) != __gmpfr_int_ceil_log2 (i)) 40 { 41 printf ("Error 2 in test_int_ceil_log2 for i = %d\n", i); 42 exit (1); 43 } 44 } 45} 46 47static void 48test_round_near_x (void) 49{ 50 mpfr_t x, y, z, eps; 51 mpfr_exp_t e; 52 int failures = 0, mx, neg, err, dir, r, inex, inex2; 53 char buffer[7], *p; 54 55 mpfr_inits (x, y, z, eps, (mpfr_ptr) 0); 56 mpfr_set_prec (x, 5); 57 mpfr_set_prec (y, 3); 58 mpfr_set_prec (z, 3); 59 mpfr_set_prec (eps, 2); 60 mpfr_set_ui_2exp (eps, 1, -32, MPFR_RNDN); 61 62 for (mx = 16; mx < 32; mx++) 63 { 64 mpfr_set_ui_2exp (x, mx, -2, MPFR_RNDN); 65 for (p = buffer, neg = 0; 66 neg <= 1; 67 mpfr_neg (x, x, MPFR_RNDN), p++, neg++) 68 for (err = 2; err <= 6; err++) 69 for (dir = 0; dir <= 1; dir++) 70 RND_LOOP_NO_RNDF (r) 71 { 72 inex = mpfr_round_near_x (y, x, err, dir, (mpfr_rnd_t) r); 73 74 if (inex == 0 && err < 6) 75 { 76 /* The test is more restrictive than necessary. 77 So, no failure in this case. */ 78 continue; 79 } 80 81 inex2 = ((dir ^ neg) ? mpfr_add : mpfr_sub) 82 (z, x, eps, (mpfr_rnd_t) r); 83 if (inex * inex2 <= 0) 84 printf ("Bad return value (%d instead of %d) for:\n", 85 inex, inex2); 86 else if (mpfr_equal_p (y, z)) 87 continue; /* correct inex and y */ 88 else 89 { 90 printf ("Bad MPFR value (should have got "); 91 mpfr_out_str (stdout, 2, 3, z, MPFR_RNDZ); 92 printf (") for:\n"); 93 } 94 95 if (!mpfr_get_str (buffer, &e, 2, 5, x, MPFR_RNDZ) || e != 3) 96 { 97 printf ("mpfr_get_str failed in test_round_near_x\n"); 98 exit (1); 99 } 100 printf ("x = %c%c%c%c.%c%c, ", neg ? '-' : '+', 101 p[0], p[1], p[2], p[3], p[4]); 102 printf ("err = %d, dir = %d, r = %s --> inex = %2d", 103 err, dir, mpfr_print_rnd_mode ((mpfr_rnd_t) r), inex); 104 if (inex != 0) 105 { 106 printf (", y = "); 107 mpfr_out_str (stdout, 2, 3, y, MPFR_RNDZ); 108 } 109 printf ("\n"); 110 if (inex == 0) 111 printf ("Rounding was possible!\n"); 112 if (++failures == 10) /* show at most 10 failures */ 113 exit (1); 114 } 115 } 116 117 if (failures) 118 exit (1); 119 120 mpfr_clears (x, y, z, eps, (mpfr_ptr) 0); 121} 122 123static void 124test_set_prec_raw (void) 125{ 126 mpfr_t x; 127 int i; 128 129 mpfr_init2 (x, 53); 130 for (i = 2; i < 11; i++) 131 { 132 mpfr_set_prec_raw (x, i); 133 if (MPFR_PREC (x) != i) 134 { 135 printf ("[ERROR]: mpfr_set_prec_raw %d\n", i); 136 exit (1); 137 } 138 } 139 mpfr_clear (x); 140} 141 142int 143main (int argc, char **argv) 144{ 145 tests_start_mpfr (); 146 147 test_int_ceil_log2 (); 148 149 test_round_near_x (); 150 test_set_prec_raw (); 151 152 tests_end_mpfr (); 153 return 0; 154} 155