tfpif.c revision 1.1.1.1.4.2 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