1/* Test mp*_class functions.
2
3Copyright 2002, 2003 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
21/* Note that we don't use <climits> for LONG_MIN, but instead our own
22   definitions in gmp-impl.h.  In g++ 2.95.4 (debian 3.0) under
23   -mcpu=ultrasparc, limits.h sees __sparc_v9__ defined and assumes that
24   means long is 64-bit long, but it's only 32-bits, causing fatal compile
25   errors.  */
26
27#include "config.h"
28
29#include <string>
30
31#include "gmpxx.h"
32#include "gmp-impl.h"
33#include "tests.h"
34
35using namespace std;
36
37
38void
39check_mpz (void)
40{
41  // mpz_class::fits_sint_p
42  {
43    bool       fits;
44    mpz_class  z;
45    z = INT_MIN; fits = z.fits_sint_p(); ASSERT_ALWAYS (fits);
46    z--;         fits = z.fits_sint_p(); ASSERT_ALWAYS (! fits);
47    z = INT_MAX; fits = z.fits_sint_p(); ASSERT_ALWAYS (fits);
48    z++;         fits = z.fits_sint_p(); ASSERT_ALWAYS (! fits);
49  }
50
51  // mpz_class::fits_uint_p
52  {
53    bool       fits;
54    mpz_class  z;
55    z = 0;        fits = z.fits_uint_p(); ASSERT_ALWAYS (fits);
56    z--;          fits = z.fits_uint_p(); ASSERT_ALWAYS (! fits);
57    z = UINT_MAX; fits = z.fits_uint_p(); ASSERT_ALWAYS (fits);
58    z++;          fits = z.fits_uint_p(); ASSERT_ALWAYS (! fits);
59  }
60
61  // mpz_class::fits_slong_p
62  {
63    bool       fits;
64    mpz_class  z;
65    z = LONG_MIN; fits = z.fits_slong_p(); ASSERT_ALWAYS (fits);
66    z--;          fits = z.fits_slong_p(); ASSERT_ALWAYS (! fits);
67    z = LONG_MAX; fits = z.fits_slong_p(); ASSERT_ALWAYS (fits);
68    z++;          fits = z.fits_slong_p(); ASSERT_ALWAYS (! fits);
69  }
70
71  // mpz_class::fits_ulong_p
72  {
73    bool       fits;
74    mpz_class  z;
75    z = 0;         fits = z.fits_ulong_p(); ASSERT_ALWAYS (fits);
76    z--;           fits = z.fits_ulong_p(); ASSERT_ALWAYS (! fits);
77    z = ULONG_MAX; fits = z.fits_ulong_p(); ASSERT_ALWAYS (fits);
78    z++;           fits = z.fits_ulong_p(); ASSERT_ALWAYS (! fits);
79  }
80
81  // mpz_class::fits_sshort_p
82  {
83    bool       fits;
84    mpz_class  z;
85    z = SHRT_MIN; fits = z.fits_sshort_p(); ASSERT_ALWAYS (fits);
86    z--;          fits = z.fits_sshort_p(); ASSERT_ALWAYS (! fits);
87    z = SHRT_MAX; fits = z.fits_sshort_p(); ASSERT_ALWAYS (fits);
88    z++;          fits = z.fits_sshort_p(); ASSERT_ALWAYS (! fits);
89  }
90
91  // mpz_class::fits_ushort_p
92  {
93    bool       fits;
94    mpz_class  z;
95    z = 0;         fits = z.fits_ushort_p(); ASSERT_ALWAYS (fits);
96    z--;           fits = z.fits_ushort_p(); ASSERT_ALWAYS (! fits);
97    z = USHRT_MAX; fits = z.fits_ushort_p(); ASSERT_ALWAYS (fits);
98    z++;           fits = z.fits_ushort_p(); ASSERT_ALWAYS (! fits);
99  }
100
101  // mpz_class::get_mpz_t
102  {
103    mpz_class  z(0);
104    mpz_ptr    p = z.get_mpz_t();
105    ASSERT_ALWAYS (mpz_cmp_ui (p, 0) == 0);
106  }
107  {
108    mpz_class  z(0);
109    mpz_srcptr p = z.get_mpz_t();
110    ASSERT_ALWAYS (mpz_cmp_ui (p, 0) == 0);
111  }
112
113  // mpz_class::get_d
114  // mpz_class::get_si
115  // mpz_class::get_ui
116  {
117    mpz_class  z(123);
118    { double d = z.get_d();  ASSERT_ALWAYS (d == 123.0); }
119    { long   l = z.get_si(); ASSERT_ALWAYS (l == 123L); }
120    { long   u = z.get_ui(); ASSERT_ALWAYS (u == 123L); }
121  }
122  {
123    mpz_class  z(-123);
124    { double d = z.get_d();  ASSERT_ALWAYS (d == -123.0); }
125    { long   l = z.get_si(); ASSERT_ALWAYS (l == -123L); }
126  }
127
128  // mpz_class::get_str
129  {
130    mpz_class  z(123);
131    string     s;
132    s = z.get_str(); ASSERT_ALWAYS (s == "123");
133    s = z.get_str(16); ASSERT_ALWAYS (s == "7b");
134    s = z.get_str(-16); ASSERT_ALWAYS (s == "7B");
135  }
136
137  // mpz_class::set_str
138  {
139    mpz_class  z;
140    int        ret;
141    ret = z.set_str ("123", 10);  ASSERT_ALWAYS (ret == 0 && z == 123);
142    ret = z.set_str ("7b",  16);  ASSERT_ALWAYS (ret == 0 && z == 123);
143    ret = z.set_str ("7B",  16);  ASSERT_ALWAYS (ret == 0 && z == 123);
144    ret = z.set_str ("0x7B", 0);  ASSERT_ALWAYS (ret == 0 && z == 123);
145
146    ret = z.set_str (string("123"), 10);  ASSERT_ALWAYS (ret == 0 && z == 123);
147    ret = z.set_str (string("7b"),  16);  ASSERT_ALWAYS (ret == 0 && z == 123);
148    ret = z.set_str (string("7B"),  16);  ASSERT_ALWAYS (ret == 0 && z == 123);
149    ret = z.set_str (string("0x7B"), 0);  ASSERT_ALWAYS (ret == 0 && z == 123);
150  }
151}
152
153void
154check_mpq (void)
155{
156  // mpq_class::canonicalize
157  {
158    mpq_class  q(12,9);
159    q.canonicalize();
160    ASSERT_ALWAYS (q.get_num() == 4);
161    ASSERT_ALWAYS (q.get_den() == 3);
162  }
163
164  // mpq_class::get_d
165  {
166    mpq_class  q(123);
167    { double d = q.get_d();  ASSERT_ALWAYS (d == 123.0); }
168  }
169  {
170    mpq_class  q(-123);
171    { double d = q.get_d();  ASSERT_ALWAYS (d == -123.0); }
172  }
173
174  // mpq_class::get_mpq_t
175  {
176    mpq_class  q(0);
177    mpq_ptr    p = q.get_mpq_t();
178    ASSERT_ALWAYS (mpq_cmp_ui (p, 0, 1) == 0);
179  }
180  {
181    mpq_class  q(0);
182    mpq_srcptr p = q.get_mpq_t();
183    ASSERT_ALWAYS (mpq_cmp_ui (p, 0, 1) == 0);
184  }
185
186  // mpq_class::get_num, mpq_class::get_den
187  {
188    const mpq_class  q(4,5);
189    mpz_class  z;
190    z = q.get_num(); ASSERT_ALWAYS (z == 4);
191    z = q.get_den(); ASSERT_ALWAYS (z == 5);
192  }
193
194  // mpq_class::get_num_mpz_t, mpq_class::get_den_mpz_t
195  {
196    mpq_class  q(4,5);
197    mpz_ptr    p;
198    p = q.get_num_mpz_t(); ASSERT_ALWAYS (mpz_cmp_ui (p, 4) == 0);
199    p = q.get_den_mpz_t(); ASSERT_ALWAYS (mpz_cmp_ui (p, 5) == 0);
200  }
201  {
202    const mpq_class  q(4,5);
203    mpz_srcptr p;
204    p = q.get_num_mpz_t(); ASSERT_ALWAYS (mpz_cmp_ui (p, 4) == 0);
205    p = q.get_den_mpz_t(); ASSERT_ALWAYS (mpz_cmp_ui (p, 5) == 0);
206  }
207
208  // mpq_class::get_str
209  {
210    mpq_class  q(17,11);
211    string     s;
212    s = q.get_str();    ASSERT_ALWAYS (s == "17/11");
213    s = q.get_str(10);  ASSERT_ALWAYS (s == "17/11");
214    s = q.get_str(16);  ASSERT_ALWAYS (s == "11/b");
215    s = q.get_str(-16); ASSERT_ALWAYS (s == "11/B");
216  }
217
218  // mpq_class::set_str
219  {
220    mpq_class  q;
221    int        ret;
222    ret = q.set_str ("123", 10);     ASSERT_ALWAYS (ret == 0 && q == 123);
223    ret = q.set_str ("4/5", 10);     ASSERT_ALWAYS (ret == 0 && q == mpq_class(4,5));
224    ret = q.set_str ("7b",  16);     ASSERT_ALWAYS (ret == 0 && q == 123);
225    ret = q.set_str ("7B",  16);     ASSERT_ALWAYS (ret == 0 && q == 123);
226    ret = q.set_str ("0x7B", 0);     ASSERT_ALWAYS (ret == 0 && q == 123);
227    ret = q.set_str ("0x10/17", 0);  ASSERT_ALWAYS (ret == 0 && q == mpq_class(16,17));
228
229    ret = q.set_str (string("4/5"), 10);  ASSERT_ALWAYS (ret == 0 && q == mpq_class(4,5));
230    ret = q.set_str (string("123"), 10);  ASSERT_ALWAYS (ret == 0 && q == 123);
231    ret = q.set_str (string("7b"),  16);  ASSERT_ALWAYS (ret == 0 && q == 123);
232    ret = q.set_str (string("7B"),  16);  ASSERT_ALWAYS (ret == 0 && q == 123);
233    ret = q.set_str (string("0x7B"), 0);  ASSERT_ALWAYS (ret == 0 && q == 123);
234    ret = q.set_str (string("0x10/17"), 0);  ASSERT_ALWAYS (ret == 0 && q == mpq_class(16,17));
235  }
236}
237
238void
239check_mpf (void)
240{
241  // mpf_class::fits_sint_p
242  {
243    bool       fits;
244    mpf_class  f (0, 2*8*sizeof(int));
245    f = INT_MIN; fits = f.fits_sint_p(); ASSERT_ALWAYS (fits);
246    f--;         fits = f.fits_sint_p(); ASSERT_ALWAYS (! fits);
247    f = INT_MAX; fits = f.fits_sint_p(); ASSERT_ALWAYS (fits);
248    f++;         fits = f.fits_sint_p(); ASSERT_ALWAYS (! fits);
249  }
250
251  // mpf_class::fits_uint_p
252  {
253    bool       fits;
254    mpf_class  f (0, 2*8*sizeof(int));
255    f = 0;        fits = f.fits_uint_p(); ASSERT_ALWAYS (fits);
256    f--;          fits = f.fits_uint_p(); ASSERT_ALWAYS (! fits);
257    f = UINT_MAX; fits = f.fits_uint_p(); ASSERT_ALWAYS (fits);
258    f++;          fits = f.fits_uint_p(); ASSERT_ALWAYS (! fits);
259  }
260
261  // mpf_class::fits_slong_p
262  {
263    bool       fits;
264    mpf_class  f (0, 2*8*sizeof(long));
265    f = LONG_MIN; fits = f.fits_slong_p(); ASSERT_ALWAYS (fits);
266    f--;          fits = f.fits_slong_p(); ASSERT_ALWAYS (! fits);
267    f = LONG_MAX; fits = f.fits_slong_p(); ASSERT_ALWAYS (fits);
268    f++;          fits = f.fits_slong_p(); ASSERT_ALWAYS (! fits);
269  }
270
271  // mpf_class::fits_ulong_p
272  {
273    bool       fits;
274    mpf_class  f (0, 2*8*sizeof(long));
275    f = 0;         fits = f.fits_ulong_p(); ASSERT_ALWAYS (fits);
276    f--;           fits = f.fits_ulong_p(); ASSERT_ALWAYS (! fits);
277    f = ULONG_MAX; fits = f.fits_ulong_p(); ASSERT_ALWAYS (fits);
278    f++;           fits = f.fits_ulong_p(); ASSERT_ALWAYS (! fits);
279  }
280
281  // mpf_class::fits_sshort_p
282  {
283    bool       fits;
284    mpf_class  f (0, 2*8*sizeof(short));
285    f = SHRT_MIN; fits = f.fits_sshort_p(); ASSERT_ALWAYS (fits);
286    f--;          fits = f.fits_sshort_p(); ASSERT_ALWAYS (! fits);
287    f = SHRT_MAX; fits = f.fits_sshort_p(); ASSERT_ALWAYS (fits);
288    f++;          fits = f.fits_sshort_p(); ASSERT_ALWAYS (! fits);
289  }
290
291  // mpf_class::fits_ushort_p
292  {
293    bool       fits;
294    mpf_class  f (0, 2*8*sizeof(short));
295    f = 0;         fits = f.fits_ushort_p(); ASSERT_ALWAYS (fits);
296    f--;           fits = f.fits_ushort_p(); ASSERT_ALWAYS (! fits);
297    f = USHRT_MAX; fits = f.fits_ushort_p(); ASSERT_ALWAYS (fits);
298    f++;           fits = f.fits_ushort_p(); ASSERT_ALWAYS (! fits);
299  }
300
301  // mpf_class::get_d
302  // mpf_class::get_si
303  // mpf_class::get_ui
304  {
305    mpf_class  f(123);
306    { double d = f.get_d();  ASSERT_ALWAYS (d == 123.0); }
307    { long   l = f.get_si(); ASSERT_ALWAYS (l == 123L); }
308    { long   u = f.get_ui(); ASSERT_ALWAYS (u == 123L); }
309  }
310  {
311    mpf_class  f(-123);
312    { double d = f.get_d();  ASSERT_ALWAYS (d == -123.0); }
313    { long   l = f.get_si(); ASSERT_ALWAYS (l == -123L); }
314  }
315
316  // mpf_class::get_prec
317  {
318    mpf_class  f;
319    ASSERT_ALWAYS (f.get_prec() == mpf_get_default_prec());
320  }
321
322  // mpf_class::get_str
323  {
324    mpf_class  f(123);
325    string     s;
326    mp_exp_t   e;
327    s = f.get_str(e);        ASSERT_ALWAYS (s == "123" && e == 3);
328    s = f.get_str(e,  16);   ASSERT_ALWAYS (s == "7b"  && e == 2);
329    s = f.get_str(e, -16);   ASSERT_ALWAYS (s == "7B"  && e == 2);
330    s = f.get_str(e, 10, 2); ASSERT_ALWAYS (s == "12"  && e == 3);
331    s = f.get_str(e, 10, 1); ASSERT_ALWAYS (s == "1"   && e == 3);
332  }
333
334  // mpf_class::set_str
335  {
336    mpf_class  f;
337    int        ret;
338    ret = f.set_str ("123",     10);  ASSERT_ALWAYS (ret == 0 && f == 123);
339    ret = f.set_str ("123e1",   10);  ASSERT_ALWAYS (ret == 0 && f == 1230);
340    ret = f.set_str ("1230e-1", 10);  ASSERT_ALWAYS (ret == 0 && f == 123);
341    ret = f.set_str ("7b",      16);  ASSERT_ALWAYS (ret == 0 && f == 123);
342    ret = f.set_str ("7B",      16);  ASSERT_ALWAYS (ret == 0 && f == 123);
343    ret = f.set_str ("7B@1",    16);  ASSERT_ALWAYS (ret == 0 && f == 1968);
344    ret = f.set_str ("7B0@-1",  16);  ASSERT_ALWAYS (ret == 0 && f == 123);
345
346    ret = f.set_str (string("123"),     10);  ASSERT_ALWAYS (ret == 0 && f == 123);
347    ret = f.set_str (string("123e1"),   10);  ASSERT_ALWAYS (ret == 0 && f == 1230);
348    ret = f.set_str (string("1230e-1"), 10);  ASSERT_ALWAYS (ret == 0 && f == 123);
349    ret = f.set_str (string("7b"),      16);  ASSERT_ALWAYS (ret == 0 && f == 123);
350    ret = f.set_str (string("7B"),      16);  ASSERT_ALWAYS (ret == 0 && f == 123);
351    ret = f.set_str (string("7B@1"),    16);  ASSERT_ALWAYS (ret == 0 && f == 1968);
352    ret = f.set_str (string("7B0@-1"),  16);  ASSERT_ALWAYS (ret == 0 && f == 123);
353  }
354
355  // mpf_class::set_prec
356  {
357    mpf_class  f;
358    f.set_prec (256);
359    ASSERT_ALWAYS (f.get_prec () >= 256);
360  }
361
362  // mpf_class::set_prec_raw
363  {
364    mpf_class  f (0, 100 * GMP_NUMB_BITS);
365    f.set_prec_raw (5 * GMP_NUMB_BITS);
366    ASSERT_ALWAYS (f.get_prec () >= 5 * GMP_NUMB_BITS);
367    ASSERT_ALWAYS (f.get_prec () < 100 * GMP_NUMB_BITS);
368    f.set_prec_raw (100 * GMP_NUMB_BITS);
369  }
370}
371
372// std::numeric_limits
373void
374check_limits (void)
375{
376  // Check that the content is not private.
377  ASSERT_ALWAYS ( std::numeric_limits<mpz_class>::is_integer);
378  ASSERT_ALWAYS (!std::numeric_limits<mpf_class>::is_integer);
379
380  // Check that symbols are emitted.
381  ASSERT_ALWAYS (&std::numeric_limits<mpz_class>::is_integer
382	      != &std::numeric_limits<mpq_class>::is_integer);
383}
384
385int
386main (void)
387{
388  tests_start();
389
390  check_mpz();
391  check_mpq();
392  check_mpf();
393  check_limits();
394
395  tests_end();
396  return 0;
397}
398