xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tstckintc.c (revision cef8759bd76c1b621f8eab8faa6f208faabc2e15)
1 /* Test file for mpfr_custom_*
2 
3 Copyright 2005-2018 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramba 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 "mpfr-test.h"
24 
25 #define BUFFER_SIZE 250
26 #define PREC_TESTED 200
27 
28 long Buffer[BUFFER_SIZE];
29 char *stack = (char *) Buffer;
30 long *org = (long *) Buffer;
31 mpfr_prec_t p = PREC_TESTED;
32 
33 #define ALIGNED(s) (((s) + sizeof (long) - 1) / sizeof (long) * sizeof (long))
34 
35 static void *
36 new_st (size_t s)
37 {
38   void *p = (void *) stack;
39 
40   if (MPFR_UNLIKELY (s > (char *) &Buffer[BUFFER_SIZE] - stack))
41     {
42       printf ("[INTERNAL TEST ERROR] Stack overflow.\n");
43       exit (1);
44     }
45   stack += ALIGNED (s);
46   return p;
47 }
48 
49 static void
50 reset_stack (void)
51 {
52   stack = (char *) Buffer;
53 }
54 
55 /*************************************************************************/
56 
57  /* Alloc a new mpfr_t on the main stack */
58 static mpfr_ptr
59 new_mpfr (mpfr_prec_t p)
60 {
61   mpfr_ptr x = (mpfr_ptr) new_st (sizeof (mpfr_t));
62   void *mantissa = new_st (mpfr_custom_get_size (p));
63   mpfr_custom_init (mantissa, p);
64   mpfr_custom_init_set (x, 0, 0, p, mantissa);
65   return x;
66 }
67 
68  /* Alloc a new mpfr_t on the main stack */
69 static mpfr_ptr
70 new_nan (mpfr_prec_t p)
71 {
72   mpfr_ptr x = (mpfr_ptr) new_st (sizeof (mpfr_t));
73   void *mantissa = new_st ((mpfr_custom_get_size) (p));
74   (mpfr_custom_init) (mantissa, p);
75   (mpfr_custom_init_set) (x, MPFR_NAN_KIND, 0, p, mantissa);
76   return x;
77 }
78 
79  /* Alloc a new mpfr_t on the main stack */
80 static mpfr_ptr
81 new_inf (mpfr_prec_t p)
82 {
83   mpfr_ptr x = (mpfr_ptr) new_st (sizeof (mpfr_t));
84   void *mantissa = new_st ((mpfr_custom_get_size) (p));
85   (mpfr_custom_init) (mantissa, p);
86   (mpfr_custom_init_set) (x, -MPFR_INF_KIND, 0, p, mantissa);
87   return x;
88 }
89 
90  /* Garbage the stack by keeping only x and save it in old_stack */
91 static mpfr_ptr
92 return_mpfr (mpfr_ptr x, char *old_stack)
93 {
94   void *mantissa       = mpfr_custom_get_significand (x);
95   size_t size_mantissa = mpfr_custom_get_size (mpfr_get_prec (x));
96   mpfr_ptr newx;
97 
98   memmove (old_stack, x, sizeof (mpfr_t));
99   memmove (old_stack + ALIGNED (sizeof (mpfr_t)), mantissa, size_mantissa);
100   newx = (mpfr_ptr) old_stack;
101   mpfr_custom_move (newx, old_stack + ALIGNED (sizeof (mpfr_t)));
102   stack = old_stack + ALIGNED (sizeof (mpfr_t)) + ALIGNED (size_mantissa);
103   return newx;
104 }
105 
106  /* Garbage the stack by keeping only x and save it in old_stack */
107 static mpfr_ptr
108 return_mpfr_func (mpfr_ptr x, char *old_stack)
109 {
110   void *mantissa       = (mpfr_custom_get_significand) (x);
111   size_t size_mantissa = (mpfr_custom_get_size) (mpfr_get_prec (x));
112   mpfr_ptr newx;
113 
114   memmove (old_stack, x, sizeof (mpfr_t));
115   memmove (old_stack + ALIGNED (sizeof (mpfr_t)), mantissa, size_mantissa);
116   newx = (mpfr_ptr) old_stack;
117   (mpfr_custom_move) (newx, old_stack + ALIGNED (sizeof (mpfr_t)));
118   stack = old_stack + ALIGNED (sizeof (mpfr_t)) + ALIGNED (size_mantissa);
119   return newx;
120 }
121 
122 /*************************************************************************/
123 
124 static void
125 test1 (void)
126 {
127   mpfr_ptr x, y;
128 
129   reset_stack ();
130   org = (long *) stack;
131 
132   x = new_mpfr (p);
133   y = new_mpfr (p);
134   mpfr_set_ui (x, 42, MPFR_RNDN);
135   mpfr_set_ui (y, 17, MPFR_RNDN);
136   mpfr_add (y, x, y, MPFR_RNDN);
137   y = return_mpfr (y, (char *) org);
138   if ((long *) y != org || mpfr_cmp_ui (y, 59) != 0)
139     {
140       printf ("Compact (1) failed!\n");
141       exit (1);
142     }
143 
144   x = new_mpfr (p);
145   y = new_mpfr (p);
146   mpfr_set_ui (x, 4217, MPFR_RNDN);
147   mpfr_set_ui (y, 1742, MPFR_RNDN);
148   mpfr_add (y, x, y, MPFR_RNDN);
149   y = return_mpfr_func (y, (char *) org);
150   if ((long *) y != org || mpfr_cmp_ui (y, 5959) != 0)
151     {
152       printf ("Compact (5) failed!\n");
153       exit (1);
154     }
155 
156   reset_stack ();
157 }
158 
159 static void
160 test_nan_inf_zero (void)
161 {
162   mpfr_ptr val;
163   int sign;
164   int kind;
165 
166   reset_stack ();
167 
168   val = new_mpfr (MPFR_PREC_MIN);
169   mpfr_set_nan (val);
170   kind = (mpfr_custom_get_kind) (val);
171   if (kind != MPFR_NAN_KIND)
172     {
173       printf ("mpfr_custom_get_kind error: ");
174       mpfr_dump (val);
175       printf (" is kind %d instead of %d\n", kind, (int) MPFR_NAN_KIND);
176       exit (1);
177     }
178 
179   val = new_nan (MPFR_PREC_MIN);
180   if (!mpfr_nan_p(val))
181     {
182       printf ("Error: mpfr_custom_init_set doesn't set NAN mpfr.\n");
183       exit (1);
184     }
185 
186   val = new_inf (MPFR_PREC_MIN);
187   if (!mpfr_inf_p(val) || mpfr_sgn(val) >= 0)
188     {
189       printf ("Error: mpfr_custom_init_set doesn't set -INF mpfr.\n");
190       exit (1);
191     }
192 
193   sign = 1;
194   mpfr_set_inf (val, sign);
195   kind = (mpfr_custom_get_kind) (val);
196   if ((ABS (kind) != MPFR_INF_KIND) || (VSIGN (kind) != VSIGN (sign)))
197     {
198       printf ("mpfr_custom_get_kind error: ");
199       mpfr_dump (val);
200       printf (" is kind %d instead of %d\n", kind, (int) MPFR_INF_KIND);
201       printf (" have sign %d instead of %d\n", VSIGN (kind), VSIGN (sign));
202       exit (1);
203     }
204 
205   sign = -1;
206   mpfr_set_zero (val, sign);
207   kind = (mpfr_custom_get_kind) (val);
208   if ((ABS (kind) != MPFR_ZERO_KIND) || (VSIGN (kind) != VSIGN (sign)))
209     {
210       printf ("mpfr_custom_get_kind error: ");
211       mpfr_dump (val);
212       printf (" is kind %d instead of %d\n", kind, (int) MPFR_ZERO_KIND);
213       printf (" have sign %d instead of %d\n", VSIGN (kind), VSIGN (sign));
214       exit (1);
215     }
216 
217   reset_stack ();
218 }
219 
220 /*************************************************************************/
221 
222 /* We build the MPFR variable each time it is needed */
223 /* a[0] is the kind, a[1] is the exponent, &a[2] is the mantissa */
224 static long *
225 dummy_new (void)
226 {
227   long *r;
228 
229   r = (long *) new_st (ALIGNED (2 * sizeof (long)) +
230                        ALIGNED (mpfr_custom_get_size (p)));
231   (mpfr_custom_init) (&r[2], p);
232   r[0] = (int) MPFR_NAN_KIND;
233   r[1] = 0;
234   return r;
235 }
236 
237 static long *
238 dummy_set_si (long si)
239 {
240   mpfr_t x;
241   long * r = dummy_new ();
242   (mpfr_custom_init_set) (x, MPFR_REGULAR_KIND, 0, p, &r[2]);
243   mpfr_set_si (x, si, MPFR_RNDN);
244   r[0] = mpfr_custom_get_kind (x);
245   r[1] = mpfr_custom_get_exp (x);
246   return r;
247 }
248 
249 static long *
250 dummy_add (long *a, long *b)
251 {
252   mpfr_t x, y, z;
253   long *r = dummy_new ();
254   mpfr_custom_init_set (x, 0 + MPFR_REGULAR_KIND, 0, p, &r[2]);
255   (mpfr_custom_init_set) (y, a[0], a[1], p, &a[2]);
256   mpfr_custom_init_set (z, 0 + b[0], b[1], p, &b[2]);
257   mpfr_add (x, y, z, MPFR_RNDN);
258   r[0] = (mpfr_custom_get_kind) (x);
259   r[1] = (mpfr_custom_get_exp) (x);
260   return r;
261 }
262 
263 static long *
264 dummy_compact (long *r, long *org_stack)
265 {
266   memmove (org_stack, r,
267            ALIGNED (2*sizeof (long)) + ALIGNED ((mpfr_custom_get_size) (p)));
268   return org_stack;
269 }
270 
271 /*************************************************************************/
272 
273 static void
274 test2 (void)
275 {
276   mpfr_t x;
277   long *a, *b, *c;
278 
279   reset_stack ();
280   org = (long *) stack;
281 
282   a = dummy_set_si (42);
283   b = dummy_set_si (17);
284   c = dummy_add (a, b);
285   c = dummy_compact (c, org);
286   (mpfr_custom_init_set) (x, c[0], c[1], p, &c[2]);
287   if (c != org || mpfr_cmp_ui (x, 59) != 0)
288     {
289       printf ("Compact (2) failed! c=%p a=%p\n", (void *) c, (void *) a);
290       mpfr_dump (x);
291       exit (1);
292     }
293 
294   a = dummy_set_si (42);
295   b = dummy_set_si (-17);
296   c = dummy_add (a, b);
297   c = dummy_compact (c, org);
298   (mpfr_custom_init_set) (x, c[0], c[1], p, &c[2]);
299   if (c != org || mpfr_cmp_ui (x, 25) != 0)
300     {
301       printf ("Compact (6) failed! c=%p a=%p\n", (void *) c, (void *) a);
302       mpfr_dump (x);
303       exit (1);
304     }
305 
306   reset_stack ();
307 }
308 
309 
310 int
311 main (void)
312 {
313   tests_start_mpfr ();
314   /* We test iff long = mp_limb_t */
315   if (sizeof (long) == sizeof (mp_limb_t))
316     {
317       test1 ();
318       test2 ();
319       test_nan_inf_zero ();
320     }
321   tests_end_mpfr ();
322   return 0;
323 }
324