tui_sub.c revision 1.1.1.6 1 1.1 mrg /* Test file for mpfr_ui_sub.
2 1.1 mrg
3 1.1.1.6 mrg Copyright 2000-2023 Free Software Foundation, Inc.
4 1.1.1.3 mrg Contributed by the AriC and Caramba projects, INRIA.
5 1.1 mrg
6 1.1 mrg This file is part of the GNU MPFR Library.
7 1.1 mrg
8 1.1 mrg The GNU MPFR Library is free software; you can redistribute it and/or modify
9 1.1 mrg it under the terms of the GNU Lesser General Public License as published by
10 1.1 mrg the Free Software Foundation; either version 3 of the License, or (at your
11 1.1 mrg option) any later version.
12 1.1 mrg
13 1.1 mrg The GNU MPFR Library is distributed in the hope that it will be useful, but
14 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 1.1 mrg License for more details.
17 1.1 mrg
18 1.1 mrg You should have received a copy of the GNU Lesser General Public License
19 1.1 mrg along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
20 1.1.1.5 mrg https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 1.1 mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22 1.1 mrg
23 1.1 mrg #include <float.h>
24 1.1 mrg
25 1.1 mrg #include "mpfr-test.h"
26 1.1 mrg
27 1.1 mrg static void
28 1.1 mrg special (void)
29 1.1 mrg {
30 1.1 mrg mpfr_t x, y, res;
31 1.1 mrg int inexact;
32 1.1 mrg
33 1.1 mrg mpfr_init (x);
34 1.1 mrg mpfr_init (y);
35 1.1 mrg mpfr_init (res);
36 1.1 mrg
37 1.1 mrg mpfr_set_prec (x, 24);
38 1.1 mrg mpfr_set_prec (y, 24);
39 1.1 mrg mpfr_set_str_binary (y, "0.111100110001011010111");
40 1.1 mrg inexact = mpfr_ui_sub (x, 1, y, MPFR_RNDN);
41 1.1 mrg if (inexact)
42 1.1 mrg {
43 1.1 mrg printf ("Wrong inexact flag: got %d, expected 0\n", inexact);
44 1.1 mrg exit (1);
45 1.1 mrg }
46 1.1 mrg
47 1.1 mrg mpfr_set_prec (x, 24);
48 1.1 mrg mpfr_set_prec (y, 24);
49 1.1 mrg mpfr_set_str_binary (y, "0.111100110001011010111");
50 1.1 mrg if ((inexact = mpfr_ui_sub (x, 38181761, y, MPFR_RNDN)) >= 0)
51 1.1 mrg {
52 1.1 mrg printf ("Wrong inexact flag: got %d, expected -1\n", inexact);
53 1.1 mrg exit (1);
54 1.1 mrg }
55 1.1 mrg
56 1.1 mrg mpfr_set_prec (x, 63);
57 1.1 mrg mpfr_set_prec (y, 63);
58 1.1 mrg mpfr_set_str_binary (y, "0.111110010010100100110101101010001001100101110001000101110111111E-1");
59 1.1 mrg if ((inexact = mpfr_ui_sub (x, 1541116494, y, MPFR_RNDN)) <= 0)
60 1.1 mrg {
61 1.1 mrg printf ("Wrong inexact flag: got %d, expected +1\n", inexact);
62 1.1 mrg exit (1);
63 1.1 mrg }
64 1.1 mrg
65 1.1 mrg mpfr_set_prec (x, 32);
66 1.1 mrg mpfr_set_prec (y, 32);
67 1.1 mrg mpfr_set_str_binary (y, "0.11011000110111010001011100011100E-1");
68 1.1 mrg if ((inexact = mpfr_ui_sub (x, 2000375416, y, MPFR_RNDN)) >= 0)
69 1.1 mrg {
70 1.1 mrg printf ("Wrong inexact flag: got %d, expected -1\n", inexact);
71 1.1 mrg exit (1);
72 1.1 mrg }
73 1.1 mrg
74 1.1 mrg mpfr_set_prec (x, 24);
75 1.1 mrg mpfr_set_prec (y, 24);
76 1.1 mrg mpfr_set_str_binary (y, "0.110011011001010011110111E-2");
77 1.1 mrg if ((inexact = mpfr_ui_sub (x, 927694848, y, MPFR_RNDN)) <= 0)
78 1.1 mrg {
79 1.1 mrg printf ("Wrong inexact flag: got %d, expected +1\n", inexact);
80 1.1 mrg exit (1);
81 1.1 mrg }
82 1.1 mrg
83 1.1 mrg /* bug found by Mathieu Dutour, 12 Apr 2001 */
84 1.1 mrg mpfr_set_prec (x, 5);
85 1.1 mrg mpfr_set_prec (y, 5);
86 1.1 mrg mpfr_set_prec (res, 5);
87 1.1 mrg mpfr_set_str_binary (x, "1e-12");
88 1.1 mrg
89 1.1 mrg mpfr_ui_sub (y, 1, x, MPFR_RNDD);
90 1.1 mrg mpfr_set_str_binary (res, "0.11111");
91 1.1 mrg if (mpfr_cmp (y, res))
92 1.1 mrg {
93 1.1 mrg printf ("Error in mpfr_ui_sub (y, 1, x, MPFR_RNDD) for x=2^(-12)\nexpected 1.1111e-1, got ");
94 1.1 mrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
95 1.1 mrg printf ("\n");
96 1.1 mrg exit (1);
97 1.1 mrg }
98 1.1 mrg
99 1.1 mrg mpfr_ui_sub (y, 1, x, MPFR_RNDU);
100 1.1 mrg mpfr_set_str_binary (res, "1.0");
101 1.1 mrg if (mpfr_cmp (y, res))
102 1.1 mrg {
103 1.1 mrg printf ("Error in mpfr_ui_sub (y, 1, x, MPFR_RNDU) for x=2^(-12)\n"
104 1.1 mrg "expected 1.0, got ");
105 1.1 mrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
106 1.1 mrg printf ("\n");
107 1.1 mrg exit (1);
108 1.1 mrg }
109 1.1 mrg
110 1.1 mrg mpfr_ui_sub (y, 1, x, MPFR_RNDN);
111 1.1 mrg mpfr_set_str_binary (res, "1.0");
112 1.1 mrg if (mpfr_cmp (y, res))
113 1.1 mrg {
114 1.1 mrg printf ("Error in mpfr_ui_sub (y, 1, x, MPFR_RNDN) for x=2^(-12)\n"
115 1.1 mrg "expected 1.0, got ");
116 1.1 mrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
117 1.1 mrg printf ("\n");
118 1.1 mrg exit (1);
119 1.1 mrg }
120 1.1 mrg
121 1.1 mrg mpfr_set_prec (x, 10);
122 1.1 mrg mpfr_set_prec (y, 10);
123 1.1 mrg mpfr_urandomb (x, RANDS);
124 1.1 mrg mpfr_ui_sub (y, 0, x, MPFR_RNDN);
125 1.1 mrg if (MPFR_IS_ZERO(x))
126 1.1 mrg MPFR_ASSERTN(MPFR_IS_ZERO(y));
127 1.1 mrg else
128 1.1 mrg MPFR_ASSERTN(mpfr_cmpabs (x, y) == 0 && mpfr_sgn (x) != mpfr_sgn (y));
129 1.1 mrg
130 1.1 mrg mpfr_set_prec (x, 73);
131 1.1 mrg mpfr_set_str_binary (x, "0.1101111010101011011011100011010000000101110001011111001011011000101111101E-99");
132 1.1 mrg mpfr_ui_sub (x, 1, x, MPFR_RNDZ);
133 1.1 mrg mpfr_nextabove (x);
134 1.1 mrg MPFR_ASSERTN(mpfr_cmp_ui (x, 1) == 0);
135 1.1 mrg
136 1.1 mrg mpfr_clear (x);
137 1.1 mrg mpfr_clear (y);
138 1.1 mrg mpfr_clear (res);
139 1.1 mrg }
140 1.1 mrg
141 1.1 mrg /* checks that (y-x) gives the right results with 53 bits of precision */
142 1.1 mrg static void
143 1.1 mrg check (unsigned long y, const char *xs, mpfr_rnd_t rnd_mode, const char *zs)
144 1.1 mrg {
145 1.1 mrg mpfr_t xx, zz;
146 1.1 mrg
147 1.1 mrg mpfr_inits2 (53, xx, zz, (mpfr_ptr) 0);
148 1.1 mrg mpfr_set_str1 (xx, xs);
149 1.1 mrg mpfr_ui_sub (zz, y, xx, rnd_mode);
150 1.1 mrg if (mpfr_cmp_str1 (zz, zs) )
151 1.1 mrg {
152 1.1 mrg printf ("expected difference is %s, got\n",zs);
153 1.1 mrg mpfr_out_str(stdout, 10, 0, zz, MPFR_RNDN);
154 1.1 mrg printf ("mpfr_ui_sub failed for y=%lu x=%s with rnd_mode=%s\n",
155 1.1 mrg y, xs, mpfr_print_rnd_mode (rnd_mode));
156 1.1 mrg exit (1);
157 1.1 mrg }
158 1.1 mrg mpfr_clears (xx, zz, (mpfr_ptr) 0);
159 1.1 mrg }
160 1.1 mrg
161 1.1 mrg /* if u = o(x-y), v = o(u-x), w = o(v+y), then x-y = u-w */
162 1.1 mrg static void
163 1.1 mrg check_two_sum (mpfr_prec_t p)
164 1.1 mrg {
165 1.1 mrg unsigned int x;
166 1.1 mrg mpfr_t y, u, v, w;
167 1.1 mrg mpfr_rnd_t rnd;
168 1.1.1.3 mrg int inexact, cmp;
169 1.1 mrg
170 1.1 mrg mpfr_inits2 (p, y, u, v, w, (mpfr_ptr) 0);
171 1.1 mrg do
172 1.1 mrg {
173 1.1 mrg x = randlimb ();
174 1.1 mrg }
175 1.1 mrg while (x < 1);
176 1.1 mrg mpfr_urandomb (y, RANDS);
177 1.1 mrg rnd = MPFR_RNDN;
178 1.1 mrg inexact = mpfr_ui_sub (u, x, y, rnd);
179 1.1 mrg mpfr_sub_ui (v, u, x, rnd);
180 1.1 mrg mpfr_add (w, v, y, rnd);
181 1.1.1.3 mrg cmp = mpfr_cmp_ui (w, 0);
182 1.1 mrg /* as u = (x-y) + w, we should have inexact and w of same sign */
183 1.1.1.3 mrg if (! SAME_SIGN (inexact, cmp))
184 1.1 mrg {
185 1.1 mrg printf ("Wrong inexact flag for prec=%u, rnd=%s\n",
186 1.1 mrg (unsigned int) p, mpfr_print_rnd_mode (rnd));
187 1.1.1.3 mrg printf ("x = %u\n", x);
188 1.1.1.3 mrg printf ("y = "); mpfr_dump (y);
189 1.1.1.3 mrg printf ("u = "); mpfr_dump (u);
190 1.1.1.3 mrg printf ("v = "); mpfr_dump (v);
191 1.1.1.3 mrg printf ("w = "); mpfr_dump (w);
192 1.1 mrg printf ("inexact = %d\n", inexact);
193 1.1 mrg exit (1);
194 1.1 mrg }
195 1.1 mrg mpfr_clears (y, u, v, w, (mpfr_ptr) 0);
196 1.1 mrg }
197 1.1 mrg
198 1.1 mrg static void
199 1.1 mrg check_nans (void)
200 1.1 mrg {
201 1.1 mrg mpfr_t x, y;
202 1.1 mrg
203 1.1 mrg mpfr_init2 (x, 123L);
204 1.1 mrg mpfr_init2 (y, 123L);
205 1.1 mrg
206 1.1 mrg /* 1 - nan == nan */
207 1.1 mrg mpfr_set_nan (x);
208 1.1 mrg mpfr_ui_sub (y, 1L, x, MPFR_RNDN);
209 1.1 mrg MPFR_ASSERTN (mpfr_nan_p (y));
210 1.1 mrg
211 1.1 mrg /* 1 - +inf == -inf */
212 1.1 mrg mpfr_set_inf (x, 1);
213 1.1 mrg mpfr_ui_sub (y, 1L, x, MPFR_RNDN);
214 1.1 mrg MPFR_ASSERTN (mpfr_inf_p (y));
215 1.1 mrg MPFR_ASSERTN (mpfr_sgn (y) < 0);
216 1.1 mrg
217 1.1 mrg /* 1 - -inf == +inf */
218 1.1 mrg mpfr_set_inf (x, -1);
219 1.1 mrg mpfr_ui_sub (y, 1L, x, MPFR_RNDN);
220 1.1 mrg MPFR_ASSERTN (mpfr_inf_p (y));
221 1.1 mrg MPFR_ASSERTN (mpfr_sgn (y) > 0);
222 1.1 mrg
223 1.1 mrg mpfr_clear (x);
224 1.1 mrg mpfr_clear (y);
225 1.1 mrg }
226 1.1 mrg
227 1.1 mrg /* Check mpfr_ui_sub with u = 0 (unsigned). */
228 1.1 mrg static void check_neg (void)
229 1.1 mrg {
230 1.1 mrg mpfr_t x, yneg, ysub;
231 1.1 mrg int i, s;
232 1.1 mrg int r;
233 1.1 mrg
234 1.1 mrg mpfr_init2 (x, 64);
235 1.1 mrg mpfr_init2 (yneg, 32);
236 1.1 mrg mpfr_init2 (ysub, 32);
237 1.1 mrg
238 1.1 mrg for (i = 0; i <= 25; i++)
239 1.1 mrg {
240 1.1 mrg mpfr_sqrt_ui (x, i, MPFR_RNDN);
241 1.1 mrg for (s = 0; s <= 1; s++)
242 1.1 mrg {
243 1.1 mrg RND_LOOP (r)
244 1.1 mrg {
245 1.1 mrg int tneg, tsub;
246 1.1 mrg
247 1.1 mrg tneg = mpfr_neg (yneg, x, (mpfr_rnd_t) r);
248 1.1 mrg tsub = mpfr_ui_sub (ysub, 0, x, (mpfr_rnd_t) r);
249 1.1 mrg MPFR_ASSERTN (mpfr_equal_p (yneg, ysub));
250 1.1 mrg MPFR_ASSERTN (!(MPFR_IS_POS (yneg) ^ MPFR_IS_POS (ysub)));
251 1.1 mrg MPFR_ASSERTN (tneg == tsub);
252 1.1 mrg }
253 1.1 mrg mpfr_neg (x, x, MPFR_RNDN);
254 1.1 mrg }
255 1.1 mrg }
256 1.1 mrg
257 1.1 mrg mpfr_clear (x);
258 1.1 mrg mpfr_clear (yneg);
259 1.1 mrg mpfr_clear (ysub);
260 1.1 mrg }
261 1.1 mrg
262 1.1.1.3 mrg static void
263 1.1.1.3 mrg check_overflow (void)
264 1.1.1.3 mrg {
265 1.1.1.3 mrg mpfr_exp_t emin, emax;
266 1.1.1.3 mrg mpfr_t x, y1, y2;
267 1.1.1.3 mrg int inex1, inex2, rnd_mode;
268 1.1.1.4 mrg mpfr_flags_t flags1, flags2;
269 1.1.1.3 mrg
270 1.1.1.3 mrg emin = mpfr_get_emin ();
271 1.1.1.3 mrg emax = mpfr_get_emax ();
272 1.1.1.3 mrg set_emin (MPFR_EMIN_MIN);
273 1.1.1.3 mrg set_emax (MPFR_EMAX_MAX);
274 1.1.1.3 mrg
275 1.1.1.3 mrg mpfr_inits2 (32, x, y1, y2, (mpfr_ptr) 0);
276 1.1.1.3 mrg mpfr_setmax (x, MPFR_EMAX_MAX);
277 1.1.1.3 mrg mpfr_neg (x, x, MPFR_RNDN);
278 1.1.1.4 mrg RND_LOOP_NO_RNDF (rnd_mode)
279 1.1.1.4 mrg {
280 1.1.1.4 mrg if (rnd_mode == MPFR_RNDU || rnd_mode == MPFR_RNDA)
281 1.1.1.4 mrg {
282 1.1.1.4 mrg inex1 = mpfr_overflow (y1, (mpfr_rnd_t) rnd_mode, 1);
283 1.1.1.4 mrg flags1 = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT;
284 1.1.1.4 mrg }
285 1.1.1.4 mrg else
286 1.1.1.4 mrg {
287 1.1.1.4 mrg mpfr_neg (y1, x, MPFR_RNDN);
288 1.1.1.4 mrg inex1 = -1;
289 1.1.1.4 mrg flags1 = MPFR_FLAGS_INEXACT;
290 1.1.1.4 mrg }
291 1.1.1.4 mrg mpfr_clear_flags ();
292 1.1.1.4 mrg inex2 = mpfr_ui_sub (y2, 1, x, (mpfr_rnd_t) rnd_mode);
293 1.1.1.4 mrg flags2 = __gmpfr_flags;
294 1.1.1.4 mrg if (!(mpfr_equal_p (y1, y2) &&
295 1.1.1.4 mrg SAME_SIGN (inex1, inex2) &&
296 1.1.1.4 mrg flags1 == flags2))
297 1.1.1.4 mrg {
298 1.1.1.4 mrg printf ("Error in check_overflow for %s\n",
299 1.1.1.4 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) rnd_mode));
300 1.1.1.4 mrg printf ("Expected ");
301 1.1.1.4 mrg mpfr_dump (y1);
302 1.1.1.4 mrg printf (" with inex = %d, flags =", inex1);
303 1.1.1.4 mrg flags_out (flags1);
304 1.1.1.4 mrg printf ("Got ");
305 1.1.1.4 mrg mpfr_dump (y2);
306 1.1.1.4 mrg printf (" with inex = %d, flags =", inex2);
307 1.1.1.4 mrg flags_out (flags2);
308 1.1.1.4 mrg exit (1);
309 1.1.1.4 mrg }
310 1.1.1.4 mrg }
311 1.1.1.3 mrg mpfr_clears (x, y1, y2, (mpfr_ptr) 0);
312 1.1.1.3 mrg
313 1.1.1.3 mrg set_emin (emin);
314 1.1.1.3 mrg set_emax (emax);
315 1.1.1.3 mrg }
316 1.1.1.3 mrg
317 1.1.1.3 mrg #define TEST_FUNCTION mpfr_ui_sub
318 1.1.1.3 mrg #define ULONG_ARG1
319 1.1.1.3 mrg #include "tgeneric.c"
320 1.1.1.3 mrg
321 1.1 mrg int
322 1.1 mrg main (int argc, char *argv[])
323 1.1 mrg {
324 1.1 mrg mpfr_prec_t p;
325 1.1 mrg unsigned k;
326 1.1 mrg
327 1.1 mrg tests_start_mpfr ();
328 1.1 mrg
329 1.1 mrg check_nans ();
330 1.1 mrg
331 1.1 mrg special ();
332 1.1 mrg for (p=2; p<100; p++)
333 1.1 mrg for (k=0; k<100; k++)
334 1.1 mrg check_two_sum (p);
335 1.1 mrg
336 1.1 mrg check(1196426492, "1.4218093058435347e-3", MPFR_RNDN,
337 1.1 mrg "1.1964264919985781e9");
338 1.1 mrg check(1092583421, "-1.0880649218158844e9", MPFR_RNDN,
339 1.1 mrg "2.1806483428158845901e9");
340 1.1 mrg check(948002822, "1.22191250737771397120e+20", MPFR_RNDN,
341 1.1 mrg "-1.2219125073682338611e20");
342 1.1 mrg check(832100416, "4.68311314939691330000e-215", MPFR_RNDD,
343 1.1 mrg "8.3210041599999988079e8");
344 1.1 mrg check(1976245324, "1.25296395864546893357e+232", MPFR_RNDZ,
345 1.1 mrg "-1.2529639586454686577e232");
346 1.1 mrg check(2128997392, "-1.08496826129284207724e+187", MPFR_RNDU,
347 1.1 mrg "1.0849682612928422704e187");
348 1.1 mrg check(293607738, "-1.9967571564050541e-5", MPFR_RNDU,
349 1.1 mrg "2.9360773800002003e8");
350 1.1 mrg check(354270183, "2.9469161763489528e3", MPFR_RNDN,
351 1.1 mrg "3.5426723608382362e8");
352 1.1.1.3 mrg check_overflow ();
353 1.1 mrg
354 1.1 mrg check_neg ();
355 1.1 mrg
356 1.1.1.4 mrg test_generic (MPFR_PREC_MIN, 1000, 100);
357 1.1.1.3 mrg
358 1.1 mrg tests_end_mpfr ();
359 1.1 mrg return 0;
360 1.1 mrg }
361