Home | History | Annotate | Line # | Download | only in tests
      1      1.1  mrg /* Miscellaneous test program support routines.
      2      1.1  mrg 
      3  1.1.1.4  mrg Copyright 2000-2003, 2005, 2013, 2015, 2019 Free Software Foundation, Inc.
      4      1.1  mrg 
      5  1.1.1.2  mrg This file is part of the GNU MP Library test suite.
      6      1.1  mrg 
      7  1.1.1.2  mrg The GNU MP Library test suite is free software; you can redistribute it
      8  1.1.1.2  mrg and/or modify it under the terms of the GNU General Public License as
      9  1.1.1.2  mrg published by the Free Software Foundation; either version 3 of the License,
     10  1.1.1.2  mrg or (at your option) any later version.
     11  1.1.1.2  mrg 
     12  1.1.1.2  mrg The GNU MP Library test suite is distributed in the hope that it will be
     13  1.1.1.2  mrg useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1.1.2  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
     15  1.1.1.2  mrg Public License for more details.
     16      1.1  mrg 
     17  1.1.1.2  mrg You should have received a copy of the GNU General Public License along with
     18  1.1.1.3  mrg the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
     19      1.1  mrg 
     20      1.1  mrg #include "config.h"
     21      1.1  mrg 
     22      1.1  mrg #include <ctype.h>
     23      1.1  mrg #include <signal.h>
     24      1.1  mrg #include <stdio.h>
     25      1.1  mrg #include <stdlib.h>     /* for getenv */
     26      1.1  mrg #include <string.h>
     27      1.1  mrg 
     28      1.1  mrg #if HAVE_FLOAT_H
     29      1.1  mrg #include <float.h>      /* for DBL_MANT_DIG */
     30      1.1  mrg #endif
     31      1.1  mrg 
     32      1.1  mrg #if TIME_WITH_SYS_TIME
     33      1.1  mrg # include <sys/time.h>  /* for struct timeval */
     34      1.1  mrg # include <time.h>
     35      1.1  mrg #else
     36      1.1  mrg # if HAVE_SYS_TIME_H
     37      1.1  mrg #  include <sys/time.h>
     38      1.1  mrg # else
     39      1.1  mrg #  include <time.h>
     40      1.1  mrg # endif
     41      1.1  mrg #endif
     42      1.1  mrg 
     43      1.1  mrg #include "gmp-impl.h"
     44      1.1  mrg #include "tests.h"
     45      1.1  mrg 
     46      1.1  mrg 
     47      1.1  mrg /* The various tests setups and final checks, collected up together. */
     48      1.1  mrg void
     49      1.1  mrg tests_start (void)
     50      1.1  mrg {
     51  1.1.1.3  mrg   char version[10];
     52  1.1.1.5  mrg #if __STDC_VERSION__ >= 199901L
     53  1.1.1.5  mrg   snprintf (version, sizeof version, "%u.%u.%u",
     54  1.1.1.3  mrg 	    __GNU_MP_VERSION,
     55  1.1.1.3  mrg 	    __GNU_MP_VERSION_MINOR,
     56  1.1.1.3  mrg 	    __GNU_MP_VERSION_PATCHLEVEL);
     57  1.1.1.5  mrg #else
     58  1.1.1.5  mrg   sprintf (version, "%u.%u.%u",
     59  1.1.1.5  mrg 	    __GNU_MP_VERSION,
     60  1.1.1.5  mrg 	    __GNU_MP_VERSION_MINOR,
     61  1.1.1.5  mrg 	    __GNU_MP_VERSION_PATCHLEVEL);
     62  1.1.1.5  mrg #endif
     63  1.1.1.3  mrg 
     64  1.1.1.3  mrg   if (strcmp (gmp_version, version) != 0)
     65  1.1.1.3  mrg     {
     66  1.1.1.3  mrg       fprintf (stderr, "tests are not linked to the newly compiled library\n");
     67  1.1.1.3  mrg       fprintf (stderr, "  local version is: %s\n", version);
     68  1.1.1.3  mrg       fprintf (stderr, "  linked version is: %s\n", gmp_version);
     69  1.1.1.3  mrg       abort ();
     70  1.1.1.3  mrg     }
     71  1.1.1.3  mrg 
     72      1.1  mrg   /* don't buffer, so output is not lost if a test causes a segv etc */
     73      1.1  mrg   setbuf (stdout, NULL);
     74      1.1  mrg   setbuf (stderr, NULL);
     75      1.1  mrg 
     76      1.1  mrg   tests_memory_start ();
     77      1.1  mrg   tests_rand_start ();
     78      1.1  mrg }
     79      1.1  mrg void
     80      1.1  mrg tests_end (void)
     81      1.1  mrg {
     82      1.1  mrg   tests_rand_end ();
     83      1.1  mrg   tests_memory_end ();
     84      1.1  mrg }
     85      1.1  mrg 
     86  1.1.1.4  mrg static void
     87  1.1.1.4  mrg seed_from_tod (gmp_randstate_ptr  rands)
     88  1.1.1.4  mrg {
     89  1.1.1.4  mrg   unsigned long seed;
     90  1.1.1.4  mrg #if HAVE_GETTIMEOFDAY
     91  1.1.1.4  mrg   struct timeval  tv;
     92  1.1.1.4  mrg   gettimeofday (&tv, NULL);
     93  1.1.1.4  mrg   seed = tv.tv_sec ^ ((unsigned long) tv.tv_usec << 12);
     94  1.1.1.4  mrg   seed &= 0xffffffff;
     95  1.1.1.4  mrg #else
     96  1.1.1.4  mrg   time_t  tv;
     97  1.1.1.4  mrg   time (&tv);
     98  1.1.1.4  mrg   seed = tv;
     99  1.1.1.4  mrg #endif
    100  1.1.1.4  mrg   gmp_randseed_ui (rands, seed);
    101  1.1.1.4  mrg   printf ("Seed GMP_CHECK_RANDOMIZE=%lu (include this in bug reports)\n", seed);
    102  1.1.1.4  mrg }
    103  1.1.1.4  mrg 
    104  1.1.1.4  mrg static void
    105  1.1.1.4  mrg seed_from_urandom (gmp_randstate_ptr rands, FILE *fs)
    106  1.1.1.4  mrg {
    107  1.1.1.4  mrg   mpz_t seed;
    108  1.1.1.4  mrg   unsigned char buf[6];
    109  1.1.1.4  mrg   fread (buf, 1, 6, fs);
    110  1.1.1.4  mrg   mpz_init (seed);
    111  1.1.1.4  mrg   mpz_import (seed, 6, 1, 1, 0, 0, buf);
    112  1.1.1.4  mrg   gmp_randseed (rands, seed);
    113  1.1.1.4  mrg   gmp_printf ("Seed GMP_CHECK_RANDOMIZE=%Zd (include this in bug reports)\n", seed);
    114  1.1.1.4  mrg   mpz_clear (seed);
    115  1.1.1.4  mrg }
    116      1.1  mrg 
    117      1.1  mrg void
    118      1.1  mrg tests_rand_start (void)
    119      1.1  mrg {
    120      1.1  mrg   gmp_randstate_ptr  rands;
    121  1.1.1.4  mrg   char           *seed_string;
    122      1.1  mrg 
    123      1.1  mrg   if (__gmp_rands_initialized)
    124      1.1  mrg     {
    125      1.1  mrg       printf ("Please let tests_start() initialize the global __gmp_rands.\n");
    126      1.1  mrg       printf ("ie. ensure that function is called before the first use of RANDS.\n");
    127      1.1  mrg       abort ();
    128      1.1  mrg     }
    129      1.1  mrg 
    130      1.1  mrg   gmp_randinit_default (__gmp_rands);
    131      1.1  mrg   __gmp_rands_initialized = 1;
    132      1.1  mrg   rands = __gmp_rands;
    133      1.1  mrg 
    134  1.1.1.4  mrg   seed_string = getenv ("GMP_CHECK_RANDOMIZE");
    135  1.1.1.4  mrg   if (seed_string != NULL)
    136      1.1  mrg     {
    137  1.1.1.4  mrg       if (strcmp (seed_string, "0") != 0 &&
    138  1.1.1.4  mrg 	  strcmp (seed_string, "1") != 0)
    139      1.1  mrg         {
    140  1.1.1.4  mrg 	  mpz_t seed;
    141  1.1.1.4  mrg 	  mpz_init_set_str (seed, seed_string, 0);
    142  1.1.1.4  mrg           gmp_printf ("Re-seeding with GMP_CHECK_RANDOMIZE=%Zd\n", seed);
    143  1.1.1.4  mrg           gmp_randseed (rands, seed);
    144  1.1.1.4  mrg 	  mpz_clear (seed);
    145      1.1  mrg         }
    146      1.1  mrg       else
    147      1.1  mrg         {
    148  1.1.1.4  mrg 	  FILE *fs = fopen ("/dev/urandom", "r");
    149  1.1.1.4  mrg 	  if (fs != NULL)
    150  1.1.1.4  mrg 	    {
    151  1.1.1.4  mrg 	      seed_from_urandom (rands, fs);
    152  1.1.1.4  mrg 	      fclose (fs);
    153  1.1.1.4  mrg 	    }
    154  1.1.1.4  mrg 	  else
    155  1.1.1.4  mrg 	    seed_from_tod (rands);
    156      1.1  mrg         }
    157      1.1  mrg       fflush (stdout);
    158      1.1  mrg     }
    159      1.1  mrg }
    160      1.1  mrg void
    161      1.1  mrg tests_rand_end (void)
    162      1.1  mrg {
    163      1.1  mrg   RANDS_CLEAR ();
    164      1.1  mrg }
    165      1.1  mrg 
    166      1.1  mrg 
    167      1.1  mrg /* Only used if CPU calling conventions checking is available. */
    168  1.1.1.2  mrg mp_limb_t (*calling_conventions_function) (ANYARGS);
    169      1.1  mrg 
    170      1.1  mrg 
    171      1.1  mrg /* Return p advanced to the next multiple of "align" bytes.  "align" must be
    172      1.1  mrg    a power of 2.  Care is taken not to assume sizeof(int)==sizeof(pointer).
    173      1.1  mrg    Using "unsigned long" avoids a warning on hpux.  */
    174      1.1  mrg void *
    175      1.1  mrg align_pointer (void *p, size_t align)
    176      1.1  mrg {
    177      1.1  mrg   gmp_intptr_t d;
    178      1.1  mrg   d = ((gmp_intptr_t) p) & (align-1);
    179      1.1  mrg   d = (d != 0 ? align-d : 0);
    180      1.1  mrg   return (void *) (((char *) p) + d);
    181      1.1  mrg }
    182      1.1  mrg 
    183      1.1  mrg 
    184      1.1  mrg /* Note that memory allocated with this function can never be freed, because
    185      1.1  mrg    the start address of the block allocated is lost. */
    186      1.1  mrg void *
    187      1.1  mrg __gmp_allocate_func_aligned (size_t bytes, size_t align)
    188      1.1  mrg {
    189      1.1  mrg   return align_pointer ((*__gmp_allocate_func) (bytes + align-1), align);
    190      1.1  mrg }
    191      1.1  mrg 
    192      1.1  mrg 
    193      1.1  mrg void *
    194      1.1  mrg __gmp_allocate_or_reallocate (void *ptr, size_t oldsize, size_t newsize)
    195      1.1  mrg {
    196      1.1  mrg   if (ptr == NULL)
    197      1.1  mrg     return (*__gmp_allocate_func) (newsize);
    198      1.1  mrg   else
    199      1.1  mrg     return (*__gmp_reallocate_func) (ptr, oldsize, newsize);
    200      1.1  mrg }
    201      1.1  mrg 
    202      1.1  mrg char *
    203      1.1  mrg __gmp_allocate_strdup (const char *s)
    204      1.1  mrg {
    205      1.1  mrg   size_t  len;
    206      1.1  mrg   char    *t;
    207      1.1  mrg   len = strlen (s);
    208  1.1.1.2  mrg   t = (char *) (*__gmp_allocate_func) (len+1);
    209      1.1  mrg   memcpy (t, s, len+1);
    210      1.1  mrg   return t;
    211      1.1  mrg }
    212      1.1  mrg 
    213      1.1  mrg 
    214      1.1  mrg char *
    215      1.1  mrg strtoupper (char *s_orig)
    216      1.1  mrg {
    217      1.1  mrg   char  *s;
    218      1.1  mrg   for (s = s_orig; *s != '\0'; s++)
    219  1.1.1.4  mrg     if (islower (*s))
    220      1.1  mrg       *s = toupper (*s);
    221      1.1  mrg   return s_orig;
    222      1.1  mrg }
    223      1.1  mrg 
    224      1.1  mrg 
    225      1.1  mrg void
    226      1.1  mrg mpz_set_n (mpz_ptr z, mp_srcptr p, mp_size_t size)
    227      1.1  mrg {
    228      1.1  mrg   ASSERT (size >= 0);
    229      1.1  mrg   MPN_NORMALIZE (p, size);
    230      1.1  mrg   MPZ_REALLOC (z, size);
    231      1.1  mrg   MPN_COPY (PTR(z), p, size);
    232      1.1  mrg   SIZ(z) = size;
    233      1.1  mrg }
    234      1.1  mrg 
    235      1.1  mrg void
    236      1.1  mrg mpz_init_set_n (mpz_ptr z, mp_srcptr p, mp_size_t size)
    237      1.1  mrg {
    238      1.1  mrg   ASSERT (size >= 0);
    239      1.1  mrg 
    240      1.1  mrg   MPN_NORMALIZE (p, size);
    241      1.1  mrg   ALLOC(z) = MAX (size, 1);
    242      1.1  mrg   PTR(z) = __GMP_ALLOCATE_FUNC_LIMBS (ALLOC(z));
    243      1.1  mrg   SIZ(z) = size;
    244      1.1  mrg   MPN_COPY (PTR(z), p, size);
    245      1.1  mrg }
    246      1.1  mrg 
    247      1.1  mrg 
    248      1.1  mrg /* Find least significant limb position where p1,size and p2,size differ.  */
    249      1.1  mrg mp_size_t
    250      1.1  mrg mpn_diff_lowest (mp_srcptr p1, mp_srcptr p2, mp_size_t size)
    251      1.1  mrg {
    252      1.1  mrg   mp_size_t  i;
    253      1.1  mrg 
    254      1.1  mrg   for (i = 0; i < size; i++)
    255      1.1  mrg     if (p1[i] != p2[i])
    256      1.1  mrg       return i;
    257      1.1  mrg 
    258      1.1  mrg   /* no differences */
    259      1.1  mrg   return -1;
    260      1.1  mrg }
    261      1.1  mrg 
    262      1.1  mrg 
    263      1.1  mrg /* Find most significant limb position where p1,size and p2,size differ.  */
    264      1.1  mrg mp_size_t
    265      1.1  mrg mpn_diff_highest (mp_srcptr p1, mp_srcptr p2, mp_size_t size)
    266      1.1  mrg {
    267      1.1  mrg   mp_size_t  i;
    268      1.1  mrg 
    269      1.1  mrg   for (i = size-1; i >= 0; i--)
    270      1.1  mrg     if (p1[i] != p2[i])
    271      1.1  mrg       return i;
    272      1.1  mrg 
    273      1.1  mrg   /* no differences */
    274      1.1  mrg   return -1;
    275      1.1  mrg }
    276      1.1  mrg 
    277      1.1  mrg 
    278      1.1  mrg /* Find least significant byte position where p1,size and p2,size differ.  */
    279      1.1  mrg mp_size_t
    280      1.1  mrg byte_diff_lowest (const void *p1, const void *p2, mp_size_t size)
    281      1.1  mrg {
    282      1.1  mrg   mp_size_t  i;
    283      1.1  mrg 
    284      1.1  mrg   for (i = 0; i < size; i++)
    285      1.1  mrg     if (((const char *) p1)[i] != ((const char *) p2)[i])
    286      1.1  mrg       return i;
    287      1.1  mrg 
    288      1.1  mrg   /* no differences */
    289      1.1  mrg   return -1;
    290      1.1  mrg }
    291      1.1  mrg 
    292      1.1  mrg 
    293  1.1.1.4  mrg /* Find most significant byte position where p1,size and p2,size differ.  */
    294      1.1  mrg mp_size_t
    295      1.1  mrg byte_diff_highest (const void *p1, const void *p2, mp_size_t size)
    296      1.1  mrg {
    297      1.1  mrg   mp_size_t  i;
    298      1.1  mrg 
    299      1.1  mrg   for (i = size-1; i >= 0; i--)
    300      1.1  mrg     if (((const char *) p1)[i] != ((const char *) p2)[i])
    301      1.1  mrg       return i;
    302      1.1  mrg 
    303      1.1  mrg   /* no differences */
    304      1.1  mrg   return -1;
    305      1.1  mrg }
    306      1.1  mrg 
    307      1.1  mrg 
    308      1.1  mrg void
    309      1.1  mrg mpz_set_str_or_abort (mpz_ptr z, const char *str, int base)
    310      1.1  mrg {
    311      1.1  mrg   if (mpz_set_str (z, str, base) != 0)
    312      1.1  mrg     {
    313      1.1  mrg       fprintf (stderr, "ERROR: mpz_set_str failed\n");
    314      1.1  mrg       fprintf (stderr, "   str  = \"%s\"\n", str);
    315      1.1  mrg       fprintf (stderr, "   base = %d\n", base);
    316      1.1  mrg       abort();
    317      1.1  mrg     }
    318      1.1  mrg }
    319      1.1  mrg 
    320      1.1  mrg void
    321      1.1  mrg mpq_set_str_or_abort (mpq_ptr q, const char *str, int base)
    322      1.1  mrg {
    323      1.1  mrg   if (mpq_set_str (q, str, base) != 0)
    324      1.1  mrg     {
    325      1.1  mrg       fprintf (stderr, "ERROR: mpq_set_str failed\n");
    326      1.1  mrg       fprintf (stderr, "   str  = \"%s\"\n", str);
    327      1.1  mrg       fprintf (stderr, "   base = %d\n", base);
    328      1.1  mrg       abort();
    329      1.1  mrg     }
    330      1.1  mrg }
    331      1.1  mrg 
    332      1.1  mrg void
    333      1.1  mrg mpf_set_str_or_abort (mpf_ptr f, const char *str, int base)
    334      1.1  mrg {
    335      1.1  mrg   if (mpf_set_str (f, str, base) != 0)
    336      1.1  mrg     {
    337      1.1  mrg       fprintf (stderr, "ERROR mpf_set_str failed\n");
    338      1.1  mrg       fprintf (stderr, "   str  = \"%s\"\n", str);
    339      1.1  mrg       fprintf (stderr, "   base = %d\n", base);
    340      1.1  mrg       abort();
    341      1.1  mrg     }
    342      1.1  mrg }
    343      1.1  mrg 
    344      1.1  mrg 
    345      1.1  mrg /* Whether the absolute value of z is a power of 2. */
    346      1.1  mrg int
    347      1.1  mrg mpz_pow2abs_p (mpz_srcptr z)
    348      1.1  mrg {
    349      1.1  mrg   mp_size_t  size, i;
    350      1.1  mrg   mp_srcptr  ptr;
    351      1.1  mrg 
    352      1.1  mrg   size = SIZ (z);
    353      1.1  mrg   if (size == 0)
    354      1.1  mrg     return 0;  /* zero is not a power of 2 */
    355      1.1  mrg   size = ABS (size);
    356      1.1  mrg 
    357      1.1  mrg   ptr = PTR (z);
    358      1.1  mrg   for (i = 0; i < size-1; i++)
    359      1.1  mrg     if (ptr[i] != 0)
    360      1.1  mrg       return 0;  /* non-zero low limb means not a power of 2 */
    361      1.1  mrg 
    362      1.1  mrg   return POW2_P (ptr[i]);  /* high limb power of 2 */
    363      1.1  mrg }
    364      1.1  mrg 
    365      1.1  mrg 
    366      1.1  mrg /* Exponentially distributed between 0 and 2^nbits-1, meaning the number of
    367      1.1  mrg    bits in the result is uniformly distributed between 0 and nbits-1.
    368      1.1  mrg 
    369      1.1  mrg    FIXME: This is not a proper exponential distribution, since the
    370      1.1  mrg    probability function will have a stepped shape due to using a uniform
    371      1.1  mrg    distribution after choosing how many bits.  */
    372      1.1  mrg 
    373      1.1  mrg void
    374      1.1  mrg mpz_erandomb (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits)
    375      1.1  mrg {
    376      1.1  mrg   mpz_urandomb (rop, rstate, gmp_urandomm_ui (rstate, nbits));
    377      1.1  mrg }
    378      1.1  mrg 
    379      1.1  mrg void
    380      1.1  mrg mpz_erandomb_nonzero (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits)
    381      1.1  mrg {
    382      1.1  mrg   mpz_erandomb (rop, rstate, nbits);
    383      1.1  mrg   if (mpz_sgn (rop) == 0)
    384      1.1  mrg     mpz_set_ui (rop, 1L);
    385      1.1  mrg }
    386      1.1  mrg 
    387      1.1  mrg void
    388      1.1  mrg mpz_errandomb (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits)
    389      1.1  mrg {
    390      1.1  mrg   mpz_rrandomb (rop, rstate, gmp_urandomm_ui (rstate, nbits));
    391      1.1  mrg }
    392      1.1  mrg 
    393      1.1  mrg void
    394      1.1  mrg mpz_errandomb_nonzero (mpz_ptr rop, gmp_randstate_t rstate, unsigned long nbits)
    395      1.1  mrg {
    396      1.1  mrg   mpz_errandomb (rop, rstate, nbits);
    397      1.1  mrg   if (mpz_sgn (rop) == 0)
    398      1.1  mrg     mpz_set_ui (rop, 1L);
    399      1.1  mrg }
    400      1.1  mrg 
    401      1.1  mrg void
    402      1.1  mrg mpz_negrandom (mpz_ptr rop, gmp_randstate_t rstate)
    403      1.1  mrg {
    404      1.1  mrg   mp_limb_t  n;
    405      1.1  mrg   _gmp_rand (&n, rstate, 1);
    406      1.1  mrg   if (n != 0)
    407      1.1  mrg     mpz_neg (rop, rop);
    408      1.1  mrg }
    409      1.1  mrg 
    410  1.1.1.4  mrg void
    411  1.1.1.4  mrg mpz_clobber(mpz_ptr rop)
    412  1.1.1.4  mrg {
    413  1.1.1.4  mrg   MPN_ZERO(PTR(rop), ALLOC(rop));
    414  1.1.1.4  mrg   PTR(rop)[0] = 0xDEADBEEF;
    415  1.1.1.4  mrg   SIZ(rop) = 0xDEFACE;
    416  1.1.1.4  mrg }
    417  1.1.1.4  mrg 
    418      1.1  mrg mp_limb_t
    419      1.1  mrg urandom (void)
    420      1.1  mrg {
    421      1.1  mrg #if GMP_NAIL_BITS == 0
    422      1.1  mrg   mp_limb_t  n;
    423      1.1  mrg   _gmp_rand (&n, RANDS, GMP_LIMB_BITS);
    424      1.1  mrg   return n;
    425      1.1  mrg #else
    426      1.1  mrg   mp_limb_t n[2];
    427      1.1  mrg   _gmp_rand (n, RANDS, GMP_LIMB_BITS);
    428      1.1  mrg   return n[0] + (n[1] << GMP_NUMB_BITS);
    429      1.1  mrg #endif
    430      1.1  mrg }
    431      1.1  mrg 
    432      1.1  mrg 
    433      1.1  mrg /* Call (*func)() with various random number generators. */
    434      1.1  mrg void
    435  1.1.1.2  mrg call_rand_algs (void (*func) (const char *, gmp_randstate_ptr))
    436      1.1  mrg {
    437      1.1  mrg   gmp_randstate_t  rstate;
    438      1.1  mrg   mpz_t            a;
    439      1.1  mrg 
    440      1.1  mrg   mpz_init (a);
    441      1.1  mrg 
    442      1.1  mrg   gmp_randinit_default (rstate);
    443      1.1  mrg   (*func) ("gmp_randinit_default", rstate);
    444      1.1  mrg   gmp_randclear (rstate);
    445      1.1  mrg 
    446      1.1  mrg   gmp_randinit_mt (rstate);
    447      1.1  mrg   (*func) ("gmp_randinit_mt", rstate);
    448      1.1  mrg   gmp_randclear (rstate);
    449      1.1  mrg 
    450      1.1  mrg   gmp_randinit_lc_2exp_size (rstate, 8L);
    451      1.1  mrg   (*func) ("gmp_randinit_lc_2exp_size 8", rstate);
    452      1.1  mrg   gmp_randclear (rstate);
    453      1.1  mrg 
    454      1.1  mrg   gmp_randinit_lc_2exp_size (rstate, 16L);
    455      1.1  mrg   (*func) ("gmp_randinit_lc_2exp_size 16", rstate);
    456      1.1  mrg   gmp_randclear (rstate);
    457      1.1  mrg 
    458      1.1  mrg   gmp_randinit_lc_2exp_size (rstate, 128L);
    459      1.1  mrg   (*func) ("gmp_randinit_lc_2exp_size 128", rstate);
    460      1.1  mrg   gmp_randclear (rstate);
    461      1.1  mrg 
    462      1.1  mrg   /* degenerate always zeros */
    463      1.1  mrg   mpz_set_ui (a, 0L);
    464      1.1  mrg   gmp_randinit_lc_2exp (rstate, a, 0L, 8L);
    465      1.1  mrg   (*func) ("gmp_randinit_lc_2exp a=0 c=0 m=8", rstate);
    466      1.1  mrg   gmp_randclear (rstate);
    467      1.1  mrg 
    468      1.1  mrg   /* degenerate always FFs */
    469      1.1  mrg   mpz_set_ui (a, 0L);
    470      1.1  mrg   gmp_randinit_lc_2exp (rstate, a, 0xFFL, 8L);
    471      1.1  mrg   (*func) ("gmp_randinit_lc_2exp a=0 c=0xFF m=8", rstate);
    472      1.1  mrg   gmp_randclear (rstate);
    473      1.1  mrg 
    474      1.1  mrg   mpz_clear (a);
    475      1.1  mrg }
    476      1.1  mrg 
    477      1.1  mrg 
    478      1.1  mrg /* Return +infinity if available, or 0 if not.
    479      1.1  mrg    We don't want to use libm, so INFINITY or other system values are not
    480      1.1  mrg    used here.  */
    481      1.1  mrg double
    482      1.1  mrg tests_infinity_d (void)
    483      1.1  mrg {
    484      1.1  mrg #if _GMP_IEEE_FLOATS
    485      1.1  mrg   union ieee_double_extract x;
    486      1.1  mrg   x.s.exp = 2047;
    487      1.1  mrg   x.s.manl = 0;
    488      1.1  mrg   x.s.manh = 0;
    489      1.1  mrg   x.s.sig = 0;
    490      1.1  mrg   return x.d;
    491      1.1  mrg #else
    492      1.1  mrg   return 0;
    493      1.1  mrg #endif
    494      1.1  mrg }
    495      1.1  mrg 
    496      1.1  mrg 
    497      1.1  mrg /* Return non-zero if d is an infinity (either positive or negative).
    498      1.1  mrg    Don't want libm, so don't use isinf() or other system tests.  */
    499      1.1  mrg int
    500      1.1  mrg tests_isinf (double d)
    501      1.1  mrg {
    502      1.1  mrg #if _GMP_IEEE_FLOATS
    503      1.1  mrg   union ieee_double_extract x;
    504      1.1  mrg   x.d = d;
    505      1.1  mrg   return (x.s.exp == 2047 && x.s.manl == 0 && x.s.manh == 0);
    506      1.1  mrg #else
    507      1.1  mrg   return 0;
    508      1.1  mrg #endif
    509      1.1  mrg }
    510      1.1  mrg 
    511      1.1  mrg 
    512      1.1  mrg /* Set the hardware floating point rounding mode.  Same mode values as mpfr,
    513      1.1  mrg    namely 0=nearest, 1=tozero, 2=up, 3=down.  Return 1 if successful, 0 if
    514      1.1  mrg    not.  */
    515      1.1  mrg int
    516      1.1  mrg tests_hardware_setround (int mode)
    517      1.1  mrg {
    518  1.1.1.3  mrg #if ! defined NO_ASM && HAVE_HOST_CPU_FAMILY_x86
    519      1.1  mrg   int  rc;
    520      1.1  mrg   switch (mode) {
    521      1.1  mrg   case 0: rc = 0; break;  /* nearest */
    522      1.1  mrg   case 1: rc = 3; break;  /* tozero  */
    523      1.1  mrg   case 2: rc = 2; break;  /* up      */
    524      1.1  mrg   case 3: rc = 1; break;  /* down    */
    525      1.1  mrg   default:
    526      1.1  mrg     return 0;
    527      1.1  mrg   }
    528      1.1  mrg   x86_fldcw ((x86_fstcw () & ~0xC00) | (rc << 10));
    529      1.1  mrg   return 1;
    530      1.1  mrg #endif
    531      1.1  mrg 
    532      1.1  mrg   return 0;
    533      1.1  mrg }
    534      1.1  mrg 
    535      1.1  mrg /* Return the hardware floating point rounding mode, or -1 if unknown. */
    536      1.1  mrg int
    537      1.1  mrg tests_hardware_getround (void)
    538      1.1  mrg {
    539  1.1.1.3  mrg #if ! defined NO_ASM && HAVE_HOST_CPU_FAMILY_x86
    540      1.1  mrg   switch ((x86_fstcw () & ~0xC00) >> 10) {
    541      1.1  mrg   case 0: return 0; break;  /* nearest */
    542      1.1  mrg   case 1: return 3; break;  /* down    */
    543      1.1  mrg   case 2: return 2; break;  /* up      */
    544      1.1  mrg   case 3: return 1; break;  /* tozero  */
    545      1.1  mrg   }
    546      1.1  mrg #endif
    547      1.1  mrg 
    548      1.1  mrg   return -1;
    549      1.1  mrg }
    550      1.1  mrg 
    551      1.1  mrg 
    552      1.1  mrg /* tests_dbl_mant_bits() determines by experiment the number of bits in the
    553      1.1  mrg    mantissa of a "double".  If it's not possible to find a value (perhaps
    554      1.1  mrg    due to the compiler optimizing too aggressively), then return 0.
    555      1.1  mrg 
    556      1.1  mrg    This code is used rather than DBL_MANT_DIG from <float.h> since ancient
    557      1.1  mrg    systems like SunOS don't have that file, and since one GNU/Linux ARM
    558      1.1  mrg    system was seen where the float emulation seemed to have only 32 working
    559      1.1  mrg    bits, not the 53 float.h claimed.  */
    560      1.1  mrg 
    561      1.1  mrg int
    562      1.1  mrg tests_dbl_mant_bits (void)
    563      1.1  mrg {
    564      1.1  mrg   static int n = -1;
    565      1.1  mrg   volatile double x, y, d;
    566      1.1  mrg 
    567      1.1  mrg   if (n != -1)
    568      1.1  mrg     return n;
    569      1.1  mrg 
    570      1.1  mrg   n = 1;
    571      1.1  mrg   x = 2.0;
    572      1.1  mrg   for (;;)
    573      1.1  mrg     {
    574      1.1  mrg       /* see if 2^(n+1)+1 can be formed without rounding, if so then
    575      1.1  mrg          continue, if not then "n" is the answer */
    576      1.1  mrg       y = x + 1.0;
    577      1.1  mrg       d = y - x;
    578      1.1  mrg       if (d != 1.0)
    579      1.1  mrg         {
    580      1.1  mrg #if defined (DBL_MANT_DIG) && DBL_RADIX == 2
    581      1.1  mrg           if (n != DBL_MANT_DIG)
    582      1.1  mrg             printf ("Warning, tests_dbl_mant_bits got %d but DBL_MANT_DIG says %d\n", n, DBL_MANT_DIG);
    583      1.1  mrg #endif
    584      1.1  mrg           break;
    585      1.1  mrg         }
    586      1.1  mrg 
    587      1.1  mrg       x *= 2;
    588      1.1  mrg       n++;
    589      1.1  mrg 
    590      1.1  mrg       if (n > 1000)
    591      1.1  mrg         {
    592      1.1  mrg           printf ("Oops, tests_dbl_mant_bits can't determine mantissa size\n");
    593      1.1  mrg           n = 0;
    594      1.1  mrg           break;
    595      1.1  mrg         }
    596      1.1  mrg     }
    597      1.1  mrg   return n;
    598      1.1  mrg }
    599      1.1  mrg 
    600      1.1  mrg 
    601      1.1  mrg /* See tests_setjmp_sigfpe in tests.h. */
    602      1.1  mrg 
    603      1.1  mrg jmp_buf    tests_sigfpe_target;
    604      1.1  mrg 
    605      1.1  mrg RETSIGTYPE
    606      1.1  mrg tests_sigfpe_handler (int sig)
    607      1.1  mrg {
    608      1.1  mrg   longjmp (tests_sigfpe_target, 1);
    609      1.1  mrg }
    610      1.1  mrg 
    611      1.1  mrg void
    612      1.1  mrg tests_sigfpe_done (void)
    613      1.1  mrg {
    614      1.1  mrg   signal (SIGFPE, SIG_DFL);
    615      1.1  mrg }
    616