blob: 3214592232da42a3adf1569f85b0a9b72b4fd0a6 [file] [log] [blame]
Austin Schuhdace2a62020-08-18 10:56:48 -07001/* Test mpf_div.
2
3Copyright 2004 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library test suite.
6
7The GNU MP Library test suite is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 3 of the License,
10or (at your option) any later version.
11
12The GNU MP Library test suite is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15Public License for more details.
16
17You should have received a copy of the GNU General Public License along with
18the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
19
20#include <stdio.h>
21#include <stdlib.h>
22#include "gmp-impl.h"
23#include "tests.h"
24
25
26void
27check_one (const char *desc, mpf_ptr got, mpf_srcptr u, mpf_srcptr v)
28{
29 if (! refmpf_validate_division ("mpf_div", got, u, v))
30 {
31 mp_trace_base = -16;
32 mpf_trace (" u", u);
33 mpf_trace (" v", v);
34 printf (" %s\n", desc);
35 abort ();
36 }
37}
38
39void
40check_rand (void)
41{
42 unsigned long min_prec = __GMPF_BITS_TO_PREC (1);
43 gmp_randstate_ptr rands = RANDS;
44 unsigned long prec;
45 mpf_t got, u, v;
46 int i;
47
48 mpf_init (got);
49 mpf_init (u);
50 mpf_init (v);
51
52 /* separate */
53 for (i = 0; i < 100; i++)
54 {
55 /* got precision */
56 prec = min_prec + gmp_urandomm_ui (rands, 15L);
57 refmpf_set_prec_limbs (got, prec);
58
59 /* u */
60 prec = min_prec + gmp_urandomm_ui (rands, 15L);
61 refmpf_set_prec_limbs (u, prec);
62 do {
63 mpf_random2 (u, PREC(u), (mp_exp_t) 20);
64 } while (SIZ(u) == 0);
65 if (gmp_urandomb_ui (rands, 1L))
66 mpf_neg (u, u);
67
68 /* v */
69 prec = min_prec + gmp_urandomm_ui (rands, 15L);
70 refmpf_set_prec_limbs (v, prec);
71 do {
72 mpf_random2 (v, PREC(v), (mp_exp_t) 20);
73 } while (SIZ(v) == 0);
74 if (gmp_urandomb_ui (rands, 1L))
75 mpf_neg (v, v);
76
77 switch (i % 3) {
78 case 0:
79 mpf_div (got, u, v);
80 check_one ("separate", got, u, v);
81 break;
82 case 1:
83 prec = refmpf_set_overlap (got, u);
84 mpf_div (got, got, v);
85 check_one ("dst == u", got, u, v);
86 mpf_set_prec_raw (got, prec);
87 break;
88 case 2:
89 prec = refmpf_set_overlap (got, v);
90 mpf_div (got, u, got);
91 check_one ("dst == v", got, u, v);
92 mpf_set_prec_raw (got, prec);
93 break;
94 }
95 }
96
97 mpf_clear (got);
98 mpf_clear (u);
99 mpf_clear (v);
100}
101
102/* Exercise calls mpf(x,x,x) */
103void
104check_reuse_three (void)
105{
106 unsigned long min_prec = __GMPF_BITS_TO_PREC (1);
107 gmp_randstate_ptr rands = RANDS;
108 unsigned long result_prec, input_prec, set_prec;
109 mpf_t got;
110 int i;
111
112 mpf_init (got);
113
114 for (i = 0; i < 8; i++)
115 {
116 result_prec = min_prec + gmp_urandomm_ui (rands, 15L);
117 input_prec = min_prec + gmp_urandomm_ui (rands, 15L);
118
119 set_prec = MAX (result_prec, input_prec);
120 refmpf_set_prec_limbs (got, set_prec);
121
122 /* input, non-zero, possibly negative */
123 PREC(got) = input_prec;
124 do {
125 mpf_random2 (got, input_prec, (mp_exp_t) 20);
126 } while (SIZ(got) == 0);
127 if (gmp_urandomb_ui (rands, 1L))
128 mpf_neg (got, got);
129
130 PREC(got) = result_prec;
131
132 mpf_div (got, got, got);
133
134 /* expect exactly 1.0 always */
135 ASSERT_ALWAYS (mpf_cmp_ui (got, 1L) == 0);
136
137 PREC(got) = set_prec;
138 }
139
140 mpf_clear (got);
141}
142
143void
144check_various (void)
145{
146 mpf_t got, u, v;
147
148 mpf_init (got);
149 mpf_init (u);
150 mpf_init (v);
151
152 /* 100/4 == 25 */
153 mpf_set_prec (got, 20L);
154 mpf_set_ui (u, 100L);
155 mpf_set_ui (v, 4L);
156 mpf_div (got, u, v);
157 MPF_CHECK_FORMAT (got);
158 ASSERT_ALWAYS (mpf_cmp_ui (got, 25L) == 0);
159
160 /* 1/(2^n+1), a case where truncating the divisor would be wrong */
161 mpf_set_prec (got, 500L);
162 mpf_set_prec (v, 900L);
163 mpf_set_ui (v, 1L);
164 mpf_mul_2exp (v, v, 800L);
165 mpf_add_ui (v, v, 1L);
166 mpf_div (got, u, v);
167 check_one ("1/2^n+1, separate", got, u, v);
168
169 mpf_clear (got);
170 mpf_clear (u);
171 mpf_clear (v);
172}
173
174int
175main (void)
176{
177 tests_start ();
178
179 check_various ();
180 check_rand ();
181 check_reuse_three ();
182
183 tests_end ();
184 exit (0);
185}