Imported Upstream version 3.1.1
[platform/upstream/mpfr.git] / tests / tremquo.c
1 /* tremquo -- test file for mpfr_remquo and mpfr_remainder
2
3 Copyright 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramel 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 <stdio.h>
24 #include <stdlib.h>
25
26 #include "mpfr-test.h"
27
28 static void
29 bug20090227 (void)
30 {
31   mpfr_t x, y, r1, r2;
32
33   mpfr_init2 (x, 118);
34   mpfr_init2 (y, 181);
35   mpfr_init2 (r1, 140);
36   mpfr_init2 (r2, 140);
37   mpfr_set_si (x, -1, MPFR_RNDN);
38   mpfr_set_str_binary (y, "1.100100100001111110110101010001000100001011010001100001000110100110001001100011001100010100010111000000011011100000111001101000100101001000000100100111000001000100010100110011111010");
39   mpfr_remainder (r1, x, y, MPFR_RNDU);
40   /* since the quotient is -1, r1 is the rounding of x+y */
41   mpfr_add (r2, x, y, MPFR_RNDU);
42   if (mpfr_cmp (r1, r2))
43     {
44       printf ("Error in mpfr_remainder (bug20090227)\n");
45       printf ("Expected ");
46       mpfr_dump (r2);
47       printf ("Got      ");
48       mpfr_dump (r1);
49       exit (1);
50     }
51   mpfr_clear (x);
52   mpfr_clear (y);
53   mpfr_clear (r1);
54   mpfr_clear (r2);
55 }
56
57 int
58 main (int argc, char *argv[])
59 {
60   mpfr_t x, y, r;
61   long q[1];
62
63   if (argc == 3) /* usage: tremquo x y (rnd=MPFR_RNDN implicit) */
64     {
65       mpfr_init2 (x, GMP_NUMB_BITS);
66       mpfr_init2 (y, GMP_NUMB_BITS);
67       mpfr_init2 (r, GMP_NUMB_BITS);
68       mpfr_set_str (x, argv[1], 10, MPFR_RNDN);
69       mpfr_set_str (y, argv[2], 10, MPFR_RNDN);
70       mpfr_remquo (r, q, x, y, MPFR_RNDN);
71       printf ("r=");
72       mpfr_out_str (stdout, 10, 0, r, MPFR_RNDN);
73       printf (" q=%ld\n", q[0]);
74       mpfr_clear (x);
75       mpfr_clear (y);
76       mpfr_clear (r);
77       return 0;
78     }
79
80   tests_start_mpfr ();
81
82   bug20090227 ();
83
84   mpfr_init (x);
85   mpfr_init (y);
86   mpfr_init (r);
87
88   /* special values */
89   mpfr_set_nan (x);
90   mpfr_set_ui (y, 1, MPFR_RNDN);
91   mpfr_remquo (r, q, x, y, MPFR_RNDN);
92   MPFR_ASSERTN(mpfr_nan_p (r));
93
94   mpfr_set_ui (x, 1, MPFR_RNDN);
95   mpfr_set_nan (y);
96   mpfr_remquo (r, q, x, y, MPFR_RNDN);
97   MPFR_ASSERTN(mpfr_nan_p (r));
98
99   mpfr_set_inf (x, 1); /* +Inf */
100   mpfr_set_ui (y, 1, MPFR_RNDN);
101   mpfr_remquo (r, q, x, y, MPFR_RNDN);
102   MPFR_ASSERTN (mpfr_nan_p (r));
103
104   mpfr_set_inf (x, 1); /* +Inf */
105   mpfr_set_ui (y, 0, MPFR_RNDN);
106   mpfr_remquo (r, q, x, y, MPFR_RNDN);
107   MPFR_ASSERTN (mpfr_nan_p (r));
108
109   mpfr_set_inf (x, 1); /* +Inf */
110   mpfr_set_inf (y, 1);
111   mpfr_remquo (r, q, x, y, MPFR_RNDN);
112   MPFR_ASSERTN (mpfr_nan_p (r));
113
114   mpfr_set_ui (x, 0, MPFR_RNDN);
115   mpfr_set_inf (y, 1);
116   mpfr_remquo (r, q, x, y, MPFR_RNDN);
117   MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_POS (r));
118   MPFR_ASSERTN (q[0] == (long) 0);
119
120   mpfr_set_ui (x, 0, MPFR_RNDN);
121   mpfr_neg (x, x, MPFR_RNDN); /* -0 */
122   mpfr_set_inf (y, 1);
123   mpfr_remquo (r, q, x, y, MPFR_RNDN);
124   MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_NEG (r));
125   MPFR_ASSERTN (q[0] == (long) 0);
126
127   mpfr_set_ui (x, 17, MPFR_RNDN);
128   mpfr_set_inf (y, 1);
129   mpfr_remquo (r, q, x, y, MPFR_RNDN);
130   MPFR_ASSERTN (mpfr_cmp (r, x) == 0);
131   MPFR_ASSERTN (q[0] == (long) 0);
132
133   mpfr_set_ui (x, 17, MPFR_RNDN);
134   mpfr_set_ui (y, 0, MPFR_RNDN);
135   mpfr_remquo (r, q, x, y, MPFR_RNDN);
136   MPFR_ASSERTN (mpfr_nan_p (r));
137
138   mpfr_set_ui (x, 0, MPFR_RNDN);
139   mpfr_set_ui (y, 17, MPFR_RNDN);
140   mpfr_remquo (r, q, x, y, MPFR_RNDN);
141   MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_POS (r));
142   MPFR_ASSERTN (q[0] == (long) 0);
143
144   mpfr_set_ui (x, 0, MPFR_RNDN);
145   mpfr_neg (x, x, MPFR_RNDN);
146   mpfr_set_ui (y, 17, MPFR_RNDN);
147   mpfr_remquo (r, q, x, y, MPFR_RNDN);
148   MPFR_ASSERTN (mpfr_cmp_ui (r, 0) == 0 && MPFR_IS_NEG (r));
149   MPFR_ASSERTN (q[0] == (long) 0);
150
151   mpfr_set_prec (x, 53);
152   mpfr_set_prec (y, 53);
153
154   /* check four possible sign combinations */
155   mpfr_set_ui (x, 42, MPFR_RNDN);
156   mpfr_set_ui (y, 17, MPFR_RNDN);
157   mpfr_remquo (r, q, x, y, MPFR_RNDN);
158   MPFR_ASSERTN (mpfr_cmp_ui (r, 8) == 0);
159   MPFR_ASSERTN (q[0] == (long) 2);
160   mpfr_set_si (x, -42, MPFR_RNDN);
161   mpfr_set_ui (y, 17, MPFR_RNDN);
162   mpfr_remquo (r, q, x, y, MPFR_RNDN);
163   MPFR_ASSERTN (mpfr_cmp_si (r, -8) == 0);
164   MPFR_ASSERTN (q[0] == (long) -2);
165   mpfr_set_si (x, -42, MPFR_RNDN);
166   mpfr_set_si (y, -17, MPFR_RNDN);
167   mpfr_remquo (r, q, x, y, MPFR_RNDN);
168   MPFR_ASSERTN (mpfr_cmp_si (r, -8) == 0);
169   MPFR_ASSERTN (q[0] == (long) 2);
170   mpfr_set_ui (x, 42, MPFR_RNDN);
171   mpfr_set_si (y, -17, MPFR_RNDN);
172   mpfr_remquo (r, q, x, y, MPFR_RNDN);
173   MPFR_ASSERTN (mpfr_cmp_ui (r, 8) == 0);
174   MPFR_ASSERTN (q[0] == (long) -2);
175
176   mpfr_set_prec (x, 100);
177   mpfr_set_prec (y, 50);
178   mpfr_set_ui (x, 42, MPFR_RNDN);
179   mpfr_nextabove (x); /* 42 + 2^(-94) */
180   mpfr_set_ui (y, 21, MPFR_RNDN);
181   mpfr_remquo (r, q, x, y, MPFR_RNDN);
182   MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 1, -94) == 0);
183   MPFR_ASSERTN (q[0] == (long) 2);
184
185   mpfr_set_prec (x, 50);
186   mpfr_set_prec (y, 100);
187   mpfr_set_ui (x, 42, MPFR_RNDN);
188   mpfr_nextabove (x); /* 42 + 2^(-44) */
189   mpfr_set_ui (y, 21, MPFR_RNDN);
190   mpfr_remquo (r, q, x, y, MPFR_RNDN);
191   MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 1, -44) == 0);
192   MPFR_ASSERTN (q[0] == (long) 2);
193
194   mpfr_set_prec (x, 100);
195   mpfr_set_prec (y, 50);
196   mpfr_set_ui (x, 42, MPFR_RNDN);
197   mpfr_set_ui (y, 21, MPFR_RNDN);
198   mpfr_nextabove (y); /* 21 + 2^(-45) */
199   mpfr_remquo (r, q, x, y, MPFR_RNDN);
200   /* r should be 42 - 2*(21 + 2^(-45)) = -2^(-44) */
201   MPFR_ASSERTN (mpfr_cmp_si_2exp (r, -1, -44) == 0);
202   MPFR_ASSERTN (q[0] == (long) 2);
203
204   mpfr_set_prec (x, 50);
205   mpfr_set_prec (y, 100);
206   mpfr_set_ui (x, 42, MPFR_RNDN);
207   mpfr_set_ui (y, 21, MPFR_RNDN);
208   mpfr_nextabove (y); /* 21 + 2^(-95) */
209   mpfr_remquo (r, q, x, y, MPFR_RNDN);
210   /* r should be 42 - 2*(21 + 2^(-95)) = -2^(-94) */
211   MPFR_ASSERTN (mpfr_cmp_si_2exp (r, -1, -94) == 0);
212   MPFR_ASSERTN (q[0] == (long) 2);
213
214   /* exercise large quotient */
215   mpfr_set_ui_2exp (x, 1, 65, MPFR_RNDN);
216   mpfr_set_ui (y, 1, MPFR_RNDN);
217   /* quotient is 2^65 */
218   mpfr_remquo (r, q, x, y, MPFR_RNDN);
219   MPFR_ASSERTN (mpfr_cmp_si (r, 0) == 0);
220   MPFR_ASSERTN (q[0] % 1073741824L == 0L);
221
222   /* another large quotient */
223   mpfr_set_prec (x, 65);
224   mpfr_set_prec (y, 65);
225   mpfr_const_pi (x, MPFR_RNDN);
226   mpfr_mul_2exp (x, x, 63, MPFR_RNDN);
227   mpfr_const_log2 (y, MPFR_RNDN);
228   mpfr_set_prec (r, 10);
229   mpfr_remquo (r, q, x, y, MPFR_RNDN);
230   /* q should be 41803643793084085130, r should be 605/2048 */
231   MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 605, -11) == 0);
232   MPFR_ASSERTN ((q[0] > 0) && ((q[0] % 1073741824L) == 733836170L));
233
234   /* check cases where quotient is 1.5 +/- eps */
235   mpfr_set_prec (x, 65);
236   mpfr_set_prec (y, 65);
237   mpfr_set_prec (r, 63);
238   mpfr_set_ui (x, 3, MPFR_RNDN);
239   mpfr_set_ui (y, 2, MPFR_RNDN);
240   mpfr_remquo (r, q, x, y, MPFR_RNDN);
241   /* x/y = 1.5, quotient should be 2 (even rule), remainder should be -1 */
242   MPFR_ASSERTN (mpfr_cmp_si (r, -1) == 0);
243   MPFR_ASSERTN (q[0] == 2L);
244   mpfr_set_ui (x, 3, MPFR_RNDN);
245   mpfr_nextabove (x); /* 3 + 2^(-63) */
246   mpfr_set_ui (y, 2, MPFR_RNDN);
247   mpfr_remquo (r, q, x, y, MPFR_RNDN);
248   /* x/y = 1.5 + 2^(-64), quo should be 2, r should be -1 + 2^(-63) */
249   MPFR_ASSERTN (mpfr_add_ui (r, r, 1, MPFR_RNDN) == 0);
250   MPFR_ASSERTN (mpfr_cmp_ui_2exp (r, 1, -63) == 0);
251   MPFR_ASSERTN (q[0] == 2L);
252   mpfr_set_ui (x, 3, MPFR_RNDN);
253   mpfr_set_ui (y, 2, MPFR_RNDN);
254   mpfr_nextabove (y); /* 2 + 2^(-63) */
255   mpfr_remquo (r, q, x, y, MPFR_RNDN);
256   /* x/y = 1.5 - eps, quo should be 1, r should be 1 - 2^(-63) */
257   MPFR_ASSERTN (mpfr_sub_ui (r, r, 1, MPFR_RNDN) == 0);
258   MPFR_ASSERTN (mpfr_cmp_si_2exp (r, -1, -63) == 0);
259   MPFR_ASSERTN (q[0] == 1L);
260
261   /* bug founds by Kaveh Ghazi, 3 May 2007 */
262   mpfr_set_ui (x, 2, MPFR_RNDN);
263   mpfr_set_ui (y, 3, MPFR_RNDN);
264   mpfr_remainder (r, x, y, MPFR_RNDN);
265   MPFR_ASSERTN (mpfr_cmp_si (r, -1) == 0);
266
267   mpfr_set_si (x, -1, MPFR_RNDN);
268   mpfr_set_ui (y, 1, MPFR_RNDN);
269   mpfr_remainder (r, x, y, MPFR_RNDN);
270   MPFR_ASSERTN (mpfr_cmp_si (r, 0) == 0 && MPFR_SIGN (r) < 0);
271
272   /* check argument reuse */
273   mpfr_set_si (x, -1, MPFR_RNDN);
274   mpfr_set_ui (y, 1, MPFR_RNDN);
275   mpfr_remainder (x, x, y, MPFR_RNDN);
276   MPFR_ASSERTN (mpfr_cmp_si (x, 0) == 0 && MPFR_SIGN (x) < 0);
277
278   mpfr_set_ui_2exp (x, 1, mpfr_get_emax () - 1, MPFR_RNDN);
279   mpfr_set_ui_2exp (y, 1, mpfr_get_emin (), MPFR_RNDN);
280   mpfr_remquo (r, q, x, y, MPFR_RNDN);
281   MPFR_ASSERTN (mpfr_zero_p (r) && MPFR_SIGN (r) > 0);
282   MPFR_ASSERTN (q[0] == 0);
283
284   mpfr_clear (x);
285   mpfr_clear (y);
286   mpfr_clear (r);
287
288   tests_end_mpfr ();
289
290   return 0;
291 }