1 /* Test file for mpfr_fpif. 2 3 Copyright 2012-2018 Free Software Foundation, Inc. 4 Contributed by Olivier Demengeon. 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 #define FILE_NAME_RW "tfpif_rw.dat" /* temporary name (written then read) */ 26 #define FILE_NAME_R "tfpif_r1.dat" /* fixed file name (read only) */ 27 #define FILE_NAME_R2 "tfpif_r2.dat" /* fixed file name (read only) with a 28 precision > MPFR_PREC_MAX */ 29 30 static void 31 doit (int argc, char *argv[], mpfr_prec_t p1, mpfr_prec_t p2) 32 { 33 char *filenameCompressed = FILE_NAME_RW; 34 char *data = FILE_NAME_R; 35 int status; 36 FILE *fh; 37 mpfr_t x[9]; 38 mpfr_t y; 39 int i, neg; 40 long pos; 41 42 mpfr_init2 (x[0], p1); 43 mpfr_init2 (x[8], p1); 44 mpfr_inits2 (p2, x[1], x[2], x[3], x[4], x[5], x[6], x[7], (mpfr_ptr) 0); 45 mpfr_set_str1 (x[0], "45.2564215000000018562786863185465335845947265625"); 46 mpfr_set_str1 (x[1], "45.2564215000000018562786863185465335845947265625"); 47 mpfr_set_str1 (x[2], "45.2564215000000018562786863185465335845947265625"); 48 mpfr_set_exp (x[2], -48000); 49 mpfr_set_inf (x[3], 1); 50 mpfr_set_zero (x[4], 1); 51 mpfr_set_nan (x[5]); 52 mpfr_set_ui (x[6], 104348, MPFR_RNDN); 53 mpfr_set_ui (x[7], 33215, MPFR_RNDN); 54 mpfr_div (x[8], x[6], x[7], MPFR_RNDN); 55 mpfr_div (x[6], x[6], x[7], MPFR_RNDN); 56 57 /* we first write to file FILE_NAME_RW the numbers x[i] */ 58 fh = fopen (filenameCompressed, "w"); 59 if (fh == NULL) 60 { 61 printf ("Failed to open for writing %s\n", filenameCompressed); 62 exit (1); 63 } 64 65 for (neg = 0; neg < 2; neg++) 66 for (i = 0; i < 9; i++) 67 { 68 if (neg) 69 MPFR_CHANGE_SIGN (x[i]); 70 71 status = mpfr_fpif_export (fh, x[i]); 72 if (status != 0) 73 { 74 fclose (fh); 75 printf ("Failed to export number %d, neg=%d\n", i, neg); 76 exit (1); 77 } 78 79 if (neg) 80 MPFR_CHANGE_SIGN (x[i]); 81 } 82 83 fclose (fh); 84 85 /* we then read back FILE_NAME_RW and check we get the same numbers x[i] */ 86 fh = fopen (filenameCompressed, "r"); 87 if (fh == NULL) 88 { 89 printf ("Failed to open for reading %s\n", filenameCompressed); 90 exit (1); 91 } 92 93 for (neg = 0; neg < 2; neg++) 94 for (i = 0; i < 9; i++) 95 { 96 mpfr_prec_t px, py; 97 98 if (neg) 99 MPFR_CHANGE_SIGN (x[i]); 100 101 mpfr_init2 (y, 2); 102 /* Set the sign bit of y to the opposite of the expected one. 103 Thus, if mpfr_fpif_import forgets to set the sign, this will 104 be detected. */ 105 MPFR_SET_SIGN (y, - MPFR_SIGN (x[i])); 106 mpfr_fpif_import (y, fh); 107 px = mpfr_get_prec (x[i]); 108 py = mpfr_get_prec (y); 109 if (px != py) 110 { 111 printf ("doit failed on written number %d, neg=%d:" 112 " bad precision\n", i, neg); 113 printf ("expected %ld\n", (long) px); 114 printf ("got %ld\n", (long) py); 115 exit (1); 116 } 117 if (MPFR_SIGN (x[i]) != MPFR_SIGN (y)) 118 { 119 printf ("doit failed on written number %d, neg=%d:" 120 " bad sign\n", i, neg); 121 printf ("expected %d\n", (int) MPFR_SIGN (x[i])); 122 printf ("got %d\n", (int) MPFR_SIGN (y)); 123 exit (1); 124 } 125 if (! SAME_VAL (x[i], y)) 126 { 127 printf ("doit failed on written number %d, neg=%d\n", i, neg); 128 printf ("expected "); mpfr_dump (x[i]); 129 printf ("got "); mpfr_dump (y); 130 exit (1); 131 } 132 mpfr_clear (y); 133 134 if (neg) 135 MPFR_CHANGE_SIGN (x[i]); 136 } 137 fclose (fh); 138 139 /* we do the same for the fixed file FILE_NAME_R, this ensures 140 we get same results with different word size or endianness */ 141 fh = src_fopen (data, "r"); 142 if (fh == NULL) 143 { 144 printf ("Failed to open for reading %s in srcdir\n", data); 145 exit (1); 146 } 147 148 /* the fixed file FILE_NAME_R assumes p1=130 and p2=2048 */ 149 for (i = 0; i < 9 && (p1 == 130 && p2 == 2048); i++) 150 { 151 mpfr_prec_t px, py; 152 153 mpfr_init2 (y, 2); 154 /* Set the sign bit of y to the opposite of the expected one. 155 Thus, if mpfr_fpif_import forgets to set the sign, this will 156 be detected. */ 157 MPFR_SET_SIGN (y, - MPFR_SIGN (x[i])); 158 pos = ftell (fh); 159 mpfr_fpif_import (y, fh); 160 px = mpfr_get_prec (x[i]); 161 py = mpfr_get_prec (y); 162 if (px != py) 163 { 164 printf ("doit failed on data number %d, neg=%d:" 165 " bad precision\n", i, neg); 166 printf ("expected %ld\n", (long) px); 167 printf ("got %ld\n", (long) py); 168 exit (1); 169 } 170 if (MPFR_SIGN (x[i]) != MPFR_SIGN (y)) 171 { 172 printf ("doit failed on data number %d, neg=%d:" 173 " bad sign\n", i, neg); 174 printf ("expected %d\n", (int) MPFR_SIGN (x[i])); 175 printf ("got %d\n", (int) MPFR_SIGN (y)); 176 exit (1); 177 } 178 if (! SAME_VAL (x[i], y)) 179 { 180 printf ("doit failed on data number %d, neg=%d, at offset 0x%lx\n", 181 i, neg, (unsigned long) pos); 182 printf ("expected "); mpfr_dump (x[i]); 183 printf ("got "); mpfr_dump (y); 184 exit (1); 185 } 186 mpfr_clear (y); 187 } 188 fclose (fh); 189 190 for (i = 0; i < 9; i++) 191 mpfr_clear (x[i]); 192 193 remove (filenameCompressed); 194 } 195 196 static void 197 check_bad (void) 198 { 199 char *filenameCompressed = FILE_NAME_RW; 200 int status; 201 FILE *fh; 202 mpfr_t x; 203 unsigned char badData[6][2] = 204 { { 7, 0 }, { 16, 0 }, { 23, 118 }, { 23, 95 }, { 23, 127 }, { 23, 47 } }; 205 int badDataSize[6] = { 1, 1, 2, 2, 2, 2 }; 206 int i; 207 208 mpfr_init2 (x, 2); 209 status = mpfr_fpif_export (NULL, x); 210 if (status == 0) 211 { 212 printf ("mpfr_fpif_export did not fail with a NULL file\n"); 213 exit(1); 214 } 215 status = mpfr_fpif_import (x, NULL); 216 if (status == 0) 217 { 218 printf ("mpfr_fpif_import did not fail with a NULL file\n"); 219 exit(1); 220 } 221 222 fh = fopen (filenameCompressed, "w+"); 223 if (fh == NULL) 224 { 225 printf ("Failed to open for reading/writing %s, exiting...\n", 226 filenameCompressed); 227 fclose (fh); 228 remove (filenameCompressed); 229 exit (1); 230 } 231 status = mpfr_fpif_import (x, fh); 232 if (status == 0) 233 { 234 printf ("mpfr_fpif_import did not fail on a empty file\n"); 235 fclose (fh); 236 remove (filenameCompressed); 237 exit(1); 238 } 239 240 for (i = 0; i < 6; i++) 241 { 242 rewind (fh); 243 status = fwrite (&badData[i][0], badDataSize[i], 1, fh); 244 if (status != 1) 245 { 246 printf ("Write error on the test file\n"); 247 fclose (fh); 248 remove (filenameCompressed); 249 exit(1); 250 } 251 rewind (fh); 252 status = mpfr_fpif_import (x, fh); 253 if (status == 0) 254 { 255 printf ("mpfr_fpif_import did not fail on a bad imported data\n"); 256 switch (i) 257 { 258 case 0: 259 printf (" not enough precision data\n"); 260 break; 261 case 1: 262 printf (" no exponent data\n"); 263 break; 264 case 2: 265 printf (" too big exponent\n"); 266 break; 267 case 3: 268 printf (" not enough exponent data\n"); 269 break; 270 case 4: 271 printf (" exponent data wrong\n"); 272 break; 273 case 5: 274 printf (" no limb data\n"); 275 break; 276 default: 277 printf ("Test fatal error, unknown case\n"); 278 break; 279 } 280 fclose (fh); 281 remove (filenameCompressed); 282 exit(1); 283 } 284 } 285 286 fclose (fh); 287 mpfr_clear (x); 288 289 fh = fopen (filenameCompressed, "r"); 290 if (fh == NULL) 291 { 292 printf ("Failed to open for reading %s, exiting...\n", 293 filenameCompressed); 294 exit (1); 295 } 296 297 mpfr_init2 (x, 2); 298 status = mpfr_fpif_export (fh, x); 299 if (status == 0) 300 { 301 printf ("mpfr_fpif_export did not fail on a read only stream\n"); 302 exit(1); 303 } 304 fclose (fh); 305 remove (filenameCompressed); 306 mpfr_clear (x); 307 } 308 309 /* exercise error when precision > MPFR_PREC_MAX */ 310 static void 311 extra (void) 312 { 313 char *data = FILE_NAME_R2; 314 mpfr_t x; 315 FILE *fp; 316 int ret; 317 318 mpfr_init2 (x, 17); 319 mpfr_set_ui (x, 42, MPFR_RNDN); 320 fp = src_fopen (data, "r"); 321 if (fp == NULL) 322 { 323 printf ("Failed to open for reading %s in srcdir, exiting...\n", data); 324 exit (1); 325 } 326 ret = mpfr_fpif_import (x, fp); 327 MPFR_ASSERTN (ret != 0); /* import failure */ 328 MPFR_ASSERTN (mpfr_get_prec (x) == 17); /* precision did not change */ 329 MPFR_ASSERTN (mpfr_cmp_ui0 (x, 42) == 0); /* value is still 42 */ 330 fclose (fp); 331 mpfr_clear (x); 332 } 333 334 int 335 main (int argc, char *argv[]) 336 { 337 if (argc != 1) 338 { 339 printf ("Usage: %s\n", argv[0]); 340 exit (1); 341 } 342 343 tests_start_mpfr (); 344 345 extra (); 346 doit (argc, argv, 130, 2048); 347 doit (argc, argv, 1, 53); 348 check_bad (); 349 350 tests_end_mpfr (); 351 352 return 0; 353 } 354