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

     1  /* Test mpz_pow_ui and mpz_ui_pow_ui.
     2  
     3  Copyright 1997, 1999-2001 Free Software Foundation, Inc.
     4  
     5  This file is part of the GNU MP Library test suite.
     6  
     7  The GNU MP Library test suite is free software; you can redistribute it
     8  and/or modify it under the terms of the GNU General Public License as
     9  published by the Free Software Foundation; either version 3 of the License,
    10  or (at your option) any later version.
    11  
    12  The GNU MP Library test suite is distributed in the hope that it will be
    13  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
    15  Public License for more details.
    16  
    17  You should have received a copy of the GNU General Public License along with
    18  the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
    19  
    20  #include <stdio.h>
    21  #include <stdlib.h>
    22  
    23  #include "gmp.h"
    24  #include "gmp-impl.h"
    25  #include "tests.h"
    26  
    27  
    28  void
    29  check_one (mpz_srcptr want, mpz_srcptr base, unsigned long exp)
    30  {
    31    mpz_t  got;
    32  
    33    mpz_init (got);
    34  
    35    MPZ_CHECK_FORMAT (want);
    36  
    37    mpz_pow_ui (got, base, exp);
    38    if (mpz_cmp (got, want))
    39      {
    40        printf ("mpz_pow_ui wrong\n");
    41        mpz_trace ("  base", base);
    42        printf    ("  exp = %lu (0x%lX)\n", exp, exp);
    43        mpz_trace ("  got ", got);
    44        mpz_trace ("  want", want);
    45        abort ();
    46      }
    47  
    48    mpz_set (got, base);
    49    mpz_pow_ui (got, got, exp);
    50    if (mpz_cmp (got, want))
    51      {
    52        printf ("mpz_pow_ui wrong\n");
    53        mpz_trace ("  base", base);
    54        printf    ("  exp = %lu (0x%lX)\n", exp, exp);
    55        mpz_trace ("  got ", got);
    56        mpz_trace ("  want", want);
    57        abort ();
    58      }
    59  
    60    if (mpz_fits_ulong_p (base))
    61      {
    62        unsigned long  base_u = mpz_get_ui (base);
    63        mpz_ui_pow_ui (got, base_u, exp);
    64        if (mpz_cmp (got, want))
    65  	{
    66  	  printf    ("mpz_ui_pow_ui wrong\n");
    67  	  printf    ("  base=%lu (0x%lX)\n", base_u, base_u);
    68  	  printf    ("  exp = %lu (0x%lX)\n", exp, exp);
    69  	  mpz_trace ("  got ", got);
    70  	  mpz_trace ("  want", want);
    71  	  abort ();
    72  	}
    73      }
    74  
    75    mpz_clear (got);
    76  }
    77  
    78  void
    79  check_base (mpz_srcptr base)
    80  {
    81    unsigned long  exp;
    82    mpz_t          want;
    83  
    84    mpz_init (want);
    85    mpz_set_ui (want, 1L);
    86  
    87    for (exp = 0; exp < 20; exp++)
    88      {
    89        check_one (want, base, exp);
    90        mpz_mul (want, want, base);
    91      }
    92  
    93    mpz_clear (want);
    94  }
    95  
    96  void
    97  check_various (void)
    98  {
    99    static const struct {
   100      const char *base;
   101    } data[] = {
   102      { "0" },
   103      { "1" },
   104      { "2" },
   105      { "3" },
   106      { "4" },
   107      { "5" },
   108      { "6" },
   109      { "10" },
   110      { "15" },
   111      { "16" },
   112  
   113      { "0x1F" },
   114      { "0xFF" },
   115      { "0x1001" },
   116      { "0xFFFF" },
   117      { "0x10000001" },
   118      { "0x1000000000000001" },
   119  
   120      /* actual size closest to estimate */
   121      { "0xFFFFFFFF" },
   122      { "0xFFFFFFFFFFFFFFFF" },
   123  
   124      /* same after rshift */
   125      { "0xFFFFFFFF0" },
   126      { "0xFFFFFFFF00" },
   127      { "0xFFFFFFFFFFFFFFFF0" },
   128      { "0xFFFFFFFFFFFFFFFF00" },
   129  
   130      /* change from 2 limbs to 1 after rshift */
   131      { "0x180000000" },
   132      { "0x18000000000000000" },
   133  
   134      /* change from 3 limbs to 2 after rshift */
   135      { "0x18000000100000000" },
   136      { "0x180000000000000010000000000000000" },
   137  
   138      /* handling of absolute value */
   139      { "-0x80000000" },
   140      { "-0x8000000000000000" },
   141  
   142      /* low zero limb, and size>2, checking argument overlap detection */
   143      { "0x3000000000000000300000000000000030000000000000000" },
   144    };
   145  
   146    mpz_t  base;
   147    int    i;
   148  
   149    mpz_init (base);
   150  
   151    for (i = 0; i < numberof (data); i++)
   152      {
   153        mpz_set_str_or_abort (base, data[i].base, 0);
   154        check_base (base);
   155      }
   156  
   157    mpz_clear (base);
   158  }
   159  
   160  void
   161  check_random (int reps)
   162  {
   163    mpz_t              base, want;
   164    mp_size_t          base_size;
   165    int                i;
   166    unsigned long      size_range, exp;
   167    gmp_randstate_ptr  rands = RANDS;
   168  
   169    mpz_init (base);
   170    mpz_init (want);
   171  
   172    for (i = 0; i < reps; i++)
   173      {
   174        /* exponentially random 0 to 2^13 bits for base */
   175        mpz_urandomb (want, rands, 32);
   176        size_range = mpz_get_ui (want) % 12 + 2;
   177        mpz_urandomb (want, rands, size_range);
   178        base_size = mpz_get_ui (want);
   179        mpz_rrandomb (base, rands, base_size);
   180  
   181        /* randomly signed base */
   182        mpz_urandomb (want, rands, 2);
   183        if ((mpz_get_ui (want) & 1) != 0)
   184  	mpz_neg (base, base);
   185  
   186        /* random 5 bits for exponent */
   187        mpz_urandomb (want, rands, 5L);
   188        exp = mpz_get_ui (want);
   189  
   190        refmpz_pow_ui (want, base, exp);
   191        check_one (want, base, exp);
   192      }
   193  
   194    mpz_clear (base);
   195    mpz_clear (want);
   196  }
   197  
   198  int
   199  main (int argc, char **argv)
   200  {
   201    int reps = 5000;
   202  
   203    /* dummy call to drag in refmpn.o for testing mpz/n_pow_ui.c with
   204       refmpn_mul_2 */
   205    refmpn_zero_p (NULL, (mp_size_t) 0);
   206  
   207    tests_start ();
   208    mp_trace_base = -16;
   209  
   210    if (argc == 2)
   211       reps = atoi (argv[1]);
   212  
   213    check_various ();
   214    check_random (reps);
   215  
   216    tests_end ();
   217    exit (0);
   218  }