Home | History | Annotate | Line # | Download | only in tests
tget_z.c revision 1.1.1.3.4.1
      1          1.1       mrg /* Test file for mpz_set_fr / mpfr_get_z.
      2          1.1       mrg 
      3  1.1.1.3.4.1  christos Copyright 2004, 2006-2018 Free Software Foundation, Inc.
      4      1.1.1.3       mrg Contributed by the AriC and Caramba projects, INRIA.
      5          1.1       mrg 
      6          1.1       mrg This file is part of the GNU MPFR Library.
      7          1.1       mrg 
      8          1.1       mrg The GNU MPFR Library is free software; you can redistribute it and/or modify
      9          1.1       mrg it under the terms of the GNU Lesser General Public License as published by
     10          1.1       mrg the Free Software Foundation; either version 3 of the License, or (at your
     11          1.1       mrg option) any later version.
     12          1.1       mrg 
     13          1.1       mrg The GNU MPFR Library is distributed in the hope that it will be useful, but
     14          1.1       mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     15          1.1       mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
     16          1.1       mrg License for more details.
     17          1.1       mrg 
     18          1.1       mrg You should have received a copy of the GNU Lesser General Public License
     19          1.1       mrg along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
     20          1.1       mrg http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
     21          1.1       mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
     22          1.1       mrg 
     23          1.1       mrg #include "mpfr-test.h"
     24          1.1       mrg 
     25          1.1       mrg static void
     26          1.1       mrg check_diff (void)
     27          1.1       mrg {
     28          1.1       mrg   int inex;
     29          1.1       mrg   mpfr_t x;
     30          1.1       mrg   mpz_t  z;
     31          1.1       mrg   mpfr_exp_t emin;
     32          1.1       mrg 
     33          1.1       mrg   mpz_init   (z);
     34          1.1       mrg   mpfr_init2 (x, 2);
     35          1.1       mrg 
     36          1.1       mrg   mpfr_set_ui (x, 2047, MPFR_RNDU);
     37          1.1       mrg   mpz_set_fr (z, x, MPFR_RNDN);
     38          1.1       mrg   if (mpz_cmp_ui (z, 2048) != 0)
     39          1.1       mrg     {
     40          1.1       mrg       printf ("get_z RU 2048 failed\n");
     41          1.1       mrg       exit (1);
     42          1.1       mrg     }
     43          1.1       mrg 
     44          1.1       mrg   mpfr_set_prec (x, 6);
     45          1.1       mrg   mpfr_set_str (x, "17.5", 10, MPFR_RNDN);
     46          1.1       mrg   inex = mpfr_get_z (z, x, MPFR_RNDN);
     47          1.1       mrg   if (inex <= 0 || mpz_cmp_ui (z, 18) != 0)
     48          1.1       mrg     {
     49          1.1       mrg       printf ("get_z RN 17.5 failed\n");
     50          1.1       mrg       exit (1);
     51          1.1       mrg     }
     52          1.1       mrg 
     53          1.1       mrg   /* save default emin */
     54          1.1       mrg   emin = mpfr_get_emin ();;
     55          1.1       mrg 
     56          1.1       mrg   mpfr_set_emin (17);
     57          1.1       mrg   mpfr_set_ui (x, 0, MPFR_RNDN);
     58          1.1       mrg   inex = mpfr_get_z (z, x, MPFR_RNDN);
     59          1.1       mrg   if (inex != 0 || mpz_cmp_ui (z, 0) != 0)
     60          1.1       mrg     {
     61          1.1       mrg       printf ("get_z 0 failed\n");
     62          1.1       mrg       exit (1);
     63          1.1       mrg     }
     64          1.1       mrg 
     65          1.1       mrg   /* restore default emin */
     66          1.1       mrg   mpfr_set_emin (emin);
     67          1.1       mrg 
     68          1.1       mrg   mpfr_clear (x);
     69          1.1       mrg   mpz_clear  (z);
     70          1.1       mrg }
     71          1.1       mrg 
     72          1.1       mrg static void
     73          1.1       mrg check_one (mpz_ptr z)
     74          1.1       mrg {
     75  1.1.1.3.4.1  christos   mpfr_exp_t emin, emax;
     76          1.1       mrg   int    inex;
     77          1.1       mrg   int    sh, neg;
     78          1.1       mrg   mpfr_t f;
     79  1.1.1.3.4.1  christos   mpz_t  got, ex, t;
     80  1.1.1.3.4.1  christos 
     81  1.1.1.3.4.1  christos   emin = mpfr_get_emin ();
     82  1.1.1.3.4.1  christos   emax = mpfr_get_emax ();
     83          1.1       mrg 
     84  1.1.1.3.4.1  christos   mpfr_init2 (f, MAX (mpz_sizeinbase (z, 2), MPFR_PREC_MIN));
     85          1.1       mrg   mpz_init (got);
     86  1.1.1.3.4.1  christos   mpz_init (ex);
     87  1.1.1.3.4.1  christos   mpz_init (t);
     88          1.1       mrg 
     89          1.1       mrg   for (sh = -2*GMP_NUMB_BITS ; sh < 2*GMP_NUMB_BITS ; sh++)
     90          1.1       mrg     {
     91  1.1.1.3.4.1  christos       inex = mpfr_set_z (f, z, MPFR_RNDN);  /* exact */
     92  1.1.1.3.4.1  christos       MPFR_ASSERTN (inex == 0);
     93  1.1.1.3.4.1  christos 
     94  1.1.1.3.4.1  christos       inex = sh < 0 ?
     95  1.1.1.3.4.1  christos         mpfr_div_2exp (f, f, -sh, MPFR_RNDN) :
     96  1.1.1.3.4.1  christos         mpfr_mul_2exp (f, f, sh, MPFR_RNDN);
     97  1.1.1.3.4.1  christos       MPFR_ASSERTN (inex == 0);
     98  1.1.1.3.4.1  christos 
     99          1.1       mrg       for (neg = 0; neg <= 1; neg++)
    100          1.1       mrg         {
    101  1.1.1.3.4.1  christos           int rnd;
    102          1.1       mrg 
    103  1.1.1.3.4.1  christos           /* Test (-1)^neg * z * 2^sh */
    104          1.1       mrg 
    105  1.1.1.3.4.1  christos           RND_LOOP_NO_RNDF (rnd)
    106          1.1       mrg             {
    107  1.1.1.3.4.1  christos               int ex_inex, same;
    108  1.1.1.3.4.1  christos               int d, fi, e;
    109  1.1.1.3.4.1  christos               mpfr_flags_t flags[3] = { 0, MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE,
    110  1.1.1.3.4.1  christos                                         MPFR_FLAGS_ALL }, ex_flags, gt_flags;
    111  1.1.1.3.4.1  christos 
    112  1.1.1.3.4.1  christos               if (neg)
    113  1.1.1.3.4.1  christos                 mpz_neg (ex, z);
    114  1.1.1.3.4.1  christos               else
    115  1.1.1.3.4.1  christos                 mpz_set (ex, z);
    116  1.1.1.3.4.1  christos 
    117  1.1.1.3.4.1  christos               if (sh < 0)
    118  1.1.1.3.4.1  christos                 switch (rnd)
    119  1.1.1.3.4.1  christos                   {
    120  1.1.1.3.4.1  christos                   case MPFR_RNDN:
    121  1.1.1.3.4.1  christos                     mpz_set_si (t, neg ? -1 : 1);
    122  1.1.1.3.4.1  christos                     mpz_mul_2exp (t, t, -sh - 1);
    123  1.1.1.3.4.1  christos                     mpz_add (ex, ex, t);
    124  1.1.1.3.4.1  christos                     /* d = mpz_divisible_2exp_p (ex, -sh); */
    125  1.1.1.3.4.1  christos                     d = mpz_scan1 (ex, 0) >= -sh;
    126  1.1.1.3.4.1  christos                     mpz_tdiv_q_2exp (ex, ex, -sh);
    127  1.1.1.3.4.1  christos                     if (d && mpz_tstbit (ex, 0) != 0)  /* even rounding */
    128  1.1.1.3.4.1  christos                       {
    129  1.1.1.3.4.1  christos                         if (neg)
    130  1.1.1.3.4.1  christos                           mpz_add_ui (ex, ex, 1);
    131  1.1.1.3.4.1  christos                         else
    132  1.1.1.3.4.1  christos                           mpz_sub_ui (ex, ex, 1);
    133  1.1.1.3.4.1  christos                       }
    134  1.1.1.3.4.1  christos                     break;
    135  1.1.1.3.4.1  christos                   case MPFR_RNDZ:
    136  1.1.1.3.4.1  christos                     mpz_tdiv_q_2exp (ex, ex, -sh);
    137  1.1.1.3.4.1  christos                     break;
    138  1.1.1.3.4.1  christos                   case MPFR_RNDU:
    139  1.1.1.3.4.1  christos                     mpz_cdiv_q_2exp (ex, ex, -sh);
    140  1.1.1.3.4.1  christos                     break;
    141  1.1.1.3.4.1  christos                   case MPFR_RNDD:
    142  1.1.1.3.4.1  christos                     mpz_fdiv_q_2exp (ex, ex, -sh);
    143  1.1.1.3.4.1  christos                     break;
    144  1.1.1.3.4.1  christos                   case MPFR_RNDA:
    145  1.1.1.3.4.1  christos                     if (neg)
    146  1.1.1.3.4.1  christos                       mpz_fdiv_q_2exp (ex, ex, -sh);
    147  1.1.1.3.4.1  christos                     else
    148  1.1.1.3.4.1  christos                       mpz_cdiv_q_2exp (ex, ex, -sh);
    149  1.1.1.3.4.1  christos                     break;
    150  1.1.1.3.4.1  christos                   default:
    151  1.1.1.3.4.1  christos                     MPFR_ASSERTN (0);
    152  1.1.1.3.4.1  christos                   }
    153  1.1.1.3.4.1  christos               else
    154  1.1.1.3.4.1  christos                 mpz_mul_2exp (ex, ex, sh);
    155  1.1.1.3.4.1  christos 
    156  1.1.1.3.4.1  christos               ex_inex = - mpfr_cmp_z (f, ex);
    157  1.1.1.3.4.1  christos               ex_inex = VSIGN (ex_inex);
    158  1.1.1.3.4.1  christos 
    159  1.1.1.3.4.1  christos               for (fi = 0; fi < numberof (flags); fi++)
    160  1.1.1.3.4.1  christos                 for (e = 0; e < 2; e++)
    161  1.1.1.3.4.1  christos                   {
    162  1.1.1.3.4.1  christos                     if (e)
    163  1.1.1.3.4.1  christos                       {
    164  1.1.1.3.4.1  christos                         mpfr_exp_t ef;
    165  1.1.1.3.4.1  christos 
    166  1.1.1.3.4.1  christos                         if (MPFR_IS_ZERO (f))
    167  1.1.1.3.4.1  christos                           break;
    168  1.1.1.3.4.1  christos                         ef = MPFR_GET_EXP (f);
    169  1.1.1.3.4.1  christos                         set_emin (ef);
    170  1.1.1.3.4.1  christos                         set_emax (ef);
    171  1.1.1.3.4.1  christos                       }
    172  1.1.1.3.4.1  christos                     ex_flags = __gmpfr_flags = flags[fi];
    173  1.1.1.3.4.1  christos                     if (ex_inex != 0)
    174  1.1.1.3.4.1  christos                       ex_flags |= MPFR_FLAGS_INEXACT;
    175  1.1.1.3.4.1  christos                     inex = mpfr_get_z (got, f, (mpfr_rnd_t) rnd);
    176  1.1.1.3.4.1  christos                     inex = VSIGN (inex);
    177  1.1.1.3.4.1  christos                     gt_flags = __gmpfr_flags;
    178  1.1.1.3.4.1  christos                     set_emin (emin);
    179  1.1.1.3.4.1  christos                     set_emax (emax);
    180  1.1.1.3.4.1  christos                     same = SAME_SIGN (inex, ex_inex);
    181  1.1.1.3.4.1  christos 
    182  1.1.1.3.4.1  christos                     if (mpz_cmp (got, ex) != 0 ||
    183  1.1.1.3.4.1  christos                         !same || gt_flags != ex_flags)
    184  1.1.1.3.4.1  christos                       {
    185  1.1.1.3.4.1  christos                         printf ("Error in check_one for sh=%d, fi=%d, %s%s\n",
    186  1.1.1.3.4.1  christos                                 sh, fi,
    187  1.1.1.3.4.1  christos                                 mpfr_print_rnd_mode ((mpfr_rnd_t) rnd),
    188  1.1.1.3.4.1  christos                                 e ? ", reduced exponent range" : "");
    189  1.1.1.3.4.1  christos                         printf ("     f = "); mpfr_dump (f);
    190  1.1.1.3.4.1  christos                         printf ("expected "); mpz_out_str (stdout, 10, ex);
    191  1.1.1.3.4.1  christos                         printf ("\n     got "); mpz_out_str (stdout, 10, got);
    192  1.1.1.3.4.1  christos                         printf ("\nExpected inex ~ %d, got %d (%s)\n",
    193  1.1.1.3.4.1  christos                                 ex_inex, inex, same ? "OK" : "wrong");
    194  1.1.1.3.4.1  christos                         printf ("Flags:\n");
    195  1.1.1.3.4.1  christos                         printf ("      in"); flags_out (flags[fi]);
    196  1.1.1.3.4.1  christos                         printf ("expected"); flags_out (ex_flags);
    197  1.1.1.3.4.1  christos                         printf ("     got"); flags_out (gt_flags);
    198  1.1.1.3.4.1  christos                         exit (1);
    199  1.1.1.3.4.1  christos                       }
    200  1.1.1.3.4.1  christos                   }
    201          1.1       mrg             }
    202  1.1.1.3.4.1  christos 
    203  1.1.1.3.4.1  christos           mpfr_neg (f, f, MPFR_RNDN);
    204          1.1       mrg         }
    205          1.1       mrg     }
    206          1.1       mrg 
    207          1.1       mrg   mpfr_clear (f);
    208          1.1       mrg   mpz_clear (got);
    209  1.1.1.3.4.1  christos   mpz_clear (ex);
    210  1.1.1.3.4.1  christos   mpz_clear (t);
    211          1.1       mrg }
    212          1.1       mrg 
    213          1.1       mrg static void
    214          1.1       mrg check (void)
    215          1.1       mrg {
    216          1.1       mrg   mpz_t  z;
    217          1.1       mrg 
    218          1.1       mrg   mpz_init (z);
    219          1.1       mrg 
    220          1.1       mrg   mpz_set_ui (z, 0L);
    221          1.1       mrg   check_one (z);
    222          1.1       mrg 
    223  1.1.1.3.4.1  christos   mpz_set_si (z, 17L);
    224  1.1.1.3.4.1  christos   check_one (z);
    225  1.1.1.3.4.1  christos 
    226          1.1       mrg   mpz_set_si (z, 123L);
    227          1.1       mrg   check_one (z);
    228          1.1       mrg 
    229          1.1       mrg   mpz_rrandomb (z, RANDS, 2*GMP_NUMB_BITS);
    230          1.1       mrg   check_one (z);
    231          1.1       mrg 
    232          1.1       mrg   mpz_rrandomb (z, RANDS, 5*GMP_NUMB_BITS);
    233          1.1       mrg   check_one (z);
    234          1.1       mrg 
    235          1.1       mrg   mpz_clear (z);
    236          1.1       mrg }
    237          1.1       mrg 
    238          1.1       mrg static void
    239          1.1       mrg special (void)
    240          1.1       mrg {
    241          1.1       mrg   int inex;
    242          1.1       mrg   mpfr_t x;
    243          1.1       mrg   mpz_t z;
    244  1.1.1.3.4.1  christos   int i, fi;
    245  1.1.1.3.4.1  christos   int rnd;
    246          1.1       mrg   mpfr_exp_t e;
    247  1.1.1.3.4.1  christos   mpfr_flags_t flags[3] = { 0, MPFR_FLAGS_ALL ^ MPFR_FLAGS_ERANGE,
    248  1.1.1.3.4.1  christos                             MPFR_FLAGS_ALL }, ex_flags, gt_flags;
    249          1.1       mrg 
    250          1.1       mrg   mpfr_init2 (x, 2);
    251          1.1       mrg   mpz_init (z);
    252          1.1       mrg 
    253  1.1.1.3.4.1  christos   RND_LOOP (rnd)
    254  1.1.1.3.4.1  christos     for (i = -1; i <= 1; i++)
    255  1.1.1.3.4.1  christos       for (fi = 0; fi < numberof (flags); fi++)
    256          1.1       mrg         {
    257  1.1.1.3.4.1  christos           ex_flags = flags[fi] | MPFR_FLAGS_ERANGE;
    258  1.1.1.3.4.1  christos           if (i != 0)
    259  1.1.1.3.4.1  christos             mpfr_set_nan (x);
    260  1.1.1.3.4.1  christos           else
    261  1.1.1.3.4.1  christos             mpfr_set_inf (x, i);
    262  1.1.1.3.4.1  christos           __gmpfr_flags = flags[fi];
    263  1.1.1.3.4.1  christos           inex = mpfr_get_z (z, x, (mpfr_rnd_t) rnd);
    264  1.1.1.3.4.1  christos           gt_flags = __gmpfr_flags;
    265  1.1.1.3.4.1  christos           if (gt_flags != ex_flags || inex != 0 || mpz_cmp_ui (z, 0) != 0)
    266  1.1.1.3.4.1  christos             {
    267  1.1.1.3.4.1  christos               printf ("special() failed on mpfr_get_z"
    268  1.1.1.3.4.1  christos                       " for %s, i = %d, fi = %d\n",
    269  1.1.1.3.4.1  christos                       mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), i, fi);
    270  1.1.1.3.4.1  christos               printf ("Expected z = 0, inex = 0,");
    271  1.1.1.3.4.1  christos               flags_out (ex_flags);
    272  1.1.1.3.4.1  christos               printf ("Got      z = ");
    273  1.1.1.3.4.1  christos               mpz_out_str (stdout, 10, z);
    274  1.1.1.3.4.1  christos               printf (", inex = %d,", inex);
    275  1.1.1.3.4.1  christos               flags_out (gt_flags);
    276  1.1.1.3.4.1  christos               exit (1);
    277  1.1.1.3.4.1  christos             }
    278  1.1.1.3.4.1  christos           __gmpfr_flags = flags[fi];
    279  1.1.1.3.4.1  christos           e = mpfr_get_z_2exp (z, x);
    280  1.1.1.3.4.1  christos           gt_flags = __gmpfr_flags;
    281  1.1.1.3.4.1  christos           if (gt_flags != ex_flags || e != __gmpfr_emin ||
    282  1.1.1.3.4.1  christos               mpz_cmp_ui (z, 0) != 0)
    283  1.1.1.3.4.1  christos             {
    284  1.1.1.3.4.1  christos               printf ("special() failed on mpfr_get_z_2exp"
    285  1.1.1.3.4.1  christos                       " for %s, i = %d, fi = %d\n",
    286  1.1.1.3.4.1  christos                       mpfr_print_rnd_mode ((mpfr_rnd_t) rnd), i, fi);
    287  1.1.1.3.4.1  christos               printf ("Expected z = 0, e = %" MPFR_EXP_FSPEC "d,",
    288  1.1.1.3.4.1  christos                       (mpfr_eexp_t) __gmpfr_emin);
    289  1.1.1.3.4.1  christos               flags_out (ex_flags);
    290  1.1.1.3.4.1  christos               printf ("Got      z = ");
    291  1.1.1.3.4.1  christos               mpz_out_str (stdout, 10, z);
    292  1.1.1.3.4.1  christos               printf (", e = %" MPFR_EXP_FSPEC "d,", (mpfr_eexp_t) e);
    293  1.1.1.3.4.1  christos               flags_out (gt_flags);
    294  1.1.1.3.4.1  christos               exit (1);
    295  1.1.1.3.4.1  christos             }
    296          1.1       mrg         }
    297          1.1       mrg 
    298          1.1       mrg   mpfr_clear (x);
    299          1.1       mrg   mpz_clear (z);
    300          1.1       mrg }
    301          1.1       mrg 
    302          1.1       mrg int
    303          1.1       mrg main (void)
    304          1.1       mrg {
    305          1.1       mrg   tests_start_mpfr ();
    306          1.1       mrg 
    307          1.1       mrg   check ();
    308          1.1       mrg   check_diff ();
    309          1.1       mrg   special ();
    310          1.1       mrg 
    311          1.1       mrg   tests_end_mpfr ();
    312          1.1       mrg   return 0;
    313          1.1       mrg }
    314