Upload Tizen:Base source
[external/gmp.git] / tests / mpf / reuse.c
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 */