Upload Tizen:Base source
[external/gmp.git] / tests / mpf / t-div.c
1 /* Test mpf_div.
2
3 Copyright 2004 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 "gmp.h"
23 #include "gmp-impl.h"
24 #include "tests.h"
25
26
27 void
28 check_one (const char *desc, mpf_ptr got, mpf_srcptr u, mpf_srcptr v)
29 {
30   if (! refmpf_validate_division ("mpf_div", got, u, v))
31     {
32       mp_trace_base = -16;
33       mpf_trace ("  u", u);
34       mpf_trace ("  v", v);
35       printf    ("  %s\n", desc);
36       abort ();
37     }
38 }
39
40 void
41 check_rand (void)
42 {
43   unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
44   gmp_randstate_ptr  rands = RANDS;
45   unsigned long  prec;
46   mpf_t  got, u, v;
47   int    i;
48
49   mpf_init (got);
50   mpf_init (u);
51   mpf_init (v);
52
53   /* separate */
54   for (i = 0; i < 100; i++)
55     {
56       /* got precision */
57       prec = min_prec + gmp_urandomm_ui (rands, 15L);
58       refmpf_set_prec_limbs (got, prec);
59
60       /* u */
61       prec = min_prec + gmp_urandomm_ui (rands, 15L);
62       refmpf_set_prec_limbs (u, prec);
63       do {
64         mpf_random2 (u, PREC(u), (mp_exp_t) 20);
65       } while (SIZ(u) == 0);
66       if (gmp_urandomb_ui (rands, 1L))
67         mpf_neg (u, u);
68
69       /* v */
70       prec = min_prec + gmp_urandomm_ui (rands, 15L);
71       refmpf_set_prec_limbs (v, prec);
72       do {
73         mpf_random2 (v, PREC(v), (mp_exp_t) 20);
74       } while (SIZ(v) == 0);
75       if (gmp_urandomb_ui (rands, 1L))
76         mpf_neg (v, v);
77
78       switch (i % 3) {
79       case 0:
80         mpf_div (got, u, v);
81         check_one ("separate", got, u, v);
82         break;
83       case 1:
84         prec = refmpf_set_overlap (got, u);
85         mpf_div (got, got, v);
86         check_one ("dst == u", got, u, v);
87         mpf_set_prec_raw (got, prec);
88         break;
89       case 2:
90         prec = refmpf_set_overlap (got, v);
91         mpf_div (got, u, got);
92         check_one ("dst == v", got, u, v);
93         mpf_set_prec_raw (got, prec);
94         break;
95       }
96     }
97
98   mpf_clear (got);
99   mpf_clear (u);
100   mpf_clear (v);
101 }
102
103 /* Exercise calls mpf(x,x,x) */
104 void
105 check_reuse_three (void)
106 {
107   unsigned long  min_prec = __GMPF_BITS_TO_PREC (1);
108   gmp_randstate_ptr  rands = RANDS;
109   unsigned long  result_prec, input_prec, set_prec;
110   mpf_t  got;
111   int    i;
112
113   mpf_init (got);
114
115   for (i = 0; i < 8; i++)
116     {
117       result_prec = min_prec + gmp_urandomm_ui (rands, 15L);
118       input_prec = min_prec + gmp_urandomm_ui (rands, 15L);
119
120       set_prec = MAX (result_prec, input_prec);
121       refmpf_set_prec_limbs (got, set_prec);
122
123       /* input, non-zero, possibly negative */
124       PREC(got) = input_prec;
125       do {
126         mpf_random2 (got, input_prec, (mp_exp_t) 20);
127       } while (SIZ(got) == 0);
128       if (gmp_urandomb_ui (rands, 1L))
129         mpf_neg (got, got);
130
131       PREC(got) = result_prec;
132
133       mpf_div (got, got, got);
134
135       /* expect exactly 1.0 always */
136       ASSERT_ALWAYS (mpf_cmp_ui (got, 1L) == 0);
137
138       PREC(got) = set_prec;
139     }
140
141   mpf_clear (got);
142 }
143
144 void
145 check_various (void)
146 {
147   mpf_t got, u, v;
148
149   mpf_init (got);
150   mpf_init (u);
151   mpf_init (v);
152
153   /* 100/4 == 25 */
154   mpf_set_prec (got, 20L);
155   mpf_set_ui (u, 100L);
156   mpf_set_ui (v, 4L);
157   mpf_div (got, u, v);
158   MPF_CHECK_FORMAT (got);
159   ASSERT_ALWAYS (mpf_cmp_ui (got, 25L) == 0);
160
161   /* 1/(2^n+1), a case where truncating the divisor would be wrong */
162   mpf_set_prec (got, 500L);
163   mpf_set_prec (v, 900L);
164   mpf_set_ui (v, 1L);
165   mpf_mul_2exp (v, v, 800L);
166   mpf_add_ui (v, v, 1L);
167   mpf_div (got, u, v);
168   check_one ("1/2^n+1, separate", got, u, v);
169
170   mpf_clear (got);
171   mpf_clear (u);
172   mpf_clear (v);
173 }
174
175 int
176 main (void)
177 {
178   tests_start ();
179
180   check_various ();
181   check_rand ();
182   check_reuse_three ();
183
184   tests_end ();
185   exit (0);
186 }