1/* Test file for mpfr_sub1sp.
2
3Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4Contributed by the Arenaire and Cacao projects, INRIA.
5
6This file is part of the GNU MPFR Library.
7
8The GNU MPFR Library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as published by
10the Free Software Foundation; either version 3 of the License, or (at your
11option) any later version.
12
13The GNU MPFR Library is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16License for more details.
17
18You should have received a copy of the GNU Lesser General Public License
19along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22
23#include <stdio.h>
24#include <stdlib.h>
25
26#include "mpfr-test.h"
27
28static void check_special (void);
29static void check_random (mpfr_prec_t p);
30
31int
32main (void)
33{
34  mpfr_prec_t p;
35
36  tests_start_mpfr ();
37
38  check_special ();
39  for (p = 2 ; p < 200 ; p++)
40    check_random (p);
41
42  tests_end_mpfr ();
43  return 0;
44}
45
46#define STD_ERROR \
47            {\
48              printf("ERROR: for %s and p=%lu and i=%d:\nY=",\
49                     mpfr_print_rnd_mode ((mpfr_rnd_t) r), p, i);\
50               mpfr_print_binary(y);\
51               printf("\nZ="); mpfr_print_binary(z);\
52               printf("\nReal: "); mpfr_print_binary(x2);\
53               printf("\nGot : "); mpfr_print_binary(x);\
54               putchar('\n');\
55               exit(1);\
56            }
57
58#define STD_ERROR2 \
59            {\
60              printf("ERROR: for %s and p=%lu and i=%d:\nY=",\
61                      mpfr_print_rnd_mode ((mpfr_rnd_t) r), p, i);\
62               mpfr_print_binary(y);\
63               printf("\nZ="); mpfr_print_binary(z);\
64               printf("\nR="); mpfr_print_binary(x);\
65               printf("\nWrong inexact flag. Real: %d. Got: %d\n", \
66                      inexact1, inexact2); \
67               exit(1);\
68            }
69
70static void
71check_random (mpfr_prec_t p)
72{
73  mpfr_t x,y,z,x2;
74  int r;
75  int i, inexact1, inexact2;
76
77  mpfr_inits2 (p, x, y, z, x2, (mpfr_ptr) 0);
78
79  for (i = 0 ; i < 500 ; i++)
80    {
81      mpfr_urandomb (y, RANDS);
82      mpfr_urandomb (z, RANDS);
83      if (MPFR_IS_PURE_FP(y) && MPFR_IS_PURE_FP(z))
84        for(r = 0 ; r < MPFR_RND_MAX ; r++)
85          {
86            inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
87            inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
88            if (mpfr_cmp(x, x2))
89              STD_ERROR;
90            if (inexact1 != inexact2)
91              STD_ERROR2;
92          }
93    }
94
95  mpfr_clears (x, y, z, x2, (mpfr_ptr) 0);
96}
97
98static void
99check_special (void)
100{
101  mpfr_t x,y,z,x2;
102  int r;
103  mpfr_prec_t p;
104  int i = -1, inexact1, inexact2;
105  mpfr_exp_t es;
106
107  mpfr_inits (x, y, z, x2, (mpfr_ptr) 0);
108
109  for (r = 0 ; r < MPFR_RND_MAX ; r++)
110    {
111      p = 53;
112      mpfr_set_prec(x, 53);
113      mpfr_set_prec(x2, 53);
114      mpfr_set_prec(y, 53);
115      mpfr_set_prec(z, 53);
116
117      mpfr_set_str_binary (y,
118       "0.10110111101101110010010010011011000001101101011011001E31");
119
120      mpfr_sub1sp (x, y, y, (mpfr_rnd_t) r);
121      if (mpfr_cmp_ui(x, 0))
122        {
123          printf("Error for x-x with p=%lu. Expected 0. Got:", p);
124          mpfr_print_binary(x);
125          exit(1);
126        }
127
128      mpfr_set(z, y, (mpfr_rnd_t) r);
129      mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
130      if (mpfr_cmp_ui(x, 0))
131        {
132          printf("Error for x-y with y=x and p=%lu. Expected 0. Got:", p);
133          mpfr_print_binary(x);
134          exit(1);
135        }
136      /* diff = 0 */
137      mpfr_set_str_binary (y,
138       "0.10110111101101110010010010011011001001101101011011001E31");
139      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
140      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
141      if (mpfr_cmp(x, x2))
142        STD_ERROR;
143      if (inexact1 != inexact2)
144        STD_ERROR2;
145
146      /* Diff = 1 */
147      mpfr_set_str_binary (y,
148       "0.10110111101101110010010010011011000001101101011011001E30");
149      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
150      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
151      if (mpfr_cmp(x, x2))
152        STD_ERROR;
153      if (inexact1 != inexact2)
154        STD_ERROR2;
155
156      /* Diff = 2 */
157      mpfr_set_str_binary (y,
158       "0.10110111101101110010010010011011000101101101011011001E32");
159      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
160      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
161      if (mpfr_cmp(x, x2))
162        STD_ERROR;
163      if (inexact1 != inexact2)
164        STD_ERROR2;
165
166      /* Diff = 32 */
167      mpfr_set_str_binary (y,
168       "0.10110111101101110010010010011011000001101101011011001E63");
169      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
170      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
171      if (mpfr_cmp(x, x2))
172        STD_ERROR;
173      if (inexact1 != inexact2)
174        STD_ERROR2;
175
176      /* Diff = 52 */
177      mpfr_set_str_binary (y,
178       "0.10110111101101110010010010011011010001101101011011001E83");
179      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
180      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
181      if (mpfr_cmp(x, x2))
182        STD_ERROR;
183      if (inexact1 != inexact2)
184        STD_ERROR2;
185
186      /* Diff = 53 */
187      mpfr_set_str_binary (y,
188       "0.10110111101101110010010010011111000001101101011011001E31");
189      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
190      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
191      if (mpfr_cmp(x, x2))
192        STD_ERROR;
193      if (inexact1 != inexact2)
194        STD_ERROR2;
195
196      /* Diff > 200 */
197      mpfr_set_str_binary (y,
198       "0.10110111101101110010010010011011000001101101011011001E331");
199      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
200      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
201      if (mpfr_cmp(x, x2))
202        STD_ERROR;
203      if (inexact1 != inexact2)
204        STD_ERROR2;
205
206      mpfr_set_str_binary (y,
207       "0.10000000000000000000000000000000000000000000000000000E31");
208      mpfr_set_str_binary (z,
209       "0.11111111111111111111111111111111111111111111111111111E30");
210      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
211      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
212      if (mpfr_cmp(x, x2))
213        STD_ERROR;
214      if (inexact1 != inexact2)
215        STD_ERROR2;
216
217      mpfr_set_str_binary (y,
218       "0.10000000000000000000000000000000000000000000000000000E31");
219      mpfr_set_str_binary (z,
220       "0.11111111111111111111111111111111111111111111111111111E29");
221      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
222      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
223      if (mpfr_cmp(x, x2))
224        STD_ERROR;
225      if (inexact1 != inexact2)
226        STD_ERROR2;
227
228      mpfr_set_str_binary (y,
229       "0.10000000000000000000000000000000000000000000000000000E52");
230      mpfr_set_str_binary (z,
231       "0.10000000000010000000000000000000000000000000000000000E00");
232      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
233      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
234      if (mpfr_cmp(x, x2))
235        STD_ERROR;
236      if (inexact1 != inexact2)
237        STD_ERROR2;
238
239      mpfr_set_str_binary (y,
240        "0.11100000000000000000000000000000000000000000000000000E53");
241      mpfr_set_str_binary (z,
242        "0.10000000000000000000000000000000000000000000000000000E00");
243      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
244      inexact2 = mpfr_sub1sp(z, y, z, (mpfr_rnd_t) r);
245      mpfr_set(x, z, (mpfr_rnd_t) r);
246      if (mpfr_cmp(x, x2))
247        STD_ERROR;
248      if (inexact1 != inexact2)
249        STD_ERROR2;
250
251      mpfr_set_str_binary (y,
252       "0.10000000000000000000000000000000000000000000000000000E53");
253      mpfr_set_str_binary (z,
254       "0.10100000000000000000000000000000000000000000000000000E00");
255      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
256      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
257      if (mpfr_cmp(x, x2))
258        STD_ERROR;
259      if (inexact1 != inexact2)
260        STD_ERROR2;
261
262      mpfr_set_str_binary (y,
263        "0.10000000000000000000000000000000000000000000000000000E54");
264      mpfr_set_str_binary (z,
265        "0.10100000000000000000000000000000000000000000000000000E00");
266      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
267      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
268      if (mpfr_cmp(x, x2))
269        STD_ERROR;
270      if (inexact1 != inexact2)
271        STD_ERROR2;
272
273      p = 63;
274      mpfr_set_prec(x, p);
275      mpfr_set_prec(x2, p);
276      mpfr_set_prec(y, p);
277      mpfr_set_prec(z, p);
278      mpfr_set_str_binary (y,
279      "0.100000000000000000000000000000000000000000000000000000000000000E62");
280      mpfr_set_str_binary (z,
281      "0.110000000000000000000000000000000000000000000000000000000000000E00");
282      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
283      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
284      if (mpfr_cmp(x, x2))
285        STD_ERROR;
286      if (inexact1 != inexact2)
287        STD_ERROR2;
288
289      p = 64;
290      mpfr_set_prec(x, 64);
291      mpfr_set_prec(x2, 64);
292      mpfr_set_prec(y, 64);
293      mpfr_set_prec(z, 64);
294
295      mpfr_set_str_binary (y,
296      "0.1100000000000000000000000000000000000000000000000000000000000000E31");
297      mpfr_set_str_binary (z,
298      "0.1111111111111111111111111110000000000000000000000000011111111111E29");
299      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
300      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
301      if (mpfr_cmp(x, x2))
302        STD_ERROR;
303      if (inexact1 != inexact2)
304        STD_ERROR2;
305
306      mpfr_set_str_binary (y,
307      "0.1000000000000000000000000000000000000000000000000000000000000000E63");
308      mpfr_set_str_binary (z,
309      "0.1011000000000000000000000000000000000000000000000000000000000000E00");
310      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
311      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
312      if (mpfr_cmp(x, x2))
313        STD_ERROR;
314      if (inexact1 != inexact2)
315        STD_ERROR2;
316
317      mpfr_set_str_binary (y,
318      "0.1000000000000000000000000000000000000000000000000000000000000000E63");
319      mpfr_set_str_binary (z,
320      "0.1110000000000000000000000000000000000000000000000000000000000000E00");
321      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
322      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
323      if (mpfr_cmp(x, x2))
324        STD_ERROR;
325      if (inexact1 != inexact2)
326        STD_ERROR2;
327
328      mpfr_set_str_binary (y,
329        "0.10000000000000000000000000000000000000000000000000000000000000E63");
330      mpfr_set_str_binary (z,
331        "0.10000000000000000000000000000000000000000000000000000000000000E00");
332      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
333      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
334      if (mpfr_cmp(x, x2))
335        STD_ERROR;
336      if (inexact1 != inexact2)
337        STD_ERROR2;
338
339      mpfr_set_str_binary (y,
340      "0.1000000000000000000000000000000000000000000000000000000000000000E64");
341      mpfr_set_str_binary (z,
342      "0.1010000000000000000000000000000000000000000000000000000000000000E00");
343      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
344      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
345      if (mpfr_cmp(x, x2))
346        STD_ERROR;
347      if (inexact1 != inexact2)
348        STD_ERROR2;
349
350      MPFR_SET_NAN(x);
351      MPFR_SET_NAN(x2);
352      mpfr_set_str_binary (y,
353      "0.1000000000000000000000000000000000000000000000000000000000000000"
354                          "E-1073741823");
355      mpfr_set_str_binary (z,
356      "0.1100000000000000000000000000000000000000000000000000000000000000"
357                          "E-1073741823");
358      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
359      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
360      if (mpfr_cmp(x, x2))
361        STD_ERROR;
362      if (inexact1 != inexact2)
363        STD_ERROR2;
364
365      p = 9;
366      mpfr_set_prec(x, p);
367      mpfr_set_prec(x2, p);
368      mpfr_set_prec(y, p);
369      mpfr_set_prec(z, p);
370
371      mpfr_set_str_binary (y, "0.100000000E1");
372      mpfr_set_str_binary (z, "0.100000000E-8");
373      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
374      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
375      if (mpfr_cmp(x, x2))
376        STD_ERROR;
377      if (inexact1 != inexact2)
378        STD_ERROR2;
379
380      p = 34;
381      mpfr_set_prec(x, p);
382      mpfr_set_prec(x2, p);
383      mpfr_set_prec(y, p);
384      mpfr_set_prec(z, p);
385
386      mpfr_set_str_binary (y, "-0.1011110000111100010111011100110100E-18");
387      mpfr_set_str_binary (z, "0.1000101010110011010101011110000000E-14");
388      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
389      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
390      if (mpfr_cmp(x, x2))
391        STD_ERROR;
392      if (inexact1 != inexact2)
393        STD_ERROR2;
394
395      p = 124;
396      mpfr_set_prec(x, p);
397      mpfr_set_prec(x2, p);
398      mpfr_set_prec(y, p);
399      mpfr_set_prec(z, p);
400
401      mpfr_set_str_binary (y,
402"0.1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E1");
403      mpfr_set_str_binary (z,
404"0.1011111000100111000011001000011101010101101100101010101001000001110100001101110110001110111010000011101001100010111110001100E-31");
405      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
406      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
407      if (mpfr_cmp(x, x2))
408        STD_ERROR;
409      if (inexact1 != inexact2)
410        STD_ERROR2;
411
412      p = 288;
413      mpfr_set_prec(x, p);
414      mpfr_set_prec(x2, p);
415      mpfr_set_prec(y, p);
416      mpfr_set_prec(z, p);
417
418      mpfr_set_str_binary (y,
419     "0.111000110011000001000111101010111011110011101001101111111110000011100101000001001010110010101010011001010100000001110011110001010101101010001011101110100100001011110100110000101101100011010001001011011010101010000010001101001000110010010111111011110001111101001000101101001100101100101000E80");
420      mpfr_set_str_binary (z,
421     "-0.100001111111101001011010001100110010100111001110000110011101001011010100001000000100111011010110110010000000000010101101011000010000110001110010100001100101011100100100001011000100011110000001010101000100011101001000010111100000111000111011001000100100011000100000010010111000000100100111E-258");
422      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
423      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
424      if (mpfr_cmp(x, x2))
425        STD_ERROR;
426      if (inexact1 != inexact2)
427        STD_ERROR2;
428
429      p = 85;
430      mpfr_set_prec(x, p);
431      mpfr_set_prec(x2, p);
432      mpfr_set_prec(y, p);
433      mpfr_set_prec(z, p);
434
435      mpfr_set_str_binary (y,
436"0.1111101110100110110110100010101011101001100010100011110110110010010011101100101111100E-4");
437      mpfr_set_str_binary (z,
438"0.1111101110100110110110100010101001001000011000111000011101100101110100001110101010110E-4");
439      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
440      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
441      if (mpfr_cmp(x, x2))
442        STD_ERROR;
443      if (inexact1 != inexact2)
444        STD_ERROR2;
445
446      p = 64;
447      mpfr_set_prec(x, p); mpfr_set_prec(x2, p);
448      mpfr_set_prec(y, p); mpfr_set_prec(z, p);
449
450      mpfr_set_str_binary (y,
451                          "0.11000000000000000000000000000000"
452                          "00000000000000000000000000000000E1");
453      mpfr_set_str_binary (z,
454                          "0.10000000000000000000000000000000"
455                          "00000000000000000000000000000001E0");
456      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
457      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
458      if (mpfr_cmp(x, x2))
459        STD_ERROR;
460      if (inexact1 != inexact2)
461        STD_ERROR2;
462
463      mpfr_set_str_binary (y,
464                          "0.11000000000000000000000000000000"
465                          "000000000000000000000000000001E1");
466      mpfr_set_str_binary (z,
467                          "0.10000000000000000000000000000000"
468                          "00000000000000000000000000000001E0");
469      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
470      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
471      if (mpfr_cmp(x, x2))
472        STD_ERROR;
473      if (inexact1 != inexact2)
474        STD_ERROR2;
475
476      es = mpfr_get_emin ();
477      set_emin (-1024);
478
479      mpfr_set_str_binary (y,
480                          "0.10000000000000000000000000000000"
481                          "000000000000000000000000000000E-1023");
482      mpfr_set_str_binary (z,
483                          "0.10000000000000000000000000000000"
484                          "00000000000000000000000000000001E-1023");
485      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
486      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
487      if (mpfr_cmp(x, x2))
488        STD_ERROR;
489      if (inexact1 != inexact2)
490        STD_ERROR2;
491
492      mpfr_set_str_binary (y,
493                           "0.10000000000000000000000000000000"
494                           "000000000000000000000000000000E-1023");
495      mpfr_set_str_binary (z,
496                           "0.1000000000000000000000000000000"
497                           "000000000000000000000000000000E-1023");
498      inexact1 = mpfr_sub1(x2, y, z, (mpfr_rnd_t) r);
499      inexact2 = mpfr_sub1sp(x, y, z, (mpfr_rnd_t) r);
500      if (mpfr_cmp(x, x2))
501        STD_ERROR;
502      if (inexact1 != inexact2)
503        STD_ERROR2;
504
505      set_emin (es);
506    }
507
508  mpfr_clears (x, y, z, x2, (mpfr_ptr) 0);
509}
510