xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tstckintc.c (revision 479d8f7d843cc1b22d497efdf1f27a50ee8418d4)
1 /* Test file for mpfr_custom_*
2 
3 Copyright 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 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 <stdlib.h>
24 
25 #include "mpfr-test.h"
26 
27 #define BUFFER_SIZE 250
28 #define PREC_TESTED 200
29 
30 long Buffer[BUFFER_SIZE];
31 char *stack = (char *) Buffer;
32 mpfr_prec_t p = PREC_TESTED;
33 
34 #define ALIGNED(s) (((s) + sizeof (long) - 1) / sizeof (long) * sizeof (long))
35 
36 static void *
37 new_st (size_t s)
38 {
39   void *p = (void *) stack;
40   stack += ALIGNED (s);
41   if (MPFR_UNLIKELY (stack > (char *) &Buffer[BUFFER_SIZE]))
42     {
43       printf ("Stack overflow.\n");
44       exit (1);
45     }
46   return p;
47 }
48 
49  /* Alloc a new mpfr_t on the main stack */
50 static mpfr_ptr
51 new_mpfr (mpfr_prec_t p)
52 {
53   mpfr_ptr x = (mpfr_ptr) new_st (sizeof (mpfr_t));
54   void *mantissa = new_st (mpfr_custom_get_size (p));
55   mpfr_custom_init (mantissa, p);
56   mpfr_custom_init_set (x, 0, 0, p, mantissa);
57   return x;
58 }
59 
60  /* Garbage the stack by keeping only x  */
61 static mpfr_ptr
62 return_mpfr (mpfr_ptr x, char *old_stack)
63 {
64   void *mantissa       = mpfr_custom_get_significand (x);
65   size_t size_mantissa = mpfr_custom_get_size (mpfr_get_prec (x));
66   mpfr_ptr newx;
67 
68   memmove (old_stack, x, sizeof (mpfr_t));
69   memmove (old_stack + ALIGNED (sizeof (mpfr_t)), mantissa, size_mantissa);
70   newx = (mpfr_ptr) old_stack;
71   mpfr_custom_move (newx, old_stack + ALIGNED (sizeof (mpfr_t)));
72   stack = old_stack + ALIGNED (sizeof (mpfr_t)) + ALIGNED (size_mantissa);
73   return newx;
74 }
75 
76 static void
77 test1 (void)
78 {
79   mpfr_ptr x, y;
80   char *org;
81 
82   org = stack;
83   x = new_mpfr (p);
84   y = new_mpfr (p);
85   mpfr_set_ui (x, 42, MPFR_RNDN);
86   mpfr_set_ui (y, 17, MPFR_RNDN);
87   mpfr_add (y, x, y, MPFR_RNDN);
88   y = return_mpfr (y, org);
89   if (y != x || mpfr_cmp_ui (y, 59) != 0)
90     {
91       printf ("Compact (1) failed!\n");
92       exit (1);
93     }
94   stack = org;
95 }
96 
97 /* We build the MPFR variable each time it is needed */
98 /* a[0] is the kind, a[1] is the exponent, &a[2] is the mantissa */
99 static long *
100 dummy_new (void)
101 {
102   long *r;
103 
104   r = (long *) new_st (ALIGNED (2 * sizeof (long)) +
105                        ALIGNED (mpfr_custom_get_size (p)));
106   MPFR_ASSERTN (r != NULL);
107   (mpfr_custom_init) (&r[2], p);
108   r[0] = (int) MPFR_NAN_KIND;
109   r[1] = 0;
110   return r;
111 }
112 
113 static long *
114 dummy_set_si (long si)
115 {
116   mpfr_t x;
117   long * r = dummy_new ();
118   (mpfr_custom_init_set) (x, 0, 0, p, &r[2]);
119   mpfr_set_si (x, si, MPFR_RNDN);
120   r[0] = mpfr_custom_get_kind (x);
121   r[1] = mpfr_custom_get_exp (x);
122   return r;
123 }
124 
125 static long *
126 dummy_add (long *a, long *b)
127 {
128   mpfr_t x, y, z;
129   long *r = dummy_new ();
130   mpfr_custom_init_set (x, 0, 0, p, &r[2]);
131   (mpfr_custom_init_set) (y, a[0], a[1], p, &a[2]);
132   mpfr_custom_init_set (z, b[0], b[1], p, &b[2]);
133   mpfr_add (x, y, z, MPFR_RNDN);
134   r[0] = (mpfr_custom_get_kind) (x);
135   r[1] = (mpfr_custom_get_exp) (x);
136   return r;
137 }
138 
139 static long *
140 dummy_compact (long *r, char *org_stack)
141 {
142   memmove (org_stack, r,
143            ALIGNED (2*sizeof (long)) + ALIGNED ((mpfr_custom_get_size) (p)));
144   return (long *) org_stack;
145 }
146 
147 static void
148 test2 (void)
149 {
150   mpfr_t x;
151   char *org = stack;
152   long *a, *b, *c;
153 
154   a = dummy_set_si (42);
155   b = dummy_set_si (17);
156   c = dummy_add (a, b);
157   c = dummy_compact (c, org);
158   (mpfr_custom_init_set) (x, c[0], c[1], p, &c[2]);
159   if (c != a || mpfr_cmp_ui (x, 59) != 0)
160     {
161       printf ("Compact (2) failed! c=%p a=%p\n", (void *) c, (void *) a);
162       mpfr_dump (x);
163       exit (1);
164     }
165   stack = org;
166 }
167 
168 static void
169 test_nan_inf_zero (void)
170 {
171   mpfr_ptr val;
172   int sign;
173   int kind;
174   char *org = stack;
175 
176   val = new_mpfr (MPFR_PREC_MIN);
177 
178   mpfr_set_nan (val);
179   kind = (mpfr_custom_get_kind) (val);
180   if (kind != MPFR_NAN_KIND)
181     {
182       printf ("mpfr_custom_get_kind error : ");
183       mpfr_dump (val);
184       printf (" is kind %d instead of %d\n", kind, MPFR_NAN_KIND);
185       exit (1);
186     }
187 
188   sign = 1;
189   mpfr_set_inf (val, sign);
190   kind = (mpfr_custom_get_kind) (val);
191   if ((ABS (kind) != MPFR_INF_KIND) || (SIGN (kind) != SIGN (sign)))
192     {
193       printf ("mpfr_custom_get_kind error : ");
194       mpfr_dump (val);
195       printf (" is kind %d instead of %d\n", kind, MPFR_INF_KIND);
196       printf (" have sign %d instead of %d\n", SIGN (kind), SIGN (sign));
197       exit (1);
198     }
199 
200   sign = -1;
201   mpfr_set_zero (val, sign);
202   kind = (mpfr_custom_get_kind) (val);
203   if ((ABS (kind) != MPFR_ZERO_KIND) || (SIGN (kind) != SIGN (sign)))
204     {
205       printf ("mpfr_custom_get_kind error : ");
206       mpfr_dump (val);
207       printf (" is kind %d instead of %d\n", kind, MPFR_ZERO_KIND);
208       printf (" have sign %d instead of %d\n", SIGN (kind), SIGN (sign));
209       exit (1);
210     }
211 
212   stack = org;
213 }
214 
215 int
216 main (void)
217 {
218   tests_start_mpfr ();
219   /* We test iff long = mp_limb_t */
220   if (sizeof (long) == sizeof (mp_limb_t))
221     {
222       test1 ();
223       test2 ();
224       test_nan_inf_zero ();
225     }
226   tests_end_mpfr ();
227   return 0;
228 }
229