1 /* Test mpf_mul, mpf_div, mpf_ui_div, and mpf_div_ui.
2
3 Copyright 1996, 2000, 2001, 2003 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 2.1 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; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 MA 02110-1301, USA. */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include "mpir.h"
26 #include "gmp-impl.h"
27 #include "tests.h"
28
29 #ifndef SIZE
30 #define SIZE 16
31 #endif
32
33 int
main(int argc,char ** argv)34 main (int argc, char **argv)
35 {
36 mp_size_t size;
37 mp_exp_t exp;
38 int reps = 10000;
39 int i;
40 mpf_t u, v, w, x;
41 mp_size_t bprec = SIZE * BITS_PER_MP_LIMB;
42 mpf_t rerr, limit_rerr;
43 unsigned long ulimb, vlimb;
44 int single_flag;
45 gmp_randstate_t rands;
46
47 tests_start ();
48 gmp_randinit_default(rands);
49
50 if (argc > 1)
51 {
52 reps = strtol (argv[1], 0, 0);
53 if (argc > 2)
54 bprec = strtol (argv[2], 0, 0);
55 }
56
57 mpf_set_default_prec (bprec);
58
59 mpf_init (rerr);
60 mpf_init (limit_rerr);
61
62 mpf_init (u);
63 mpf_init (v);
64 mpf_init (w);
65 mpf_init (x);
66
67 for (i = 0; i < reps; i++)
68 {
69 mp_size_t res_prec;
70
71 res_prec = urandom (rands) % bprec + 1;
72 mpf_set_prec (w, res_prec);
73 mpf_set_prec (x, res_prec);
74
75 mpf_set_ui (limit_rerr, 1);
76 mpf_div_2exp (limit_rerr, limit_rerr, res_prec - 1);
77
78 single_flag = 0;
79
80 if ((urandom (rands) & 1) != 0)
81 {
82 size = urandom (rands) % (2 * SIZE) - SIZE;
83 exp = urandom (rands) % SIZE;
84 mpf_rrandomb (u, rands, size, exp);
85 }
86 else
87 {
88 ulimb = urandom (rands);
89 mpf_set_ui (u, ulimb);
90 single_flag = 1;
91 }
92
93 if ((urandom (rands) & 1) != 0)
94 {
95 size = urandom (rands) % (2 * SIZE) - SIZE;
96 exp = urandom (rands) % SIZE;
97 mpf_rrandomb (v, rands, size, exp);
98 }
99 else
100 {
101 vlimb = urandom (rands);
102 mpf_set_ui (v, vlimb);
103 single_flag = 2;
104 }
105
106 if (mpf_sgn (v) == 0)
107 continue;
108
109 mpf_div (w, u, v);
110 mpf_mul (x, w, v);
111 mpf_reldiff (rerr, u, x);
112 if (mpf_cmp (rerr, limit_rerr) > 0)
113 {
114 printf ("ERROR in mpf_mul or mpf_div after %d tests\n", i);
115 printf (" u = "); mpf_dump (u);
116 printf (" v = "); mpf_dump (v);
117 printf (" x = "); mpf_dump (x);
118 printf (" w = "); mpf_dump (w);
119 abort ();
120 }
121
122 if (single_flag == 2)
123 {
124 mpf_div_ui (x, u, vlimb);
125 mpf_reldiff (rerr, w, x);
126 if (mpf_cmp (rerr, limit_rerr) > 0)
127 {
128 printf ("ERROR in mpf_div or mpf_div_ui after %d tests\n", i);
129 printf (" u = "); mpf_dump (u);
130 printf (" v = "); mpf_dump (v);
131 printf (" x = "); mpf_dump (x);
132 printf (" w = "); mpf_dump (w);
133 abort ();
134 }
135 }
136
137 if (single_flag == 1)
138 {
139 mpf_ui_div (x, ulimb, v);
140 mpf_reldiff (rerr, w, x);
141 if (mpf_cmp (rerr, limit_rerr) > 0)
142 {
143 printf ("ERROR in mpf_div or mpf_ui_div after %d tests\n", i);
144 printf (" u = "); mpf_dump (u);
145 printf (" v = "); mpf_dump (v);
146 printf (" x = "); mpf_dump (x);
147 printf (" w = "); mpf_dump (w);
148 abort ();
149 }
150 }
151 }
152
153 mpf_clear (rerr);
154 mpf_clear (limit_rerr);
155
156 mpf_clear (u);
157 mpf_clear (v);
158 mpf_clear (w);
159 mpf_clear (x);
160 gmp_randclear(rands);
161 tests_end ();
162 exit (0);
163 }
164