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