(root)/
mpfr-4.2.1/
tests/
tmul_ui.c
       1  /* Test file for mpfr_mul_ui.
       2  
       3  Copyright 1999-2023 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  https://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_inexact (mpfr_prec_t p)
      27  {
      28    mpfr_t x, y, z;
      29    unsigned long u;
      30    mpfr_prec_t q;
      31    int inexact, cmp;
      32    int rnd;
      33  
      34    mpfr_init2 (x, p);
      35    mpfr_init (y);
      36    mpfr_init2 (z, p + mp_bits_per_limb);
      37    mpfr_urandomb (x, RANDS);
      38    u = randlimb ();
      39    if (mpfr_mul_ui (z, x, u, MPFR_RNDN))
      40      {
      41        printf ("Error: result should be exact\n");
      42        exit (1);
      43      }
      44  
      45    for (q = MPFR_PREC_MIN; q <= p; q++)
      46      RND_LOOP (rnd)
      47        {
      48          if (rnd == MPFR_RNDF)
      49            continue; /* inexact is undefined */
      50  
      51          mpfr_set_prec (y, q);
      52          inexact = mpfr_mul_ui (y, x, u, (mpfr_rnd_t) rnd);
      53          cmp = mpfr_cmp (y, z);
      54          if (((inexact == 0) && (cmp != 0)) ||
      55              ((inexact < 0) && (cmp >= 0)) ||
      56              ((inexact > 0) && (cmp <= 0)))
      57            {
      58              printf ("Wrong inexact flag for p=%u, q=%u, rnd=%s\n",
      59                      (unsigned int) p, (unsigned int) q,
      60                      mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
      61              exit (1);
      62            }
      63        }
      64  
      65    mpfr_set_prec (x, 2);
      66    mpfr_set_ui (x, 1, MPFR_RNDN);
      67    if (mpfr_mul_ui (x, x, 5, MPFR_RNDZ) == 0)
      68      {
      69        printf ("mul_ui(1, 5) cannot be exact with prec=2\n");
      70        exit (1);
      71      }
      72  
      73    mpfr_clear (x);
      74    mpfr_clear (y);
      75    mpfr_clear (z);
      76  }
      77  
      78  #define TEST_FUNCTION mpfr_mul_ui
      79  #define ULONG_ARG2
      80  #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), 1, RANDS)
      81  #include "tgeneric.c"
      82  
      83  int
      84  main (int argc, char *argv[])
      85  {
      86    mpfr_t x, y;
      87    unsigned int xprec, yprec, i;
      88    mpfr_prec_t p;
      89    mpfr_exp_t emax;
      90    int r;
      91  
      92    tests_start_mpfr ();
      93  
      94    emax = mpfr_get_emax ();
      95  
      96    for (p=2; p<100; p++)
      97      for (i=1; i<50; i++)
      98        check_inexact (p);
      99  
     100    mpfr_init2 (x, 53);
     101    mpfr_init2 (y, 53);
     102  
     103    /* checks that result is normalized */
     104    mpfr_set_str (y, "6.93147180559945286227e-01", 10, MPFR_RNDZ);
     105    mpfr_mul_ui (x, y, 1, MPFR_RNDZ);
     106    if (MPFR_MANT(x)[MPFR_PREC(x)/mp_bits_per_limb] >> (mp_bits_per_limb-1) == 0)
     107      {
     108        printf ("Error in mpfr_mul_ui: result not normalized\n");
     109        exit (1);
     110      }
     111    if (mpfr_cmp (x, y))
     112      {
     113        printf ("Error in mpfr_mul_ui: 1*y != y\n");
     114        printf ("y=  "); mpfr_dump (y);
     115        printf ("1*y="); mpfr_dump (x);
     116        exit (1);
     117      }
     118  
     119    mpfr_set_inf (x, 1);
     120    mpfr_mul_ui (x, x, 3, MPFR_RNDU);
     121    if (!mpfr_inf_p (x) || (mpfr_sgn (x) <= 0))
     122      {
     123        printf ("Error in mpfr_mul_ui: +Inf*3 does not give +Inf\n");
     124        exit (1);
     125      }
     126  
     127    mpfr_set_inf (x, -1);
     128    mpfr_mul_ui (x, x, 3, MPFR_RNDU);
     129    if (!mpfr_inf_p (x) || (mpfr_sgn (x) >= 0))
     130      {
     131        printf ("Error in mpfr_mul_ui: -Inf*3 does not give -Inf\n");
     132        exit (1);
     133      }
     134  
     135    mpfr_set_nan (x);
     136    mpfr_mul_ui (x, x, 3, MPFR_RNDU);
     137    if (!mpfr_nan_p(x))
     138      {
     139        printf ("Error in mpfr_mul_ui: NaN*3 does not give NaN\n");
     140        exit (1);
     141      }
     142  
     143    mpfr_set_inf (x, 1);
     144    mpfr_mul_ui (x, x, 0, MPFR_RNDU);
     145    MPFR_ASSERTN(mpfr_nan_p (x));
     146  
     147    mpfr_set_ui (x, 1, MPFR_RNDU);
     148    mpfr_mul_ui (x, x, 0, MPFR_RNDU);
     149    MPFR_ASSERTN(mpfr_cmp_ui (x, 0) == 0 && MPFR_IS_POS(x));
     150  
     151    set_emax (0);
     152    mpfr_set_str_binary (x, "0.1E0");
     153    (mpfr_mul_ui) (x, x, 2, MPFR_RNDN);
     154    MPFR_ASSERTN(mpfr_inf_p (x) && MPFR_IS_POS(x));
     155    set_emax (emax);
     156  
     157    /* To check the macros call */
     158    mpfr_set_ui (x, 1, MPFR_RNDN);
     159    mpfr_mul_ui (x, x, 2, MPFR_RNDN);
     160    MPFR_ASSERTN(mpfr_cmp_ui(x, 2) == 0);
     161    mpfr_mul_si (x, x, 4, MPFR_RNDN);
     162    MPFR_ASSERTN(mpfr_cmp_ui(x, 8) == 0);
     163  
     164    mpfr_set_str (x, /*1.0/3.0*/
     165                  "0.333333333333333333333333333333333", 10, MPFR_RNDZ);
     166    mpfr_mul_ui (x, x, 3, MPFR_RNDU);
     167    if (mpfr_cmp_ui (x, 1))
     168      {
     169        printf ("Error in mpfr_mul_ui: U(Z(1/3)*3) does not give 1\n");
     170        exit (1);
     171      }
     172  
     173    /* checks sign is correct */
     174    mpfr_set_si (x, -2, MPFR_RNDZ);
     175    mpfr_set_si (y, 3, MPFR_RNDZ);
     176    mpfr_mul_ui(x, y, 4, MPFR_RNDZ);
     177    if (mpfr_cmp_ui(x, 0) <= 0)
     178      {
     179        printf("Error in mpfr_mul_ui: 4*3.0 does not give a positive result:\n");
     180        mpfr_dump (x);
     181        printf("mpfr_cmp_ui(x, 0) = %d\n", mpfr_cmp_ui(x, 0));
     182        exit(1);
     183      }
     184  
     185    mpfr_set_prec (x, 9);
     186    mpfr_set_prec (y, 9);
     187    mpfr_set_str_binary (y, "0.100001111E9"); /* 271 */
     188    mpfr_mul_ui (x, y, 1335, MPFR_RNDN);
     189    mpfr_set_str_binary (y, "0.101100001E19"); /* 361472 */
     190    if (mpfr_cmp (x, y))
     191      {
     192        printf ("Error in mul_ui for 1335*(0.100001111E9)\n");
     193        printf ("got "); mpfr_dump (x);
     194        exit(1);
     195      }
     196  
     197    mpfr_set_prec(y, 100);
     198    mpfr_set_prec(x, 100);
     199    /* y = 1199781142214086656 */
     200    mpfr_set_str_binary(y, "0.1000010100110011110101001011110010101111000100001E61");
     201    mpfr_mul_ui(x, y, 121, MPFR_RNDD);
     202    /* 121*y = 145173518207904485376, representable exactly */
     203    mpfr_set_str_binary(y, "0.1111101111010101111111100011010010111010111110110011001E67");
     204    if (mpfr_cmp(x, y))
     205      {
     206        printf("Error for 121*y: expected result is:\n");
     207        mpfr_dump (y);
     208      }
     209  
     210    mpfr_set_prec (x, 32);
     211    mpfr_set_str_binary (x, "0.10000000000000000000000000000000E1");
     212    mpfr_set_prec (y, 93);
     213    mpfr_mul_ui (y, x, 1, MPFR_RNDN);
     214  
     215    mpfr_set_prec (x, 287);
     216    mpfr_set_str_binary (x, "0.1111E7");
     217    mpfr_set_prec (y, 289);
     218    mpfr_mul_ui (y, x, 6, MPFR_RNDN);
     219    mpfr_set_str_binary (x, "0.101101E10");
     220    if (mpfr_cmp (x, y))
     221      {
     222        printf ("Error for 6 * 120\n");
     223        exit (1);
     224      }
     225  
     226    mpfr_set_prec (x, 68);
     227    mpfr_set_prec (y, 64);
     228    mpfr_set_str (x, "2143861251406875.0", 10, MPFR_RNDN);
     229    mpfr_mul_ui (y, x, 23, MPFR_RNDN);
     230    mpfr_set_str_binary (x, "10101111001011100001100110101111110001010010011001101101.0");
     231    if (mpfr_cmp (x, y))
     232      {
     233        printf ("Error for 23 * 2143861251406875.0\n");
     234        printf ("expected "); mpfr_dump (x);
     235        printf ("got      "); mpfr_dump (y);
     236        exit (1);
     237      }
     238  
     239  
     240    for (xprec = 53; xprec <= 128; xprec++)
     241      {
     242        mpfr_set_prec (x, xprec);
     243        mpfr_set_str_binary (x, "0.1100100100001111110011111000000011011100001100110111E2");
     244        for (yprec = 53; yprec <= 128; yprec++)
     245          {
     246            mpfr_set_prec (y, yprec);
     247            mpfr_mul_ui (y, x, 1, MPFR_RNDN);
     248            if (mpfr_cmp(x,y))
     249              {
     250                printf ("multiplication by 1.0 fails for xprec=%u, yprec=%u\n",
     251                        xprec, yprec);
     252                printf ("expected "); mpfr_dump (x);
     253                printf ("got      "); mpfr_dump (y);
     254                exit (1);
     255              }
     256          }
     257      }
     258  
     259    mpfr_set_prec (x, 128);
     260    mpfr_set_ui (x, 17, MPFR_RNDN);
     261    mpfr_mul_ui (x, x, ULONG_HIGHBIT, MPFR_RNDN);
     262    mpfr_set_prec (y, 128);
     263    mpfr_set_ui (y, ULONG_HIGHBIT, MPFR_RNDN);
     264    mpfr_mul_ui (y, y, 17, MPFR_RNDN);
     265    if (mpfr_cmp (x, y))
     266      {
     267        printf ("Error for 17 * ULONG_HIGHBIT\n");
     268        exit (1);
     269      }
     270  
     271    /* Check regression */
     272    mpfr_set_prec (x, 32);
     273    mpfr_set_prec (y, 96);
     274    mpfr_set_ui (x, 1742175942, MPFR_RNDN);
     275    mpfr_mul_ui (y, x, 59, MPFR_RNDN);
     276    if (mpfr_cmp_str (y, "0.10111111011101010101000110111101000100000000000000"
     277                      "0000000000000000000000000000000000000000000000E37",
     278                      2, MPFR_RNDN))
     279      {
     280        printf ("Regression tested failed for x=1742175942 * 59\n");
     281        exit (1);
     282      }
     283  
     284    set_emax (MPFR_EMAX_MAX);
     285    mpfr_set_prec (x, 32);
     286    mpfr_set_prec (y, 96);
     287    mpfr_set_inf (x, 1);
     288    mpfr_nextbelow (x);
     289    RND_LOOP (r)
     290      {
     291        mpfr_flags_t ex_flags, flags;
     292  
     293        ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT;
     294        mpfr_clear_flags ();
     295        mpfr_mul_ui (y, x, 123, (mpfr_rnd_t) r);
     296        flags = __gmpfr_flags;
     297        if (flags != ex_flags)
     298          {
     299            printf ("Error in overflow check for %s\n",
     300                    mpfr_print_rnd_mode ((mpfr_rnd_t) r));
     301            printf ("Expected flags:");
     302            flags_out (ex_flags);
     303            printf ("Got:           ");
     304            flags_out (flags);
     305            exit (1);
     306          }
     307      }
     308    set_emax (emax);
     309  
     310    mpfr_clear(x);
     311    mpfr_clear(y);
     312  
     313    test_generic (MPFR_PREC_MIN, 500, 100);
     314  
     315    tests_end_mpfr ();
     316    return 0;
     317  }