xref: /netbsd-src/external/lgpl3/gmp/dist/tests/mpf/reuse.c (revision c7c727fae85036860d5bb848f2730ff419e2b060)
1 /* Test that routines allow reusing a source variable as destination.
2 
3 Copyright 1996, 2000, 2001, 2002 Free Software Foundation, Inc.
4 
5 This file is part of the GNU MP Library.
6 
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
15 License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "gmp.h"
25 #include "gmp-impl.h"
26 #include "tests.h"
27 
28 #if __GMP_LIBGMP_DLL
29 
30 /* FIXME: When linking to a DLL libgmp, mpf_add etc can't be used as
31    initializers for global variables because they're effectively global
32    variables (function pointers) themselves.  Perhaps calling a test
33    function successively with mpf_add etc would be better.  */
34 
35 int
36 main (void)
37 {
38   printf ("Test suppressed for windows DLL\n");
39   exit (0);
40 }
41 
42 
43 #else /* ! DLL_EXPORT */
44 
45 #ifndef SIZE
46 #define SIZE 16
47 #endif
48 
49 #ifndef EXPO
50 #define EXPO 32
51 #endif
52 
53 void dump_abort __GMP_PROTO ((char *, mpf_t, mpf_t));
54 
55 typedef void (*dss_func) __GMP_PROTO ((mpf_ptr, mpf_srcptr, mpf_srcptr));
56 
57 dss_func dss_funcs[] =
58 {
59   mpf_div, mpf_add, mpf_mul, mpf_sub,
60 };
61 
62 char *dss_func_names[] =
63 {
64   "mpf_div", "mpf_add", "mpf_mul", "mpf_sub",
65 };
66 
67 typedef void (*dsi_func) __GMP_PROTO ((mpf_ptr, mpf_srcptr, unsigned long int));
68 
69 dsi_func dsi_funcs[] =
70 {
71   mpf_div_ui, mpf_add_ui, mpf_mul_ui, mpf_sub_ui,
72   mpf_mul_2exp, mpf_div_2exp
73 };
74 
75 char *dsi_func_names[] =
76 {
77   "mpf_div_ui", "mpf_add_ui", "mpf_mul_ui", "mpf_sub_ui",
78   "mpf_mul_2exp", "mpf_div_2exp"
79 };
80 
81 typedef void (*dis_func) __GMP_PROTO ((mpf_ptr, unsigned long int, mpf_srcptr));
82 
83 dis_func dis_funcs[] =
84 {
85   mpf_ui_div, mpf_ui_sub,
86 };
87 
88 char *dis_func_names[] =
89 {
90   "mpf_ui_div", "mpf_ui_sub",
91 };
92 
93 int
94 main (int argc, char **argv)
95 {
96   int i;
97   int pass, reps = 10000;
98   mpf_t in1, in2, out1;
99   unsigned long int in1i, in2i;
100   mpf_t res1, res2, res3;
101   mp_size_t bprec = 100;
102 
103   tests_start ();
104 
105   if (argc > 1)
106     {
107       reps = strtol (argv[1], 0, 0);
108       if (argc > 2)
109 	bprec = strtol (argv[2], 0, 0);
110     }
111 
112   mpf_set_default_prec (bprec);
113 
114   mpf_init (in1);
115   mpf_init (in2);
116   mpf_init (out1);
117   mpf_init (res1);
118   mpf_init (res2);
119   mpf_init (res3);
120 
121   for (pass = 1; pass <= reps; pass++)
122     {
123       mpf_random2 (in1, urandom () % SIZE - SIZE/2, urandom () % EXPO);
124       mpf_random2 (in2, urandom () % SIZE - SIZE/2, urandom () % EXPO);
125 
126       for (i = 0; i < sizeof (dss_funcs) / sizeof (dss_func); i++)
127 	{
128 	  /* Don't divide by 0.  */
129 	  if (i == 0 && mpf_cmp_ui (in2, 0) == 0)
130 	    continue;
131 
132 	  (dss_funcs[i]) (res1, in1, in2);
133 
134 	  mpf_set (out1, in1);
135 	  (dss_funcs[i]) (out1, out1, in2);
136 	  mpf_set (res2, out1);
137 
138 	  mpf_set (out1, in2);
139 	  (dss_funcs[i]) (out1, in1, out1);
140 	  mpf_set (res3, out1);
141 
142 	  if (mpf_cmp (res1, res2) != 0)
143 	    dump_abort (dss_func_names[i], res1, res2);
144 	  if (mpf_cmp (res1, res3) != 0)
145 	    dump_abort (dss_func_names[i], res1, res3);
146 	}
147 
148       in2i = urandom ();
149       for (i = 0; i < sizeof (dsi_funcs) / sizeof (dsi_func); i++)
150 	{
151 	  /* Don't divide by 0.  */
152 	  if (strcmp (dsi_func_names[i], "mpf_div_ui") == 0 && in2i == 0)
153 	    continue;
154 
155 	  (dsi_funcs[i]) (res1, in1, in2i);
156 
157 	  mpf_set (out1, in1);
158 	  (dsi_funcs[i]) (out1, out1, in2i);
159 	  mpf_set (res2, out1);
160 
161 	  if (mpf_cmp (res1, res2) != 0)
162 	    dump_abort (dsi_func_names[i], res1, res2);
163 	}
164 
165       in1i = urandom ();
166       for (i = 0; i < sizeof (dis_funcs) / sizeof (dis_func); i++)
167 	{
168 	  /* Don't divide by 0.  */
169 	  if (strcmp (dis_func_names[i], "mpf_ui_div") == 0
170 	      && mpf_cmp_ui (in2, 0) == 0)
171 	    continue;
172 
173 	  (dis_funcs[i]) (res1, in1i, in2);
174 
175 	  mpf_set (out1, in2);
176 	  (dis_funcs[i]) (out1, in1i, out1);
177 	  mpf_set (res2, out1);
178 
179 	  if (mpf_cmp (res1, res2) != 0)
180 	    dump_abort (dis_func_names[i], res1, res2);
181 	}
182 
183     }
184 
185   mpf_clear (in1);
186   mpf_clear (in2);
187   mpf_clear (out1);
188   mpf_clear (res1);
189   mpf_clear (res2);
190   mpf_clear (res3);
191 
192   tests_end ();
193   exit (0);
194 }
195 
196 void
197 dump_abort (char *name, mpf_t res1, mpf_t res2)
198 {
199   printf ("failure in %s:\n", name);
200   mpf_dump (res1);
201   mpf_dump (res2);
202   abort ();
203 }
204 
205 #if 0
206 void mpf_abs		__GMP_PROTO ((mpf_ptr, mpf_srcptr));
207 void mpf_sqrt		__GMP_PROTO ((mpf_ptr, mpf_srcptr));
208 void mpf_neg		__GMP_PROTO ((mpf_ptr, mpf_srcptr));
209 #endif
210 
211 #endif /* ! DLL_EXPORT */
212