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