(root)/
mpfr-4.2.1/
tests/
tget_q.c
       1  /* Test file for mpfr_get_q.
       2  
       3  Copyright 2017-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  special (void)
      29  {
      30    mpfr_t f;
      31    mpq_t q;
      32  
      33    mpfr_init2 (f, MPFR_PREC_MIN);
      34    mpq_init (q);
      35  
      36    /* check NaN */
      37    mpfr_set_nan (f);
      38    mpfr_clear_erangeflag ();
      39    mpfr_get_q (q, f);
      40    MPFR_ASSERTN(mpq_cmp_ui (q, 0, 1) == 0);
      41    MPFR_ASSERTN(mpfr_erangeflag_p ());
      42  
      43    /* check +Inf */
      44    mpfr_set_inf (f, 1);
      45    mpfr_clear_erangeflag ();
      46    mpfr_get_q (q, f);
      47    MPFR_ASSERTN(mpq_cmp_ui (q, 0, 1) == 0);
      48    MPFR_ASSERTN(mpfr_erangeflag_p ());
      49  
      50    /* check -Inf */
      51    mpfr_set_inf (f, -1);
      52    mpfr_clear_erangeflag ();
      53    mpfr_get_q (q, f);
      54    MPFR_ASSERTN(mpq_cmp_ui (q, 0, 1) == 0);
      55    MPFR_ASSERTN(mpfr_erangeflag_p ());
      56  
      57    /* check +0 */
      58    mpfr_set_zero (f, 1);
      59    mpfr_clear_erangeflag ();
      60    mpfr_get_q (q, f);
      61    MPFR_ASSERTN(mpq_cmp_ui (q, 0, 1) == 0);
      62    MPFR_ASSERTN(!mpfr_erangeflag_p ());
      63  
      64    /* check -0 */
      65    mpfr_set_zero (f, -1);
      66    mpfr_clear_erangeflag ();
      67    mpfr_get_q (q, f);
      68    MPFR_ASSERTN(mpq_cmp_ui (q, 0, 1) == 0);
      69    MPFR_ASSERTN(!mpfr_erangeflag_p ());
      70  
      71    mpq_clear (q);
      72    mpfr_clear (f);
      73  }
      74  
      75  static void
      76  random_tests (void)
      77  {
      78    mpfr_t f, g;
      79    mpq_t q;
      80    int inex;
      81    mpfr_rnd_t rnd;
      82    int i;
      83  
      84    mpfr_init2 (f, MPFR_PREC_MIN + (randlimb() % 100));
      85    mpfr_init2 (g, mpfr_get_prec (f));
      86    mpq_init (q);
      87  
      88    for (i = 0; i < 1000; i++)
      89      {
      90        mpfr_urandomb (f, RANDS);
      91        mpfr_get_q (q, f);
      92        rnd = RND_RAND ();
      93        inex = mpfr_set_q (g, q, rnd);
      94        MPFR_ASSERTN(inex == 0);
      95        MPFR_ASSERTN(mpfr_cmp (f, g) == 0);
      96      }
      97  
      98    mpq_clear (q);
      99    mpfr_clear (f);
     100    mpfr_clear (g);
     101  }
     102  
     103  /* Check results are in canonical form.
     104     See https://sympa.inria.fr/sympa/arc/mpfr/2017-12/msg00029.html */
     105  static void
     106  check_canonical (void)
     107  {
     108    mpfr_t x;
     109    mpq_t q;
     110    mpz_t z;
     111  
     112    mpfr_init2 (x, 53);
     113    mpfr_set_ui (x, 3, MPFR_RNDN);
     114    mpq_init (q);
     115    mpfr_get_q (q, x);
     116    /* check the denominator is positive */
     117    if (mpz_sgn (mpq_denref (q)) <= 0)
     118      {
     119        printf ("Error, the denominator of mpfr_get_q should be positive\n");
     120        exit (1);
     121      }
     122    mpz_init (z);
     123    mpz_gcd (z, mpq_numref (q), mpq_denref (q));
     124    /* check the numerator and denominator are coprime */
     125    if (mpz_cmp_ui (z, 1) != 0)
     126      {
     127        printf ("Error, numerator and denominator of mpfr_get_q should be coprime\n");
     128        exit (1);
     129      }
     130    mpfr_clear (x);
     131    mpq_clear (q);
     132    mpz_clear (z);
     133  }
     134  
     135  static void
     136  coverage (void)
     137  {
     138    mpfr_t x;
     139    mpq_t q;
     140    mpz_t z;
     141  
     142    mpfr_init2 (x, 5);
     143    mpq_init (q);
     144    mpz_init (z);
     145  
     146    mpfr_set_ui_2exp (x, 17, 100, MPFR_RNDN);
     147    mpfr_get_q (q, x);
     148    MPFR_ASSERTN(mpz_cmp_ui (mpq_denref (q), 1) == 0);
     149    mpz_set_ui (z, 17);
     150    mpz_mul_2exp (z, z, 100);
     151    MPFR_ASSERTN(mpz_cmp (mpq_numref (q), z) == 0);
     152  
     153    mpfr_clear (x);
     154    mpq_clear (q);
     155    mpz_clear (z);
     156  }
     157  
     158  int
     159  main (void)
     160  {
     161    tests_start_mpfr ();
     162  
     163    coverage ();
     164    special ();
     165    random_tests ();
     166  
     167    check_canonical ();
     168  
     169    tests_end_mpfr ();
     170    return 0;
     171  }
     172  
     173  #else
     174  
     175  int
     176  main (void)
     177  {
     178    return 77;
     179  }
     180  
     181  #endif /* MPFR_USE_MINI_GMP */