1/* Test file for mpfr_sqr.
2
3Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4Contributed by the Arenaire and Cacao 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
20http://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 <stdio.h>
24#include <stdlib.h>
25
26#include "mpfr-test.h"
27
28#define TEST_FUNCTION mpfr_sqr
29#include "tgeneric.c"
30
31static int
32inexact_sign (int x)
33{
34  return (x < 0) ? -1 : (x > 0);
35}
36
37static void
38error1 (mpfr_rnd_t rnd, mpfr_prec_t prec,
39        mpfr_t in, mpfr_t outmul, mpfr_t outsqr)
40{
41  printf("ERROR: for %s and prec=%lu\nINPUT=", mpfr_print_rnd_mode(rnd), prec);
42  mpfr_dump(in);
43  printf("OutputMul="); mpfr_dump(outmul);
44  printf("OutputSqr="); mpfr_dump(outsqr);
45  exit(1);
46}
47
48static void
49error2 (mpfr_rnd_t rnd, mpfr_prec_t prec, mpfr_t in, mpfr_t out,
50        int inexactmul, int inexactsqr)
51{
52  printf("ERROR: for %s and prec=%lu\nINPUT=", mpfr_print_rnd_mode(rnd), prec);
53  mpfr_dump(in);
54  printf("Output="); mpfr_dump(out);
55  printf("InexactMul= %d InexactSqr= %d\n", inexactmul, inexactsqr);
56  exit(1);
57}
58
59static void
60check_random (mpfr_prec_t p)
61{
62  mpfr_t x,y,z;
63  int r;
64  int i, inexact1, inexact2;
65
66  mpfr_inits2 (p, x, y, z, (mpfr_ptr) 0);
67  for(i = 0 ; i < 500 ; i++)
68    {
69      mpfr_urandomb (x, RANDS);
70      if (MPFR_IS_PURE_FP(x))
71        for (r = 0 ; r < MPFR_RND_MAX ; r++)
72          {
73            inexact1 = mpfr_mul (y, x, x, (mpfr_rnd_t) r);
74            inexact2 = mpfr_sqr (z, x, (mpfr_rnd_t) r);
75            if (mpfr_cmp (y, z))
76              error1 ((mpfr_rnd_t) r,p,x,y,z);
77            if (inexact_sign (inexact1) != inexact_sign (inexact2))
78              error2 ((mpfr_rnd_t) r,p,x,y,inexact1,inexact2);
79          }
80    }
81  mpfr_clears (x, y, z, (mpfr_ptr) 0);
82}
83
84static void
85check_special (void)
86{
87  mpfr_t x, y;
88  mpfr_exp_t emin;
89
90  mpfr_init (x);
91  mpfr_init (y);
92
93  mpfr_set_nan (x);
94  mpfr_sqr (y, x, MPFR_RNDN);
95  MPFR_ASSERTN (mpfr_nan_p (y));
96
97  mpfr_set_inf (x, 1);
98  mpfr_sqr (y, x, MPFR_RNDN);
99  MPFR_ASSERTN (mpfr_inf_p (y) && mpfr_sgn (y) > 0);
100
101  mpfr_set_inf (x, -1);
102  mpfr_sqr (y, x, MPFR_RNDN);
103  MPFR_ASSERTN (mpfr_inf_p (y) && mpfr_sgn (y) > 0);
104
105  mpfr_set_ui (x, 0, MPFR_RNDN);
106  mpfr_sqr (y, x, MPFR_RNDN);
107  MPFR_ASSERTN (mpfr_zero_p (y));
108
109  emin = mpfr_get_emin ();
110  mpfr_set_emin (0);
111  mpfr_set_ui (x, 1, MPFR_RNDN);
112  mpfr_div_2ui (x, x, 1, MPFR_RNDN);
113  MPFR_ASSERTN (!mpfr_zero_p (x));
114  mpfr_sqr (y, x, MPFR_RNDN);
115  MPFR_ASSERTN (mpfr_zero_p (y));
116  mpfr_set_emin (emin);
117
118  mpfr_clear (y);
119  mpfr_clear (x);
120}
121
122int
123main (void)
124{
125  mpfr_prec_t p;
126
127  tests_start_mpfr ();
128
129  check_special ();
130  for (p = 2; p < 200; p++)
131    check_random (p);
132
133  test_generic (2, 200, 15);
134  data_check ("data/sqr", mpfr_sqr, "mpfr_sqr");
135  bad_cases (mpfr_sqr, mpfr_sqrt, "mpfr_sqr", 8, -256, 255, 4, 128, 800, 50);
136
137  tests_end_mpfr ();
138  return 0;
139}
140