convert.c revision 1.1.1.4
1254885Sdumbbell/* Test conversion using mpz_get_str and mpz_set_str.
2254885Sdumbbell
3254885SdumbbellCopyright 1993, 1994, 1996, 1999-2002, 2006, 2007 Free Software Foundation,
4254885SdumbbellInc.
5254885Sdumbbell
6254885SdumbbellThis file is part of the GNU MP Library test suite.
7254885Sdumbbell
8254885SdumbbellThe GNU MP Library test suite is free software; you can redistribute it
9254885Sdumbbelland/or modify it under the terms of the GNU General Public License as
10254885Sdumbbellpublished by the Free Software Foundation; either version 3 of the License,
11254885Sdumbbellor (at your option) any later version.
12254885Sdumbbell
13254885SdumbbellThe GNU MP Library test suite is distributed in the hope that it will be
14254885Sdumbbelluseful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15254885SdumbbellMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
16254885SdumbbellPublic License for more details.
17254885Sdumbbell
18254885SdumbbellYou should have received a copy of the GNU General Public License along with
19254885Sdumbbellthe GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
20254885Sdumbbell
21254885Sdumbbell#include <stdio.h>
22254885Sdumbbell#include <stdlib.h>
23254885Sdumbbell#include <string.h> /* for strlen */
24254885Sdumbbell
25254885Sdumbbell#include "gmp-impl.h"
26254885Sdumbbell#include "tests.h"
27254885Sdumbbell
28254885Sdumbbellvoid debug_mp (mpz_t, int);
29254885Sdumbbell
30254885Sdumbbell
31254885Sdumbbellvoid
32254885Sdumbbellstring_urandomb (char *bp, size_t len, int base, gmp_randstate_ptr rands)
33254885Sdumbbell{
34254885Sdumbbell  mpz_t bs;
35254885Sdumbbell  unsigned long bsi;
36254885Sdumbbell  int d, l;
37254885Sdumbbell  const char *collseq = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
38254885Sdumbbell
39254885Sdumbbell  mpz_init (bs);
40254885Sdumbbell
41254885Sdumbbell  mpz_urandomb (bs, rands, 32);
42254885Sdumbbell  bsi = mpz_get_ui (bs);
43254885Sdumbbell  d = bsi % base;
44254885Sdumbbell  while (len != 0)
45254885Sdumbbell    {
46254885Sdumbbell      l = (bsi >> 16) % 20;
47254885Sdumbbell      l = MIN (l, len);
48254885Sdumbbell
49254885Sdumbbell      memset (bp, collseq[d], l);
50254885Sdumbbell
51254885Sdumbbell      len -= l;
52254885Sdumbbell      bp += l;
53254885Sdumbbell
54254885Sdumbbell      mpz_urandomb (bs, rands, 32);
55254885Sdumbbell      bsi = mpz_get_ui (bs);
56254885Sdumbbell      d = bsi & 0xfff;
57254885Sdumbbell      if (d >= base)
58254885Sdumbbell	d = 0;
59254885Sdumbbell    }
60254885Sdumbbell
61254885Sdumbbell  bp[0] = '\0';
62254885Sdumbbell  mpz_clear (bs);
63254885Sdumbbell}
64254885Sdumbbell
65254885Sdumbbellint
66254885Sdumbbellmain (int argc, char **argv)
67254885Sdumbbell{
68254885Sdumbbell  mpz_t op1, op2;
69254885Sdumbbell  mp_size_t size;
70254885Sdumbbell  int i;
71254885Sdumbbell  int reps = 2000;
72254885Sdumbbell  char *str, *buf, *bp;
73254885Sdumbbell  int base;
74254885Sdumbbell  gmp_randstate_ptr rands;
75254885Sdumbbell  mpz_t bs;
76254885Sdumbbell  unsigned long bsi, size_range;
77254885Sdumbbell  size_t len;
78254885Sdumbbell
79254885Sdumbbell  tests_start ();
80254885Sdumbbell  TESTS_REPS (reps, argv, argc);
81254885Sdumbbell
82254885Sdumbbell  rands = RANDS;
83254885Sdumbbell
84254885Sdumbbell  mpz_init (bs);
85254885Sdumbbell
86254885Sdumbbell  mpz_init (op1);
87254885Sdumbbell  mpz_init (op2);
88254885Sdumbbell
89254885Sdumbbell  for (i = 0; i < reps; i++)
90254885Sdumbbell    {
91254885Sdumbbell      /* 1. Generate random mpz_t and convert to a string and back to mpz_t
92254885Sdumbbell	 again.  */
93254885Sdumbbell      mpz_urandomb (bs, rands, 32);
94254885Sdumbbell      size_range = mpz_get_ui (bs) % 17 + 2;	/* 2..18 */
95254885Sdumbbell      mpz_urandomb (bs, rands, size_range);	/* 3..262144 bits */
96254885Sdumbbell      size = mpz_get_ui (bs);
97254885Sdumbbell      mpz_rrandomb (op1, rands, size);
98254885Sdumbbell
99254885Sdumbbell      mpz_urandomb (bs, rands, 1);
100254885Sdumbbell      bsi = mpz_get_ui (bs);
101254885Sdumbbell      if ((bsi & 1) != 0)
102254885Sdumbbell	mpz_neg (op1, op1);
103254885Sdumbbell
104254885Sdumbbell      mpz_urandomb (bs, rands, 32);
105254885Sdumbbell      bsi = mpz_get_ui (bs);
106254885Sdumbbell      base = bsi % 62 + 1;
107254885Sdumbbell      if (base == 1)
108254885Sdumbbell	base = 0;
109254885Sdumbbell
110254885Sdumbbell      str = mpz_get_str ((char *) 0, base, op1);
111254885Sdumbbell      mpz_set_str_or_abort (op2, str, base);
112254885Sdumbbell
113254885Sdumbbell      if (mpz_cmp (op1, op2))
114254885Sdumbbell	{
115254885Sdumbbell	  fprintf (stderr, "ERROR, op1 and op2 different in test %d\n", i);
116254885Sdumbbell	  fprintf (stderr, "str  = %s\n", str);
117254885Sdumbbell	  fprintf (stderr, "base = %d\n", base);
118254885Sdumbbell	  fprintf (stderr, "op1  = "); debug_mp (op1, -16);
119254885Sdumbbell	  fprintf (stderr, "op2  = "); debug_mp (op2, -16);
120254885Sdumbbell	  abort ();
121254885Sdumbbell	}
122254885Sdumbbell
123254885Sdumbbell      (*__gmp_free_func) (str, strlen (str) + 1);
124254885Sdumbbell
125254885Sdumbbell      /* 2. Generate random string and convert to mpz_t and back to a string
126254885Sdumbbell	 again.  */
127254885Sdumbbell      mpz_urandomb (bs, rands, 32);
128254885Sdumbbell      size_range = mpz_get_ui (bs) % 16 + 1;	/* 1..16 */
129254885Sdumbbell      mpz_urandomb (bs, rands, size_range);	/* 1..65536 digits */
130254885Sdumbbell      len = mpz_get_ui (bs) + 1;
131254885Sdumbbell      buf = (char *) (*__gmp_allocate_func) (len + 1);
132254885Sdumbbell      if (base == 0)
133254885Sdumbbell	base = 10;
134254885Sdumbbell      string_urandomb (buf, len, base, rands);
135254885Sdumbbell
136254885Sdumbbell      mpz_set_str_or_abort (op1, buf, base);
137254885Sdumbbell      str = mpz_get_str ((char *) 0, base, op1);
138254885Sdumbbell
139254885Sdumbbell      /* Skip over leading zeros, but don't leave the string at zero length. */
140254885Sdumbbell      for (bp = buf; bp[0] == '0' && bp[1] != '\0'; bp++)
141254885Sdumbbell	;
142254885Sdumbbell
143254885Sdumbbell      if (strcasecmp (str, bp) != 0)
144254885Sdumbbell	{
145254885Sdumbbell	  fprintf (stderr, "ERROR, str and buf different in test %d\n", i);
146254885Sdumbbell	  fprintf (stderr, "str  = %s\n", str);
147254885Sdumbbell	  fprintf (stderr, "buf  = %s\n", buf);
148254885Sdumbbell	  fprintf (stderr, "base = %d\n", base);
149254885Sdumbbell	  fprintf (stderr, "op1  = "); debug_mp (op1, -16);
150254885Sdumbbell	  abort ();
151254885Sdumbbell	}
152254885Sdumbbell
153254885Sdumbbell      (*__gmp_free_func) (buf, len + 1);
154254885Sdumbbell      (*__gmp_free_func) (str, strlen (str) + 1);
155254885Sdumbbell    }
156254885Sdumbbell
157254885Sdumbbell  mpz_clear (bs);
158254885Sdumbbell  mpz_clear (op1);
159254885Sdumbbell  mpz_clear (op2);
160254885Sdumbbell
161254885Sdumbbell  tests_end ();
162254885Sdumbbell  exit (0);
163254885Sdumbbell}
164254885Sdumbbell
165254885Sdumbbellvoid
166254885Sdumbbelldebug_mp (mpz_t x, int base)
167254885Sdumbbell{
168254885Sdumbbell  mpz_out_str (stderr, base, x); fputc ('\n', stderr);
169254885Sdumbbell}
170254885Sdumbbell