1/* Test file for mpfr_check.
2
3Copyright 2003-2004, 2006-2023 Free Software Foundation, Inc.
4Contributed by the AriC and Caramba projects, INRIA.
5
6This file is part of the GNU MPFR Library.
7
8The GNU MPFR Library is free software; you can redistribute it and/or modify
9it under the terms of the GNU Lesser General Public License as published by
10the Free Software Foundation; either version 3 of the License, or (at your
11option) any later version.
12
13The GNU MPFR Library is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16License for more details.
17
18You should have received a copy of the GNU Lesser General Public License
19along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22
23#include "mpfr-test.h"
24
25#define PRINT_ERROR(s)                                                \
26  (printf ("mpfr_check failed " s " Prec=%lu\n", (unsigned long) pr), \
27   exit(1))
28
29int
30main (void)
31{
32  mpfr_t a;
33  mp_limb_t *p, tmp;
34  mp_size_t s;
35  mpfr_prec_t pr;
36  int max;
37
38  tests_start_mpfr ();
39  for (pr = MPFR_PREC_MIN ; pr < 500 ; pr++)
40    {
41      mpfr_init2 (a, pr);
42      if (!mpfr_check (a))
43        PRINT_ERROR ("for init");
44      /* Check special cases */
45      MPFR_SET_NAN (a);
46      if (!mpfr_check (a))
47        PRINT_ERROR ("for nan");
48      MPFR_SET_POS (a);
49      MPFR_SET_INF (a);
50      if (!mpfr_check (a))
51        PRINT_ERROR ("for inf");
52      MPFR_SET_ZERO (a);
53      if (!mpfr_check (a))
54        PRINT_ERROR ("for zero");
55      MPFR_EXP (a) = MPFR_EXP_MIN;
56      if (mpfr_check (a))
57        PRINT_ERROR ("for EXP = MPFR_EXP_MIN");
58      /* Check var */
59      mpfr_set_ui (a, 2, MPFR_RNDN);
60      if (!mpfr_check (a))
61        PRINT_ERROR ("for set_ui");
62      mpfr_clear_overflow ();
63      max = 1000; /* Allows max 2^1000 bits for the exponent */
64      while (!mpfr_overflow_p () && max > 0)
65        {
66          /* this call to mpfr_mul with identical arguments is intentional,
67             and should not be replaced by mpfr_sqr */
68          mpfr_mul (a, a, a, MPFR_RNDN);
69          if (!mpfr_check (a))
70            PRINT_ERROR ("for mul");
71          max--;
72        }
73      if (max == 0)
74        PRINT_ERROR ("for overflow");
75      mpfr_set_ui (a, 2137, MPFR_RNDN);
76      /* Corrupt a and check for it */
77      MPFR_SIGN (a) = 2;
78      if (mpfr_check (a))
79        PRINT_ERROR ("sgn");
80      MPFR_SET_POS (a);
81      /* Check prec */
82      MPFR_PREC (a) = MPFR_PREC_MIN - 1;
83      if (mpfr_check (a))  PRINT_ERROR ("precmin");
84#if MPFR_VERSION_MAJOR < 3
85      /* Disable the test with MPFR >= 3 since mpfr_prec_t is now signed.
86         The "if" below is sufficient, but the MPFR_PREC_MAX+1 generates
87         a warning with GCC 4.4.4 even though the test is always false. */
88      if ((mpfr_prec_t) 0 - 1 > 0)
89        {
90          MPFR_PREC (a) = MPFR_PREC_MAX + 1;
91          if (mpfr_check (a))
92            PRINT_ERROR ("precmax");
93        }
94#endif
95      MPFR_PREC (a) = pr;
96      if (!mpfr_check (a))
97        PRINT_ERROR ("prec");
98      /* Check exponent */
99      MPFR_EXP (a) = MPFR_EXP_INVALID;
100      if (mpfr_check(a))
101        PRINT_ERROR ("exp invalid");
102      MPFR_EXP (a) = -MPFR_EXP_INVALID;
103      if (mpfr_check(a))
104        PRINT_ERROR ("-exp invalid");
105      MPFR_EXP(a) = 0;
106      if (!mpfr_check(a)) PRINT_ERROR ("exp 0");
107      /* Check Mantissa */
108      p = MPFR_MANT(a);
109      MPFR_MANT (a) = NULL;
110      if (mpfr_check (a))
111        PRINT_ERROR ("Mantissa Null Ptr");
112      MPFR_MANT (a) = p;
113      /* Check size */
114      s = MPFR_GET_ALLOC_SIZE (a);
115      MPFR_SET_ALLOC_SIZE (a, 0);
116      if (mpfr_check (a))
117        PRINT_ERROR ("0 size");
118      MPFR_SET_ALLOC_SIZE (a, MP_SIZE_T_MIN);
119      if (mpfr_check (a))  PRINT_ERROR ("min size");
120      MPFR_SET_ALLOC_SIZE (a, MPFR_LIMB_SIZE (a) - 1);
121      if (mpfr_check (a))
122        PRINT_ERROR ("size < prec");
123      MPFR_SET_ALLOC_SIZE (a, s);
124      /* Check normal form */
125      tmp = MPFR_MANT (a)[0];
126      if ((pr % GMP_NUMB_BITS) != 0)
127        {
128          MPFR_MANT(a)[0] = MPFR_LIMB_MAX;
129          if (mpfr_check (a))
130            PRINT_ERROR ("last bits non 0");
131        }
132      MPFR_MANT(a)[0] = tmp;
133      MPFR_MANT(a)[MPFR_LIMB_SIZE(a)-1] &= MPFR_LIMB_MASK (GMP_NUMB_BITS-1);
134      if (mpfr_check (a))
135        PRINT_ERROR ("last bits non 0");
136      /* Final */
137      mpfr_set_ui (a, 2137, MPFR_RNDN);
138      if (!mpfr_check (a))
139        PRINT_ERROR ("after last set");
140      mpfr_clear (a);
141      if (mpfr_check (a))
142        PRINT_ERROR ("after clear");
143    }
144  tests_end_mpfr ();
145  return 0;
146}
147