1129202Scognet/* Test mpf_set, mpf_init_set.
2129202Scognet
3129202ScognetCopyright 2004, 2012 Free Software Foundation, Inc.
4129202Scognet
5129202ScognetThis file is part of the GNU MP Library test suite.
6129202Scognet
7129202ScognetThe GNU MP Library test suite is free software; you can redistribute it
8129202Scognetand/or modify it under the terms of the GNU General Public License as
9129202Scognetpublished by the Free Software Foundation; either version 3 of the License,
10129202Scognetor (at your option) any later version.
11129202Scognet
12129202ScognetThe GNU MP Library test suite is distributed in the hope that it will be
13129202Scognetuseful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14255361SandrewMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15129202ScognetPublic License for more details.
16129202Scognet
17129202ScognetYou should have received a copy of the GNU General Public License along with
18164051Scognetthe GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
19164051Scognet
20164051Scognet#include <stdio.h>
21164051Scognet#include <stdlib.h>
22#include "gmp-impl.h"
23#include "tests.h"
24
25void
26check_reuse (void)
27{
28  /* Try mpf_set(f,f) when f is bigger than prec.  In the past this had
29     resulted in an MPN_COPY with invalid operand overlap. */
30  mpf_t  f;
31  mp_size_t      limbs = 20;
32  unsigned long  bits = limbs * GMP_NUMB_BITS;
33  mpf_init2 (f, bits);
34  refmpf_fill (f, limbs, GMP_NUMB_MAX);
35  mpf_set_prec_raw (f, bits / 2);
36  mpf_set (f, f);
37  MPF_CHECK_FORMAT (f);
38  mpf_set_prec_raw (f, bits);
39  mpf_clear (f);
40}
41
42void
43check_random (long reps)
44{
45  unsigned long test;
46  gmp_randstate_ptr rands;
47  mpf_t a, b;
48  mpz_t z;
49  int precbits;
50
51#define PRECBITS 10
52
53  rands = RANDS;
54
55  mpz_init (z);
56  mpf_init2 (a, 1 << PRECBITS);
57
58  for (test = 0; test < reps; test++)
59    {
60      mpz_urandomb (z, rands, PRECBITS + 1);
61      precbits = mpz_get_ui (z) + 1;
62      mpz_urandomb (z, rands, precbits);
63      mpz_setbit (z, precbits  - 1);	/* make sure msb is set */
64      mpf_set_z (a, z);
65      if (precbits & 1)
66	mpf_neg (a, a);
67      mpz_urandomb (z, rands, PRECBITS);
68      mpf_div_2exp (a, a, mpz_get_ui (z) + 1);
69      mpz_urandomb (z, rands, PRECBITS);
70      precbits -= mpz_get_ui (z);
71      if (precbits <= 0)
72	precbits = 1 - precbits;
73      mpf_set_default_prec (precbits);
74
75      mpf_init_set (b, a);
76      MPF_CHECK_FORMAT (b);
77      if (!mpf_eq (a, b, precbits))
78	{
79	  printf ("mpf_init_set wrong.\n");
80	  abort();
81	}
82
83      mpf_set_ui (b, 0);
84      mpf_set (b, a);
85      MPF_CHECK_FORMAT (b);
86      if (!mpf_eq (a, b, precbits))
87	{
88	  printf ("mpf_set wrong.\n");
89	  abort();
90	}
91
92      mpf_clear (b);
93    }
94
95  mpf_clear (a);
96  mpz_clear (z);
97}
98
99int
100main (int argc, char *argv[])
101{
102  long reps = 10000;
103
104  tests_start ();
105  TESTS_REPS (reps, argv, argc);
106
107  check_reuse ();
108  check_random (reps);
109
110  tests_end ();
111  exit (0);
112}
113