(root)/
mpfr-4.2.1/
tests/
tset_q.c
       1  /* Test file for mpfr_set_q.
       2  
       3  Copyright 2000-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  #ifndef MPFR_USE_MINI_GMP
      26  
      27  static void
      28  check (long int n, long int d, mpfr_rnd_t rnd, const char *ys)
      29  {
      30    mpq_t q;
      31    mpfr_t x, t;
      32    int inexact, compare;
      33    mpfr_flags_t flags, ex_flags;
      34  
      35    mpfr_init2 (x, 53);
      36    mpfr_init2 (t, mpfr_get_prec (x) + mp_bits_per_limb);
      37    mpq_init (q);
      38    mpq_set_si (q, n, d);
      39    mpfr_clear_flags ();
      40    inexact = mpfr_set_q (x, q, rnd);
      41    flags = __gmpfr_flags;
      42  
      43    /* check values */
      44    if (mpfr_cmp_str1 (x, ys))
      45      {
      46        printf ("Error for q = %ld/%ld and rnd = %s\n", n, d,
      47                mpfr_print_rnd_mode (rnd));
      48        printf ("correct result is %s, mpfr_set_q gives ", ys);
      49        mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN);
      50        putchar ('\n');
      51        exit (1);
      52      }
      53  
      54    /* check inexact flag */
      55    if (mpfr_mul_ui (t, x, (d < 0) ? (-d) : d, rnd))
      56      {
      57        printf ("t <- x * d should be exact\n");
      58        exit (1);
      59      }
      60    compare = mpfr_cmp_si (t, n);
      61    if (! SAME_SIGN (inexact, compare))
      62      {
      63        printf ("Wrong ternary value for q = %ld/%ld and rnd = %s:\n"
      64                "expected %d or equivalent, got %d\n",
      65                n, d, mpfr_print_rnd_mode (rnd), compare, inexact);
      66        exit (1);
      67      }
      68  
      69    ex_flags = compare == 0 ? 0 : MPFR_FLAGS_INEXACT;
      70    if (flags != ex_flags)
      71      {
      72        printf ("Wrong flags for q = %ld/%ld and rnd = %s:\n",
      73                n, d, mpfr_print_rnd_mode (rnd));
      74        printf ("Expected flags:");
      75        flags_out (ex_flags);
      76        printf ("Got flags:     ");
      77        flags_out (flags);
      78        exit (1);
      79      }
      80  
      81    mpfr_clear (x);
      82    mpfr_clear (t);
      83    mpq_clear (q);
      84  }
      85  
      86  static void
      87  check0 (void)
      88  {
      89    mpq_t y;
      90    mpfr_t x;
      91    int inexact;
      92    int r;
      93  
      94    /* Check for +0 */
      95    mpfr_init (x);
      96    mpq_init (y);
      97    mpq_set_si (y, 0, 1);
      98    RND_LOOP (r)
      99      {
     100        mpfr_clear_flags ();
     101        inexact = mpfr_set_q (x, y, (mpfr_rnd_t) r);
     102        if (!MPFR_IS_ZERO(x) || !MPFR_IS_POS(x) || inexact ||
     103            __gmpfr_flags != 0)
     104          {
     105            printf("mpfr_set_q(x,0) failed for %s\n",
     106                   mpfr_print_rnd_mode ((mpfr_rnd_t) r));
     107            exit(1);
     108          }
     109      }
     110    mpfr_clear (x);
     111    mpq_clear (y);
     112  }
     113  
     114  static void
     115  check_nan_inf_mpq (void)
     116  {
     117    mpfr_t mpfr_value, mpfr_cmp;
     118    mpq_t mpq_value;
     119    int status;
     120  
     121    mpfr_init2 (mpfr_value, MPFR_PREC_MIN);
     122    mpq_init (mpq_value);
     123    mpq_set_si (mpq_value, 0, 0);
     124    mpz_set_si (mpq_denref (mpq_value), 0);
     125  
     126    status = mpfr_set_q (mpfr_value, mpq_value, MPFR_RNDN);
     127  
     128    if ((status != 0) || (!MPFR_IS_NAN (mpfr_value)))
     129      {
     130        mpfr_init2 (mpfr_cmp, MPFR_PREC_MIN);
     131        mpfr_set_nan (mpfr_cmp);
     132        printf ("mpfr_set_q with a NAN mpq value returned a wrong value :\n"
     133                "  expected ");
     134        mpfr_dump (mpfr_cmp);
     135        printf ("  got      ");
     136        mpfr_dump (mpfr_value);
     137        printf ("  ternary value is %d\n", status);
     138        exit (1);
     139      }
     140  
     141    mpq_set_si (mpq_value, -1, 0);
     142    mpz_set_si (mpq_denref (mpq_value), 0);
     143  
     144    status = mpfr_set_q (mpfr_value, mpq_value, MPFR_RNDN);
     145  
     146    if ((status != 0) || (!MPFR_IS_INF (mpfr_value)) ||
     147        (MPFR_SIGN(mpfr_value) != mpq_sgn(mpq_value)))
     148      {
     149        mpfr_init2 (mpfr_cmp, MPFR_PREC_MIN);
     150        mpfr_set_inf (mpfr_cmp, -1);
     151        printf ("mpfr_set_q with a -INF mpq value returned a wrong value :\n"
     152                "  expected ");
     153        mpfr_dump (mpfr_cmp);
     154        printf ("  got      ");
     155        mpfr_dump (mpfr_value);
     156        printf ("  ternary value is %d\n", status);
     157        exit (1);
     158      }
     159  
     160    mpq_clear (mpq_value);
     161    mpfr_clear (mpfr_value);
     162  }
     163  
     164  int
     165  main (void)
     166  {
     167    tests_start_mpfr ();
     168  
     169    check(-1647229822, 40619231, MPFR_RNDZ, "-4.055295438754120596e1");
     170    check(-148939696, 1673285490, MPFR_RNDZ, "-8.9010331404953485501e-2");
     171    check(-441322590, 273662545, MPFR_RNDZ, "-1.6126525096812205362");
     172    check(-1631156895, 1677687197, MPFR_RNDU, "-9.722652100563177191e-1");
     173    check(2141332571, 3117601, MPFR_RNDZ, "6.8685267004982347316e2");
     174    check(75504803, 400207282, MPFR_RNDU, "1.8866424074712365155e-1");
     175    check(643562308, 23100894, MPFR_RNDD, "2.7858762002890447462e1");
     176    check(632549085, 1831935802, MPFR_RNDN, "3.4528998467600230393e-1");
     177    check (1, 1, MPFR_RNDN, "1.0");
     178  
     179    check0();
     180  
     181    check_nan_inf_mpq ();
     182  
     183    tests_end_mpfr ();
     184    return 0;
     185  }
     186  
     187  #else
     188  
     189  int
     190  main (void)
     191  {
     192    return 77;
     193  }
     194  
     195  #endif