Home | History | Annotate | Line # | Download | only in mpn
t-get_d.c revision 1.1.1.2
      1      1.1  mrg /* Test mpn_get_d.
      2      1.1  mrg 
      3      1.1  mrg Copyright 2002, 2003, 2004 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.2  mrg the GNU MP Library test suite.  If not, see http://www.gnu.org/licenses/.  */
     19      1.1  mrg 
     20      1.1  mrg /* Note that we don't use <limits.h> for LONG_MIN, but instead our own
     21      1.1  mrg    definition in gmp-impl.h.  In gcc 2.95.4 (debian 3.0) under
     22      1.1  mrg    -mcpu=ultrasparc, limits.h sees __sparc_v9__ defined and assumes that
     23      1.1  mrg    means long is 64-bit long, but it's only 32-bits, causing fatal compile
     24      1.1  mrg    errors.  */
     25      1.1  mrg 
     26      1.1  mrg #include "config.h"
     27      1.1  mrg 
     28      1.1  mrg #include <setjmp.h>
     29      1.1  mrg #include <signal.h>
     30      1.1  mrg #include <stdio.h>
     31      1.1  mrg #include <stdlib.h>
     32      1.1  mrg 
     33      1.1  mrg #include "gmp.h"
     34      1.1  mrg #include "gmp-impl.h"
     35      1.1  mrg #include "tests.h"
     36      1.1  mrg 
     37      1.1  mrg 
     38      1.1  mrg #ifndef _GMP_IEEE_FLOATS
     39      1.1  mrg #define _GMP_IEEE_FLOATS 0
     40      1.1  mrg #endif
     41      1.1  mrg 
     42      1.1  mrg 
     43      1.1  mrg /* Exercise various 2^n values, with various exponents and positive and
     44      1.1  mrg    negative.  */
     45      1.1  mrg void
     46      1.1  mrg check_onebit (void)
     47      1.1  mrg {
     48      1.1  mrg   static const int bit_table[] = {
     49      1.1  mrg     0, 1, 2, 3,
     50      1.1  mrg     GMP_NUMB_BITS - 2, GMP_NUMB_BITS - 1,
     51      1.1  mrg     GMP_NUMB_BITS,
     52      1.1  mrg     GMP_NUMB_BITS + 1, GMP_NUMB_BITS + 2,
     53      1.1  mrg     2 * GMP_NUMB_BITS - 2, 2 * GMP_NUMB_BITS - 1,
     54      1.1  mrg     2 * GMP_NUMB_BITS,
     55      1.1  mrg     2 * GMP_NUMB_BITS + 1, 2 * GMP_NUMB_BITS + 2,
     56      1.1  mrg     3 * GMP_NUMB_BITS - 2, 3 * GMP_NUMB_BITS - 1,
     57      1.1  mrg     3 * GMP_NUMB_BITS,
     58      1.1  mrg     3 * GMP_NUMB_BITS + 1, 3 * GMP_NUMB_BITS + 2,
     59      1.1  mrg     4 * GMP_NUMB_BITS - 2, 4 * GMP_NUMB_BITS - 1,
     60      1.1  mrg     4 * GMP_NUMB_BITS,
     61      1.1  mrg     4 * GMP_NUMB_BITS + 1, 4 * GMP_NUMB_BITS + 2,
     62      1.1  mrg     5 * GMP_NUMB_BITS - 2, 5 * GMP_NUMB_BITS - 1,
     63      1.1  mrg     5 * GMP_NUMB_BITS,
     64      1.1  mrg     5 * GMP_NUMB_BITS + 1, 5 * GMP_NUMB_BITS + 2,
     65      1.1  mrg     6 * GMP_NUMB_BITS - 2, 6 * GMP_NUMB_BITS - 1,
     66      1.1  mrg     6 * GMP_NUMB_BITS,
     67      1.1  mrg     6 * GMP_NUMB_BITS + 1, 6 * GMP_NUMB_BITS + 2,
     68      1.1  mrg   };
     69      1.1  mrg   static const int exp_table[] = {
     70      1.1  mrg     0, -100, -10, -1, 1, 10, 100,
     71      1.1  mrg   };
     72      1.1  mrg 
     73      1.1  mrg   /* FIXME: It'd be better to base this on the float format. */
     74  1.1.1.2  mrg #if defined (__vax) || defined (__vax__)
     75      1.1  mrg   int     limit = 127;  /* vax fp numbers have limited range */
     76      1.1  mrg #else
     77      1.1  mrg   int     limit = 511;
     78      1.1  mrg #endif
     79      1.1  mrg 
     80      1.1  mrg   int        bit_i, exp_i, i;
     81      1.1  mrg   double     got, want;
     82      1.1  mrg   mp_size_t  nsize, sign;
     83      1.1  mrg   long       bit, exp, want_bit;
     84      1.1  mrg   mp_limb_t  np[20];
     85      1.1  mrg 
     86      1.1  mrg   for (bit_i = 0; bit_i < numberof (bit_table); bit_i++)
     87      1.1  mrg     {
     88      1.1  mrg       bit = bit_table[bit_i];
     89      1.1  mrg 
     90      1.1  mrg       nsize = BITS_TO_LIMBS (bit+1);
     91      1.1  mrg       refmpn_zero (np, nsize);
     92      1.1  mrg       np[bit/GMP_NUMB_BITS] = CNST_LIMB(1) << (bit % GMP_NUMB_BITS);
     93      1.1  mrg 
     94      1.1  mrg       for (exp_i = 0; exp_i < numberof (exp_table); exp_i++)
     95      1.1  mrg         {
     96      1.1  mrg           exp = exp_table[exp_i];
     97      1.1  mrg 
     98      1.1  mrg           want_bit = bit + exp;
     99  1.1.1.2  mrg           if (want_bit >= limit || want_bit <= -limit)
    100      1.1  mrg             continue;
    101      1.1  mrg 
    102      1.1  mrg           want = 1.0;
    103      1.1  mrg           for (i = 0; i < want_bit; i++)
    104      1.1  mrg             want *= 2.0;
    105      1.1  mrg           for (i = 0; i > want_bit; i--)
    106      1.1  mrg             want *= 0.5;
    107      1.1  mrg 
    108      1.1  mrg           for (sign = 0; sign >= -1; sign--, want = -want)
    109      1.1  mrg             {
    110      1.1  mrg               got = mpn_get_d (np, nsize, sign, exp);
    111      1.1  mrg               if (got != want)
    112      1.1  mrg                 {
    113      1.1  mrg                   printf    ("mpn_get_d wrong on 2^n\n");
    114      1.1  mrg                   printf    ("   bit      %ld\n", bit);
    115      1.1  mrg                   printf    ("   exp      %ld\n", exp);
    116      1.1  mrg                   printf    ("   want_bit %ld\n", want_bit);
    117      1.1  mrg                   printf    ("   sign     %ld\n", (long) sign);
    118      1.1  mrg                   mpn_trace ("   n        ", np, nsize);
    119      1.1  mrg                   printf    ("   nsize    %ld\n", (long) nsize);
    120      1.1  mrg                   d_trace   ("   want     ", want);
    121      1.1  mrg                   d_trace   ("   got      ", got);
    122      1.1  mrg                   abort();
    123      1.1  mrg                 }
    124      1.1  mrg             }
    125      1.1  mrg         }
    126      1.1  mrg     }
    127      1.1  mrg }
    128      1.1  mrg 
    129      1.1  mrg 
    130      1.1  mrg /* Exercise values 2^n+1, while such a value fits the mantissa of a double. */
    131      1.1  mrg void
    132      1.1  mrg check_twobit (void)
    133      1.1  mrg {
    134      1.1  mrg   int        i, mant_bits;
    135      1.1  mrg   double     got, want;
    136      1.1  mrg   mp_size_t  nsize, sign;
    137      1.1  mrg   mp_ptr     np;
    138      1.1  mrg 
    139      1.1  mrg   mant_bits = tests_dbl_mant_bits ();
    140      1.1  mrg   if (mant_bits == 0)
    141      1.1  mrg     return;
    142      1.1  mrg 
    143      1.1  mrg   np = refmpn_malloc_limbs (BITS_TO_LIMBS (mant_bits));
    144      1.1  mrg   want = 3.0;
    145      1.1  mrg   for (i = 1; i < mant_bits; i++)
    146      1.1  mrg     {
    147      1.1  mrg       nsize = BITS_TO_LIMBS (i+1);
    148      1.1  mrg       refmpn_zero (np, nsize);
    149      1.1  mrg       np[i/GMP_NUMB_BITS] = CNST_LIMB(1) << (i % GMP_NUMB_BITS);
    150      1.1  mrg       np[0] |= 1;
    151      1.1  mrg 
    152      1.1  mrg       for (sign = 0; sign >= -1; sign--)
    153      1.1  mrg         {
    154      1.1  mrg           got = mpn_get_d (np, nsize, sign, 0);
    155      1.1  mrg           if (got != want)
    156      1.1  mrg             {
    157      1.1  mrg               printf    ("mpn_get_d wrong on 2^%d + 1\n", i);
    158      1.1  mrg               printf    ("   sign     %ld\n", (long) sign);
    159      1.1  mrg               mpn_trace ("   n        ", np, nsize);
    160      1.1  mrg               printf    ("   nsize    %ld\n", (long) nsize);
    161      1.1  mrg               d_trace   ("   want     ", want);
    162      1.1  mrg               d_trace   ("   got      ", got);
    163      1.1  mrg               abort();
    164      1.1  mrg             }
    165      1.1  mrg           want = -want;
    166      1.1  mrg         }
    167      1.1  mrg 
    168      1.1  mrg       want = 2.0 * want - 1.0;
    169      1.1  mrg     }
    170      1.1  mrg 
    171      1.1  mrg   free (np);
    172      1.1  mrg }
    173      1.1  mrg 
    174      1.1  mrg 
    175      1.1  mrg /* Expect large negative exponents to underflow to 0.0.
    176      1.1  mrg    Some systems might have hardware traps for such an underflow (though
    177      1.1  mrg    usually it's not the default), so watch out for SIGFPE. */
    178      1.1  mrg void
    179      1.1  mrg check_underflow (void)
    180      1.1  mrg {
    181      1.1  mrg   static const long exp_table[] = {
    182      1.1  mrg     -999999L, LONG_MIN,
    183      1.1  mrg   };
    184      1.1  mrg   static const mp_limb_t  np[1] = { 1 };
    185      1.1  mrg 
    186      1.1  mrg   static long exp;
    187      1.1  mrg   mp_size_t  nsize, sign;
    188      1.1  mrg   double     got;
    189      1.1  mrg   int        exp_i;
    190      1.1  mrg 
    191      1.1  mrg   nsize = numberof (np);
    192      1.1  mrg 
    193      1.1  mrg   if (tests_setjmp_sigfpe() == 0)
    194      1.1  mrg     {
    195      1.1  mrg       for (exp_i = 0; exp_i < numberof (exp_table); exp_i++)
    196      1.1  mrg         {
    197      1.1  mrg           exp = exp_table[exp_i];
    198      1.1  mrg 
    199      1.1  mrg           for (sign = 0; sign >= -1; sign--)
    200      1.1  mrg             {
    201      1.1  mrg               got = mpn_get_d (np, nsize, sign, exp);
    202      1.1  mrg               if (got != 0.0)
    203      1.1  mrg                 {
    204      1.1  mrg                   printf  ("mpn_get_d wrong, didn't get 0.0 on underflow\n");
    205      1.1  mrg                   printf  ("  nsize    %ld\n", (long) nsize);
    206      1.1  mrg                   printf  ("  exp      %ld\n", exp);
    207      1.1  mrg                   printf  ("  sign     %ld\n", (long) sign);
    208      1.1  mrg                   d_trace ("  got      ", got);
    209      1.1  mrg                   abort ();
    210      1.1  mrg                 }
    211      1.1  mrg             }
    212      1.1  mrg         }
    213      1.1  mrg     }
    214      1.1  mrg   else
    215      1.1  mrg     {
    216      1.1  mrg       printf ("Warning, underflow to zero tests skipped due to SIGFPE (exp=%ld)\n", exp);
    217      1.1  mrg     }
    218      1.1  mrg   tests_sigfpe_done ();
    219      1.1  mrg }
    220      1.1  mrg 
    221      1.1  mrg 
    222      1.1  mrg /* Expect large values to result in +/-inf, on IEEE systems. */
    223      1.1  mrg void
    224      1.1  mrg check_inf (void)
    225      1.1  mrg {
    226      1.1  mrg   static const long exp_table[] = {
    227      1.1  mrg     999999L, LONG_MAX,
    228      1.1  mrg   };
    229      1.1  mrg   static const mp_limb_t  np[4] = { 1, 1, 1, 1 };
    230      1.1  mrg   long       exp;
    231      1.1  mrg   mp_size_t  nsize, sign, got_sign;
    232      1.1  mrg   double     got;
    233      1.1  mrg   int        exp_i;
    234      1.1  mrg 
    235      1.1  mrg   if (! _GMP_IEEE_FLOATS)
    236      1.1  mrg     return;
    237      1.1  mrg 
    238      1.1  mrg   for (nsize = 1; nsize <= numberof (np); nsize++)
    239      1.1  mrg     {
    240      1.1  mrg       for (exp_i = 0; exp_i < numberof (exp_table); exp_i++)
    241      1.1  mrg         {
    242      1.1  mrg           exp = exp_table[exp_i];
    243      1.1  mrg 
    244      1.1  mrg           for (sign = 0; sign >= -1; sign--)
    245      1.1  mrg             {
    246      1.1  mrg               got = mpn_get_d (np, nsize, sign, exp);
    247      1.1  mrg               got_sign = (got >= 0 ? 0 : -1);
    248      1.1  mrg               if (! tests_isinf (got))
    249      1.1  mrg                 {
    250      1.1  mrg                   printf  ("mpn_get_d wrong, didn't get infinity\n");
    251      1.1  mrg                 bad:
    252      1.1  mrg                   printf  ("  nsize    %ld\n", (long) nsize);
    253      1.1  mrg                   printf  ("  exp      %ld\n", exp);
    254      1.1  mrg                   printf  ("  sign     %ld\n", (long) sign);
    255      1.1  mrg                   d_trace ("  got      ", got);
    256      1.1  mrg                   printf  ("  got sign %ld\n", (long) got_sign);
    257      1.1  mrg                   abort ();
    258      1.1  mrg                 }
    259      1.1  mrg               if (got_sign != sign)
    260      1.1  mrg                 {
    261      1.1  mrg                   printf  ("mpn_get_d wrong sign on infinity\n");
    262      1.1  mrg                   goto bad;
    263      1.1  mrg                 }
    264      1.1  mrg             }
    265      1.1  mrg         }
    266      1.1  mrg     }
    267      1.1  mrg }
    268      1.1  mrg 
    269      1.1  mrg /* Check values 2^n approaching and into IEEE denorm range.
    270      1.1  mrg    Some systems might not support denorms, or might have traps setup, so
    271      1.1  mrg    watch out for SIGFPE.  */
    272      1.1  mrg void
    273      1.1  mrg check_ieee_denorm (void)
    274      1.1  mrg {
    275      1.1  mrg   static long exp;
    276      1.1  mrg   mp_limb_t  n = 1;
    277      1.1  mrg   long       i;
    278      1.1  mrg   mp_size_t  sign;
    279      1.1  mrg   double     want, got;
    280      1.1  mrg 
    281      1.1  mrg   if (! _GMP_IEEE_FLOATS)
    282      1.1  mrg     return;
    283      1.1  mrg 
    284      1.1  mrg   if (tests_setjmp_sigfpe() == 0)
    285      1.1  mrg     {
    286      1.1  mrg       exp = -1020;
    287      1.1  mrg       want = 1.0;
    288      1.1  mrg       for (i = 0; i > exp; i--)
    289      1.1  mrg         want *= 0.5;
    290      1.1  mrg 
    291      1.1  mrg       for ( ; exp > -1500 && want != 0.0; exp--)
    292      1.1  mrg         {
    293      1.1  mrg           for (sign = 0; sign >= -1; sign--)
    294      1.1  mrg             {
    295      1.1  mrg               got = mpn_get_d (&n, (mp_size_t) 1, sign, exp);
    296      1.1  mrg               if (got != want)
    297      1.1  mrg                 {
    298      1.1  mrg                   printf  ("mpn_get_d wrong on denorm\n");
    299      1.1  mrg                   printf  ("  n=1\n");
    300      1.1  mrg                   printf  ("  exp   %ld\n", exp);
    301      1.1  mrg                   printf  ("  sign  %ld\n", (long) sign);
    302      1.1  mrg                   d_trace ("  got   ", got);
    303      1.1  mrg                   d_trace ("  want  ", want);
    304      1.1  mrg                   abort ();
    305      1.1  mrg                 }
    306      1.1  mrg               want = -want;
    307      1.1  mrg             }
    308      1.1  mrg           want *= 0.5;
    309      1.1  mrg           FORCE_DOUBLE (want);
    310      1.1  mrg         }
    311      1.1  mrg     }
    312      1.1  mrg   else
    313      1.1  mrg     {
    314      1.1  mrg       printf ("Warning, IEEE denorm tests skipped due to SIGFPE (exp=%ld)\n", exp);
    315      1.1  mrg     }
    316      1.1  mrg   tests_sigfpe_done ();
    317      1.1  mrg }
    318      1.1  mrg 
    319      1.1  mrg 
    320      1.1  mrg /* Check values 2^n approaching exponent overflow.
    321      1.1  mrg    Some systems might trap on overflow, so watch out for SIGFPE.  */
    322      1.1  mrg void
    323      1.1  mrg check_ieee_overflow (void)
    324      1.1  mrg {
    325      1.1  mrg   static long exp;
    326      1.1  mrg   mp_limb_t  n = 1;
    327      1.1  mrg   long       i;
    328      1.1  mrg   mp_size_t  sign;
    329      1.1  mrg   double     want, got;
    330      1.1  mrg 
    331      1.1  mrg   if (! _GMP_IEEE_FLOATS)
    332      1.1  mrg     return;
    333      1.1  mrg 
    334      1.1  mrg   if (tests_setjmp_sigfpe() == 0)
    335      1.1  mrg     {
    336      1.1  mrg       exp = 1010;
    337      1.1  mrg       want = 1.0;
    338      1.1  mrg       for (i = 0; i < exp; i++)
    339      1.1  mrg         want *= 2.0;
    340      1.1  mrg 
    341      1.1  mrg       for ( ; exp < 1050; exp++)
    342      1.1  mrg         {
    343      1.1  mrg           for (sign = 0; sign >= -1; sign--)
    344      1.1  mrg             {
    345      1.1  mrg               got = mpn_get_d (&n, (mp_size_t) 1, sign, exp);
    346      1.1  mrg               if (got != want)
    347      1.1  mrg                 {
    348      1.1  mrg                   printf  ("mpn_get_d wrong on overflow\n");
    349      1.1  mrg                   printf  ("  n=1\n");
    350      1.1  mrg                   printf  ("  exp   %ld\n", exp);
    351      1.1  mrg                   printf  ("  sign  %ld\n", (long) sign);
    352      1.1  mrg                   d_trace ("  got   ", got);
    353      1.1  mrg                   d_trace ("  want  ", want);
    354      1.1  mrg                   abort ();
    355      1.1  mrg                 }
    356      1.1  mrg               want = -want;
    357      1.1  mrg             }
    358      1.1  mrg           want *= 2.0;
    359      1.1  mrg           FORCE_DOUBLE (want);
    360      1.1  mrg         }
    361      1.1  mrg     }
    362      1.1  mrg   else
    363      1.1  mrg     {
    364      1.1  mrg       printf ("Warning, IEEE overflow tests skipped due to SIGFPE (exp=%ld)\n", exp);
    365      1.1  mrg     }
    366      1.1  mrg   tests_sigfpe_done ();
    367      1.1  mrg }
    368      1.1  mrg 
    369      1.1  mrg 
    370      1.1  mrg /* ARM gcc 2.95.4 was seen generating bad code for ulong->double
    371      1.1  mrg    conversions, resulting in for instance 0x81c25113 incorrectly converted.
    372      1.1  mrg    This test exercises that value, to see mpn_get_d has avoided the
    373      1.1  mrg    problem.  */
    374      1.1  mrg void
    375      1.1  mrg check_0x81c25113 (void)
    376      1.1  mrg {
    377      1.1  mrg #if GMP_NUMB_BITS >= 32
    378      1.1  mrg   double     want = 2176995603.0;
    379      1.1  mrg   double     got;
    380      1.1  mrg   mp_limb_t  np[4];
    381      1.1  mrg   mp_size_t  nsize;
    382      1.1  mrg   long       exp;
    383      1.1  mrg 
    384      1.1  mrg   if (tests_dbl_mant_bits() < 32)
    385      1.1  mrg     return;
    386      1.1  mrg 
    387      1.1  mrg   for (nsize = 1; nsize <= numberof (np); nsize++)
    388      1.1  mrg     {
    389      1.1  mrg       refmpn_zero (np, nsize-1);
    390      1.1  mrg       np[nsize-1] = CNST_LIMB(0x81c25113);
    391      1.1  mrg       exp = - (nsize-1) * GMP_NUMB_BITS;
    392      1.1  mrg       got = mpn_get_d (np, nsize, (mp_size_t) 0, exp);
    393      1.1  mrg       if (got != want)
    394      1.1  mrg         {
    395      1.1  mrg           printf  ("mpn_get_d wrong on 2176995603 (0x81c25113)\n");
    396      1.1  mrg           printf  ("  nsize  %ld\n", (long) nsize);
    397      1.1  mrg           printf  ("  exp    %ld\n", exp);
    398      1.1  mrg           d_trace ("  got    ", got);
    399      1.1  mrg           d_trace ("  want   ", want);
    400      1.1  mrg           abort ();
    401      1.1  mrg         }
    402      1.1  mrg     }
    403      1.1  mrg #endif
    404      1.1  mrg }
    405      1.1  mrg 
    406      1.1  mrg 
    407      1.1  mrg void
    408      1.1  mrg check_rand (void)
    409      1.1  mrg {
    410      1.1  mrg   gmp_randstate_ptr rands = RANDS;
    411      1.1  mrg   int            rep, i;
    412      1.1  mrg   unsigned long  mant_bits;
    413      1.1  mrg   long           exp, exp_min, exp_max;
    414      1.1  mrg   double         got, want, d;
    415      1.1  mrg   mp_size_t      nalloc, nsize, sign;
    416      1.1  mrg   mp_limb_t      nhigh_mask;
    417      1.1  mrg   mp_ptr         np;
    418      1.1  mrg 
    419      1.1  mrg   mant_bits = tests_dbl_mant_bits ();
    420      1.1  mrg   if (mant_bits == 0)
    421      1.1  mrg     return;
    422      1.1  mrg 
    423      1.1  mrg   /* Allow for vax D format with exponent 127 to -128 only.
    424      1.1  mrg      FIXME: Do something to probe for a valid exponent range.  */
    425      1.1  mrg   exp_min = -100 - mant_bits;
    426      1.1  mrg   exp_max =  100 - mant_bits;
    427      1.1  mrg 
    428      1.1  mrg   /* space for mant_bits */
    429      1.1  mrg   nalloc = BITS_TO_LIMBS (mant_bits);
    430      1.1  mrg   np = refmpn_malloc_limbs (nalloc);
    431      1.1  mrg   nhigh_mask = MP_LIMB_T_MAX
    432      1.1  mrg     >> (GMP_NAIL_BITS + nalloc * GMP_NUMB_BITS - mant_bits);
    433      1.1  mrg 
    434      1.1  mrg   for (rep = 0; rep < 200; rep++)
    435      1.1  mrg     {
    436      1.1  mrg       /* random exp_min to exp_max, inclusive */
    437      1.1  mrg       exp = exp_min + (long) gmp_urandomm_ui (rands, exp_max - exp_min + 1);
    438      1.1  mrg 
    439      1.1  mrg       /* mant_bits worth of random at np */
    440      1.1  mrg       if (rep & 1)
    441      1.1  mrg         mpn_random (np, nalloc);
    442      1.1  mrg       else
    443      1.1  mrg         mpn_random2 (np, nalloc);
    444      1.1  mrg       nsize = nalloc;
    445      1.1  mrg       np[nsize-1] &= nhigh_mask;
    446      1.1  mrg       MPN_NORMALIZE (np, nsize);
    447      1.1  mrg       if (nsize == 0)
    448      1.1  mrg         continue;
    449      1.1  mrg 
    450      1.1  mrg       sign = (mp_size_t) gmp_urandomb_ui (rands, 1L) - 1;
    451      1.1  mrg 
    452      1.1  mrg       /* want = {np,nsize}, converting one bit at a time */
    453      1.1  mrg       want = 0.0;
    454      1.1  mrg       for (i = 0, d = 1.0; i < mant_bits; i++, d *= 2.0)
    455      1.1  mrg         if (np[i/GMP_NUMB_BITS] & (CNST_LIMB(1) << (i%GMP_NUMB_BITS)))
    456      1.1  mrg           want += d;
    457      1.1  mrg       if (sign < 0)
    458      1.1  mrg         want = -want;
    459      1.1  mrg 
    460      1.1  mrg       /* want = want * 2^exp */
    461      1.1  mrg       for (i = 0; i < exp; i++)
    462      1.1  mrg         want *= 2.0;
    463      1.1  mrg       for (i = 0; i > exp; i--)
    464      1.1  mrg         want *= 0.5;
    465      1.1  mrg 
    466      1.1  mrg       got = mpn_get_d (np, nsize, sign, exp);
    467      1.1  mrg 
    468      1.1  mrg       if (got != want)
    469      1.1  mrg         {
    470      1.1  mrg           printf    ("mpn_get_d wrong on random data\n");
    471      1.1  mrg           printf    ("   sign     %ld\n", (long) sign);
    472      1.1  mrg           mpn_trace ("   n        ", np, nsize);
    473      1.1  mrg           printf    ("   nsize    %ld\n", (long) nsize);
    474      1.1  mrg           printf    ("   exp      %ld\n", exp);
    475      1.1  mrg           d_trace   ("   want     ", want);
    476      1.1  mrg           d_trace   ("   got      ", got);
    477      1.1  mrg           abort();
    478      1.1  mrg         }
    479      1.1  mrg     }
    480      1.1  mrg 
    481      1.1  mrg   free (np);
    482      1.1  mrg }
    483      1.1  mrg 
    484      1.1  mrg 
    485      1.1  mrg int
    486      1.1  mrg main (void)
    487      1.1  mrg {
    488      1.1  mrg   tests_start ();
    489      1.1  mrg   mp_trace_base = -16;
    490      1.1  mrg 
    491      1.1  mrg   check_onebit ();
    492      1.1  mrg   check_twobit ();
    493      1.1  mrg   check_inf ();
    494      1.1  mrg   check_underflow ();
    495      1.1  mrg   check_ieee_denorm ();
    496      1.1  mrg   check_ieee_overflow ();
    497      1.1  mrg   check_0x81c25113 ();
    498  1.1.1.2  mrg #if ! (defined (__vax) || defined (__vax__))
    499      1.1  mrg   check_rand ();
    500  1.1.1.2  mrg #endif
    501      1.1  mrg 
    502      1.1  mrg   tests_end ();
    503      1.1  mrg   exit (0);
    504      1.1  mrg }
    505