github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpz/convert.c (about)

     1  /* Test conversion using mpz_get_str and mpz_set_str.
     2  
     3  Copyright 1993, 1994, 1996, 1999-2002, 2006, 2007 Free Software Foundation,
     4  Inc.
     5  
     6  This file is part of the GNU MP Library test suite.
     7  
     8  The GNU MP Library test suite is free software; you can redistribute it
     9  and/or modify it under the terms of the GNU General Public License as
    10  published by the Free Software Foundation; either version 3 of the License,
    11  or (at your option) any later version.
    12  
    13  The GNU MP Library test suite is distributed in the hope that it will be
    14  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
    16  Public License for more details.
    17  
    18  You should have received a copy of the GNU General Public License along with
    19  the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
    20  
    21  #include <stdio.h>
    22  #include <stdlib.h>
    23  #include <string.h> /* for strlen */
    24  
    25  #include "gmp.h"
    26  #include "gmp-impl.h"
    27  #include "tests.h"
    28  
    29  void debug_mp (mpz_t, int);
    30  
    31  
    32  void
    33  string_urandomb (char *bp, size_t len, int base, gmp_randstate_ptr rands)
    34  {
    35    mpz_t bs;
    36    unsigned long bsi;
    37    int d, l;
    38    const char *collseq = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    39  
    40    mpz_init (bs);
    41  
    42    mpz_urandomb (bs, rands, 32);
    43    bsi = mpz_get_ui (bs);
    44    d = bsi % base;
    45    while (len != 0)
    46      {
    47        l = (bsi >> 16) % 20;
    48        l = MIN (l, len);
    49  
    50        memset (bp, collseq[d], l);
    51  
    52        len -= l;
    53        bp += l;
    54  
    55        mpz_urandomb (bs, rands, 32);
    56        bsi = mpz_get_ui (bs);
    57        d = bsi & 0xfff;
    58        if (d >= base)
    59  	d = 0;
    60      }
    61  
    62    bp[0] = '\0';
    63    mpz_clear (bs);
    64  }
    65  
    66  int
    67  main (int argc, char **argv)
    68  {
    69    mpz_t op1, op2;
    70    mp_size_t size;
    71    int i;
    72    int reps = 2000;
    73    char *str, *buf, *bp;
    74    int base;
    75    gmp_randstate_ptr rands;
    76    mpz_t bs;
    77    unsigned long bsi, size_range;
    78    size_t len;
    79  
    80    tests_start ();
    81    TESTS_REPS (reps, argv, argc);
    82  
    83    rands = RANDS;
    84  
    85    mpz_init (bs);
    86  
    87    mpz_init (op1);
    88    mpz_init (op2);
    89  
    90    for (i = 0; i < reps; i++)
    91      {
    92        /* 1. Generate random mpz_t and convert to a string and back to mpz_t
    93  	 again.  */
    94        mpz_urandomb (bs, rands, 32);
    95        size_range = mpz_get_ui (bs) % 17 + 2;	/* 2..18 */
    96        mpz_urandomb (bs, rands, size_range);	/* 3..262144 bits */
    97        size = mpz_get_ui (bs);
    98        mpz_rrandomb (op1, rands, size);
    99  
   100        mpz_urandomb (bs, rands, 1);
   101        bsi = mpz_get_ui (bs);
   102        if ((bsi & 1) != 0)
   103  	mpz_neg (op1, op1);
   104  
   105        mpz_urandomb (bs, rands, 32);
   106        bsi = mpz_get_ui (bs);
   107        base = bsi % 62 + 1;
   108        if (base == 1)
   109  	base = 0;
   110  
   111        str = mpz_get_str ((char *) 0, base, op1);
   112        mpz_set_str_or_abort (op2, str, base);
   113  
   114        if (mpz_cmp (op1, op2))
   115  	{
   116  	  fprintf (stderr, "ERROR, op1 and op2 different in test %d\n", i);
   117  	  fprintf (stderr, "str  = %s\n", str);
   118  	  fprintf (stderr, "base = %d\n", base);
   119  	  fprintf (stderr, "op1  = "); debug_mp (op1, -16);
   120  	  fprintf (stderr, "op2  = "); debug_mp (op2, -16);
   121  	  abort ();
   122  	}
   123  
   124        (*__gmp_free_func) (str, strlen (str) + 1);
   125  
   126        /* 2. Generate random string and convert to mpz_t and back to a string
   127  	 again.  */
   128        mpz_urandomb (bs, rands, 32);
   129        size_range = mpz_get_ui (bs) % 16 + 1;	/* 1..16 */
   130        mpz_urandomb (bs, rands, size_range);	/* 1..65536 digits */
   131        len = mpz_get_ui (bs) + 1;
   132        buf = (char *) (*__gmp_allocate_func) (len + 1);
   133        if (base == 0)
   134  	base = 10;
   135        string_urandomb (buf, len, base, rands);
   136  
   137        mpz_set_str_or_abort (op1, buf, base);
   138        str = mpz_get_str ((char *) 0, base, op1);
   139  
   140        /* Skip over leading zeros, but don't leave the string at zero length. */
   141        for (bp = buf; bp[0] == '0' && bp[1] != '\0'; bp++)
   142  	;
   143  
   144        if (strcasecmp (str, bp) != 0)
   145  	{
   146  	  fprintf (stderr, "ERROR, str and buf different in test %d\n", i);
   147  	  fprintf (stderr, "str  = %s\n", str);
   148  	  fprintf (stderr, "buf  = %s\n", buf);
   149  	  fprintf (stderr, "base = %d\n", base);
   150  	  fprintf (stderr, "op1  = "); debug_mp (op1, -16);
   151  	  abort ();
   152  	}
   153  
   154        (*__gmp_free_func) (buf, len + 1);
   155        (*__gmp_free_func) (str, strlen (str) + 1);
   156      }
   157  
   158    mpz_clear (bs);
   159    mpz_clear (op1);
   160    mpz_clear (op2);
   161  
   162    tests_end ();
   163    exit (0);
   164  }
   165  
   166  void
   167  debug_mp (mpz_t x, int base)
   168  {
   169    mpz_out_str (stderr, base, x); fputc ('\n', stderr);
   170  }