1 /* Test file for mpfr_const_log2. 2 3 Copyright 1999, 2001-2018 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 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 "mpfr-test.h" 24 25 /* tlog2 [prec] [rnd] [0 = no print] */ 26 27 static void 28 check (mpfr_prec_t p0, mpfr_prec_t p1) 29 { 30 mpfr_t x, y, z; 31 int i, inex, inex_ref; 32 33 mpfr_init (x); 34 mpfr_init (y); 35 mpfr_init2 (z, p1 + 10); 36 mpfr_const_log2 (z, MPFR_RNDN); 37 mpfr_clear_cache (__gmpfr_cache_const_log2); 38 39 for (; p0 <= p1; p0++) 40 { 41 mpfr_set_prec (x, p0); 42 mpfr_set_prec (y, p0); 43 RND_LOOP_NO_RNDF (i) 44 { 45 mpfr_rnd_t rnd = (mpfr_rnd_t) i; 46 inex = mpfr_const_log2 (x, rnd); 47 inex_ref = mpfr_set (y, z, rnd); 48 if (! mpfr_can_round (z, mpfr_get_prec (z), MPFR_RNDN, rnd, p0)) 49 { 50 printf ("increase guard precision in check()\n"); 51 exit (1); 52 } 53 if (mpfr_cmp (x, y) || inex != inex_ref) 54 { 55 printf ("mpfr_const_log2 fails for prec=%u, rnd=%s\n", 56 (unsigned int) p0, mpfr_print_rnd_mode (rnd)); 57 printf ("expected "), mpfr_dump (y); 58 printf ("got "), mpfr_dump (x); 59 printf ("expected inex = %d\n", inex_ref); 60 printf ("got inex = %d\n", inex); 61 exit (1); 62 } 63 } 64 } 65 66 mpfr_clear (x); 67 mpfr_clear (y); 68 mpfr_clear (z); 69 } 70 71 static void 72 check_large (void) 73 { 74 mpfr_t x, y, z; 75 76 mpfr_init2 (x, 25000); 77 mpfr_init2 (y, 26000); 78 mpfr_init2 (z, 26000); 79 (mpfr_const_log2) (x, MPFR_RNDN); /* First one ! */ 80 (mpfr_const_log2) (y, MPFR_RNDN); /* Then the other - cache - */ 81 mpfr_set (z, y, MPFR_RNDN); 82 mpfr_prec_round (y, 25000, MPFR_RNDN); 83 if (mpfr_cmp (x, y) != 0) 84 { 85 printf ("const_log2: error for large prec\n"); 86 printf ("x = "); 87 mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); 88 printf ("\n"); 89 printf ("y = "); 90 mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN); 91 printf ("\n"); 92 printf ("z = "); 93 mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); 94 printf ("\n"); 95 exit (1); 96 } 97 98 /* worst-case with 15 successive ones after last bit, 99 to exercise can_round loop */ 100 mpfr_set_prec (x, 26249); 101 mpfr_const_log2 (x, MPFR_RNDZ); 102 103 mpfr_clears (x, y, z, (mpfr_ptr) 0); 104 } 105 106 static void 107 check_cache (void) 108 { 109 mpfr_t x; 110 int i; 111 112 mpfr_init2 (x, 195); 113 mpfr_free_cache (); 114 i = mpfr_const_log2 (x, MPFR_RNDN); 115 if (i == 0) 116 { 117 printf("Error for log2. Invalid ternary value (1).\n"); 118 exit (1); 119 } 120 mpfr_set_prec (x, 194); 121 i = mpfr_const_log2 (x, MPFR_RNDN); 122 if (i == 0) 123 { 124 printf("Error for log2. Invalid ternary value (2).\n"); 125 exit (1); 126 } 127 128 mpfr_free_cache (); 129 mpfr_set_prec (x, 9); 130 mpfr_const_log2 (x, MPFR_RNDN); 131 mpfr_set_prec (x, 8); 132 mpfr_const_log2 (x, MPFR_RNDN); 133 if (mpfr_cmp_str (x, "0.10110001E0", 2, MPFR_RNDN)) 134 { 135 printf("Error for log2. Wrong rounding.\n"); 136 exit (1); 137 } 138 139 mpfr_clear (x); 140 } 141 142 /* Wrapper for tgeneric */ 143 static int 144 my_const_log2 (mpfr_ptr x, mpfr_srcptr y, mpfr_rnd_t r) 145 { 146 return mpfr_const_log2 (x, r); 147 } 148 149 #define RAND_FUNCTION(x) mpfr_set_ui ((x), 0, MPFR_RNDN) 150 #define TEST_FUNCTION my_const_log2 151 #include "tgeneric.c" 152 153 int 154 main (int argc, char *argv[]) 155 { 156 mpfr_t x; 157 int p; 158 mpfr_rnd_t rnd; 159 160 tests_start_mpfr (); 161 162 p = (argc>1) ? atoi(argv[1]) : 53; 163 rnd = (argc>2) ? (mpfr_rnd_t) atoi(argv[2]) : MPFR_RNDN; 164 165 mpfr_init (x); 166 167 /* increase the 2nd argument to say 300000 to perform the exhaustive search 168 in src/const_log2.c */ 169 check (MPFR_PREC_MIN, 1000); 170 171 /* check precision of 2 bits */ 172 mpfr_set_prec (x, 2); 173 mpfr_const_log2 (x, MPFR_RNDN); 174 if (mpfr_cmp_ui_2exp(x, 3, -2)) /* 3*2^-2 */ 175 { 176 printf ("mpfr_const_log2 failed for prec=2, rnd=MPFR_RNDN\n" 177 "expected 0.75, got "); 178 mpfr_out_str(stdout, 10, 0, x, MPFR_RNDN); 179 putchar('\n'); 180 exit (1); 181 } 182 183 if (argc >= 2) 184 { 185 mpfr_set_prec (x, p); 186 mpfr_const_log2 (x, rnd); 187 mpfr_out_str (stdout, 10, 0, x, rnd); 188 puts (""); 189 } 190 191 mpfr_set_prec (x, 53); 192 mpfr_const_log2 (x, MPFR_RNDZ); 193 if (mpfr_cmp_str1 (x, "6.9314718055994530941e-1") ) 194 { 195 printf ("mpfr_const_log2 failed for prec=53\n"); 196 exit (1); 197 } 198 199 mpfr_set_prec (x, 32); 200 mpfr_const_log2 (x, MPFR_RNDN); 201 if (mpfr_cmp_str1 (x, "0.69314718060195446")) 202 { 203 printf ("mpfr_const_log2 failed for prec=32\n"); 204 exit (1); 205 } 206 207 mpfr_clear (x); 208 209 check_large (); 210 check_cache (); 211 212 test_generic (MPFR_PREC_MIN, 200, 1); 213 214 tests_end_mpfr (); 215 return 0; 216 } 217