| OLD | NEW |
| (Empty) |
| 1 /* Test file for mpfr_get_f. | |
| 2 | |
| 3 Copyright 2005, 2006, 2007, 2008, 2009 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 2.1 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.LIB. If not, write to | |
| 20 the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, | |
| 21 MA 02110-1301, USA. */ | |
| 22 | |
| 23 #include <stdio.h> | |
| 24 #include <stdlib.h> | |
| 25 #include <limits.h> | |
| 26 | |
| 27 #include "mpfr-test.h" | |
| 28 | |
| 29 /* Test that there is no lost of accuracy when converting a mpfr_t number | |
| 30 into a mpf_t number (test with various precisions and exponents). */ | |
| 31 static void | |
| 32 prec_test (void) | |
| 33 { | |
| 34 int px, py; | |
| 35 | |
| 36 for (py = 3; py <= 136; py++) | |
| 37 { | |
| 38 mpfr_t y1, y2, y3; | |
| 39 | |
| 40 mpfr_init2 (y1, py); | |
| 41 mpfr_init2 (y2, py); | |
| 42 mpfr_init2 (y3, py); | |
| 43 | |
| 44 for (px = 32; px <= 160; px += 32) | |
| 45 { | |
| 46 mpf_t x1, x2, x3; | |
| 47 int e; | |
| 48 | |
| 49 mpf_init (x1); | |
| 50 mpf_init (x2); | |
| 51 mpf_init (x3); | |
| 52 mpfr_set_ui_2exp (y1, 1, py - 1, GMP_RNDN); | |
| 53 mpfr_get_f (x1, y1, GMP_RNDN); /* exact (power of 2) */ | |
| 54 mpf_set (x2, x1); | |
| 55 mpfr_set (y2, y1, GMP_RNDN); | |
| 56 | |
| 57 for (e = py - 2; e >= 0; e--) | |
| 58 { | |
| 59 int inex; | |
| 60 mpf_div_2exp (x2, x2, 1); | |
| 61 mpf_add (x1, x1, x2); | |
| 62 mpfr_div_2exp (y2, y2, 1, GMP_RNDN); | |
| 63 inex = mpfr_add (y1, y1, y2, GMP_RNDN); | |
| 64 MPFR_ASSERTN (inex == 0); | |
| 65 mpfr_set_f (y3, x1, GMP_RNDN); | |
| 66 if (! mpfr_equal_p (y1, y3)) | |
| 67 break; | |
| 68 mpfr_get_f (x3, y3, GMP_RNDN); | |
| 69 if (mpf_cmp (x1, x3) != 0) | |
| 70 { | |
| 71 printf ("Error in prec_test (px = %d, py = %d, e = %d)\n", | |
| 72 px, py, e); | |
| 73 printf ("x1 = "); | |
| 74 mpf_out_str (stdout, 16, 0, x1); | |
| 75 printf ("\nx2 = "); | |
| 76 mpf_out_str (stdout, 16, 0, x1); | |
| 77 printf ("\n"); | |
| 78 exit (1); | |
| 79 } | |
| 80 } | |
| 81 | |
| 82 mpf_clear (x1); | |
| 83 mpf_clear (x2); | |
| 84 mpf_clear (x3); | |
| 85 } | |
| 86 | |
| 87 mpfr_clear (y1); | |
| 88 mpfr_clear (y2); | |
| 89 mpfr_clear (y3); | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 int | |
| 94 main (void) | |
| 95 { | |
| 96 mpf_t x; | |
| 97 mpfr_t y, z; | |
| 98 unsigned long i; | |
| 99 mp_exp_t e; | |
| 100 int inex; | |
| 101 | |
| 102 tests_start_mpfr (); | |
| 103 | |
| 104 mpfr_init (y); | |
| 105 mpfr_init (z); | |
| 106 mpf_init (x); | |
| 107 | |
| 108 mpfr_set_nan (y); | |
| 109 if (mpfr_get_f (x, y, GMP_RNDN) == 0) | |
| 110 { | |
| 111 printf ("Error: mpfr_get_f(NaN) should fail\n"); | |
| 112 exit (1); | |
| 113 } | |
| 114 | |
| 115 mpfr_set_inf (y, 1); | |
| 116 if (mpfr_get_f (x, y, GMP_RNDN) == 0) | |
| 117 { | |
| 118 printf ("Error: mpfr_get_f(+Inf) should fail\n"); | |
| 119 exit (1); | |
| 120 } | |
| 121 | |
| 122 mpfr_set_inf (y, -1); | |
| 123 if (mpfr_get_f (x, y, GMP_RNDN) == 0) | |
| 124 { | |
| 125 printf ("Error: mpfr_get_f(-Inf) should fail\n"); | |
| 126 exit (1); | |
| 127 } | |
| 128 | |
| 129 mpfr_set_ui (y, 0, GMP_RNDN); | |
| 130 if (mpfr_get_f (x, y, GMP_RNDN) || mpf_cmp_ui (x, 0)) | |
| 131 { | |
| 132 printf ("Error: mpfr_get_f(+0) fails\n"); | |
| 133 exit (1); | |
| 134 } | |
| 135 | |
| 136 mpfr_set_ui (y, 0, GMP_RNDN); | |
| 137 mpfr_neg (y, y, GMP_RNDN); | |
| 138 if (mpfr_get_f (x, y, GMP_RNDN) || mpf_cmp_ui (x, 0)) | |
| 139 { | |
| 140 printf ("Error: mpfr_get_f(-0) fails\n"); | |
| 141 exit (1); | |
| 142 } | |
| 143 | |
| 144 i = 1; | |
| 145 while (i) | |
| 146 { | |
| 147 mpfr_set_ui (y, i, GMP_RNDN); | |
| 148 if (mpfr_get_f (x, y, GMP_RNDN) || mpf_cmp_ui (x, i)) | |
| 149 { | |
| 150 printf ("Error: mpfr_get_f(%lu) fails\n", i); | |
| 151 exit (1); | |
| 152 } | |
| 153 if (i <= - (unsigned long) LONG_MIN) | |
| 154 { | |
| 155 long j = i < - (unsigned long) LONG_MIN ? - (long) i : LONG_MIN; | |
| 156 mpfr_set_si (y, j, GMP_RNDN); | |
| 157 if (mpfr_get_f (x, y, GMP_RNDN) || mpf_cmp_si (x, j)) | |
| 158 { | |
| 159 printf ("Error: mpfr_get_f(-%lu) fails\n", i); | |
| 160 exit (1); | |
| 161 } | |
| 162 } | |
| 163 i *= 2; | |
| 164 } | |
| 165 | |
| 166 /* same tests, but with a larger precision for y, which requires to | |
| 167 round it */ | |
| 168 mpfr_set_prec (y, 100); | |
| 169 i = 1; | |
| 170 while (i) | |
| 171 { | |
| 172 mpfr_set_ui (y, i, GMP_RNDN); | |
| 173 if (mpfr_get_f (x, y, GMP_RNDN) || mpf_cmp_ui (x, i)) | |
| 174 { | |
| 175 printf ("Error: mpfr_get_f(%lu) fails\n", i); | |
| 176 exit (1); | |
| 177 } | |
| 178 mpfr_set_si (y, (signed long) -i, GMP_RNDN); | |
| 179 if (mpfr_get_f (x, y, GMP_RNDN) || mpf_cmp_si (x, (signed long) -i)) | |
| 180 { | |
| 181 printf ("Error: mpfr_get_f(-%lu) fails\n", i); | |
| 182 exit (1); | |
| 183 } | |
| 184 i *= 2; | |
| 185 } | |
| 186 | |
| 187 /* bug reported by Jim White */ | |
| 188 for (e = 0; e <= 2 * BITS_PER_MP_LIMB; e++) | |
| 189 { | |
| 190 /* test with 2^(-e) */ | |
| 191 mpfr_set_ui (y, 1, GMP_RNDN); | |
| 192 mpfr_div_2exp (y, y, e, GMP_RNDN); | |
| 193 mpfr_get_f (x, y, GMP_RNDN); | |
| 194 mpf_mul_2exp (x, x, e); | |
| 195 if (mpf_cmp_ui (x, 1) != 0) | |
| 196 { | |
| 197 printf ("Error: mpfr_get_f(x,y,GMP_RNDN) fails\n"); | |
| 198 printf ("y="); | |
| 199 mpfr_dump (y); | |
| 200 printf ("x="); | |
| 201 mpf_div_2exp (x, x, e); | |
| 202 mpf_dump (x); | |
| 203 exit (1); | |
| 204 } | |
| 205 | |
| 206 /* test with 2^(e) */ | |
| 207 mpfr_set_ui (y, 1, GMP_RNDN); | |
| 208 mpfr_mul_2exp (y, y, e, GMP_RNDN); | |
| 209 mpfr_get_f (x, y, GMP_RNDN); | |
| 210 mpf_div_2exp (x, x, e); | |
| 211 if (mpf_cmp_ui (x, 1) != 0) | |
| 212 { | |
| 213 printf ("Error: mpfr_get_f(x,y,GMP_RNDN) fails\n"); | |
| 214 printf ("y="); | |
| 215 mpfr_dump (y); | |
| 216 printf ("x="); | |
| 217 mpf_mul_2exp (x, x, e); | |
| 218 mpf_dump (x); | |
| 219 exit (1); | |
| 220 } | |
| 221 } | |
| 222 | |
| 223 /* Bug reported by Yury Lukach on 2006-04-05 */ | |
| 224 mpfr_set_prec (y, 32); | |
| 225 mpfr_set_prec (z, 32); | |
| 226 mpf_set_prec (x, 32); | |
| 227 mpfr_set_ui_2exp (y, 0xc1234567, -30, GMP_RNDN); | |
| 228 mpfr_get_f (x, y, GMP_RNDN); | |
| 229 inex = mpfr_set_f (z, x, GMP_RNDN); | |
| 230 if (inex || ! mpfr_equal_p (y, z)) | |
| 231 { | |
| 232 printf ("Error in mpfr_get_f:\n inex = %d, y = ", inex); | |
| 233 mpfr_dump (z); | |
| 234 printf ("Expected:\n inex = 0, y = "); | |
| 235 mpfr_dump (y); | |
| 236 exit (1); | |
| 237 } | |
| 238 | |
| 239 mpfr_clear (y); | |
| 240 mpfr_clear (z); | |
| 241 mpf_clear (x); | |
| 242 | |
| 243 prec_test (); | |
| 244 | |
| 245 tests_end_mpfr (); | |
| 246 return 0; | |
| 247 } | |
| OLD | NEW |