18fa80f29Smrg /* tsqr -- test file for mpc_sqr.
28fa80f29Smrg
3*39f28e1eSmrg Copyright (C) 2002, 2005, 2008, 2010, 2011, 2012, 2013 INRIA
48fa80f29Smrg
58fa80f29Smrg This file is part of GNU MPC.
68fa80f29Smrg
78fa80f29Smrg GNU MPC is free software; you can redistribute it and/or modify it under
88fa80f29Smrg the terms of the GNU Lesser General Public License as published by the
98fa80f29Smrg Free Software Foundation; either version 3 of the License, or (at your
108fa80f29Smrg option) any later version.
118fa80f29Smrg
128fa80f29Smrg GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
138fa80f29Smrg WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
148fa80f29Smrg FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
158fa80f29Smrg more details.
168fa80f29Smrg
178fa80f29Smrg You should have received a copy of the GNU Lesser General Public License
188fa80f29Smrg along with this program. If not, see http://www.gnu.org/licenses/ .
198fa80f29Smrg */
208fa80f29Smrg
218fa80f29Smrg #include <stdlib.h>
228fa80f29Smrg #include "mpc-tests.h"
238fa80f29Smrg
248fa80f29Smrg static void
cmpsqr(mpc_srcptr x,mpc_rnd_t rnd)258fa80f29Smrg cmpsqr (mpc_srcptr x, mpc_rnd_t rnd)
268fa80f29Smrg /* computes the square of x with the specific function or by simple */
278fa80f29Smrg /* multiplication using the rounding mode rnd and compares the results */
288fa80f29Smrg /* and return values. */
298fa80f29Smrg /* In our current test suite, the real and imaginary parts of x have */
308fa80f29Smrg /* the same precision, and we use this precision also for the result. */
318fa80f29Smrg /* Furthermore, we check whether computing the square in the same */
328fa80f29Smrg /* place yields the same result. */
338fa80f29Smrg /* We also compute the result with four times the precision and check */
348fa80f29Smrg /* whether the rounding is correct. Error reports in this part of the */
358fa80f29Smrg /* algorithm might still be wrong, though, since there are two */
368fa80f29Smrg /* consecutive roundings. */
378fa80f29Smrg {
388fa80f29Smrg mpc_t z, t, u;
398fa80f29Smrg int inexact_z, inexact_t;
408fa80f29Smrg
418fa80f29Smrg mpc_init2 (z, MPC_MAX_PREC (x));
428fa80f29Smrg mpc_init2 (t, MPC_MAX_PREC (x));
438fa80f29Smrg mpc_init2 (u, 4 * MPC_MAX_PREC (x));
448fa80f29Smrg
458fa80f29Smrg inexact_z = mpc_sqr (z, x, rnd);
468fa80f29Smrg inexact_t = mpc_mul (t, x, x, rnd);
478fa80f29Smrg
488fa80f29Smrg if (mpc_cmp (z, t))
498fa80f29Smrg {
508fa80f29Smrg fprintf (stderr, "sqr and mul differ for rnd=(%s,%s) \nx=",
518fa80f29Smrg mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
528fa80f29Smrg mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
538fa80f29Smrg mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
548fa80f29Smrg fprintf (stderr, "\nmpc_sqr gives ");
558fa80f29Smrg mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
568fa80f29Smrg fprintf (stderr, "\nmpc_mul gives ");
578fa80f29Smrg mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
588fa80f29Smrg fprintf (stderr, "\n");
598fa80f29Smrg exit (1);
608fa80f29Smrg }
618fa80f29Smrg if (inexact_z != inexact_t)
628fa80f29Smrg {
638fa80f29Smrg fprintf (stderr, "The return values of sqr and mul differ for rnd=(%s,%s) \nx= ",
648fa80f29Smrg mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
658fa80f29Smrg mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
668fa80f29Smrg mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
678fa80f29Smrg fprintf (stderr, "\nx^2=");
688fa80f29Smrg mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
698fa80f29Smrg fprintf (stderr, "\nmpc_sqr gives %i", inexact_z);
708fa80f29Smrg fprintf (stderr, "\nmpc_mul gives %i", inexact_t);
718fa80f29Smrg fprintf (stderr, "\n");
728fa80f29Smrg exit (1);
738fa80f29Smrg }
748fa80f29Smrg
758fa80f29Smrg mpc_set (t, x, MPC_RNDNN);
768fa80f29Smrg inexact_t = mpc_sqr (t, t, rnd);
778fa80f29Smrg if (mpc_cmp (z, t))
788fa80f29Smrg {
798fa80f29Smrg fprintf (stderr, "sqr and sqr in place differ for rnd=(%s,%s) \nx=",
808fa80f29Smrg mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
818fa80f29Smrg mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
828fa80f29Smrg mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
838fa80f29Smrg fprintf (stderr, "\nmpc_sqr gives ");
848fa80f29Smrg mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
858fa80f29Smrg fprintf (stderr, "\nmpc_sqr in place gives ");
868fa80f29Smrg mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
878fa80f29Smrg fprintf (stderr, "\n");
888fa80f29Smrg exit (1);
898fa80f29Smrg }
908fa80f29Smrg if (inexact_z != inexact_t)
918fa80f29Smrg {
928fa80f29Smrg fprintf (stderr, "The return values of sqr and sqr in place differ for rnd=(%s,%s) \nx= ",
938fa80f29Smrg mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
948fa80f29Smrg mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
958fa80f29Smrg mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
968fa80f29Smrg fprintf (stderr, "\nx^2=");
978fa80f29Smrg mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
988fa80f29Smrg fprintf (stderr, "\nmpc_sqr gives %i", inexact_z);
998fa80f29Smrg fprintf (stderr, "\nmpc_sqr in place gives %i", inexact_t);
1008fa80f29Smrg fprintf (stderr, "\n");
1018fa80f29Smrg exit (1);
1028fa80f29Smrg }
1038fa80f29Smrg
1048fa80f29Smrg mpc_sqr (u, x, rnd);
1058fa80f29Smrg mpc_set (t, u, rnd);
1068fa80f29Smrg if (mpc_cmp (z, t))
1078fa80f29Smrg {
1088fa80f29Smrg fprintf (stderr, "rounding in sqr might be incorrect for rnd=(%s,%s) \nx=",
1098fa80f29Smrg mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
1108fa80f29Smrg mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
1118fa80f29Smrg mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
1128fa80f29Smrg fprintf (stderr, "\nmpc_sqr gives ");
1138fa80f29Smrg mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
1148fa80f29Smrg fprintf (stderr, "\nmpc_sqr quadruple precision gives ");
1158fa80f29Smrg mpc_out_str (stderr, 2, 0, u, MPC_RNDNN);
1168fa80f29Smrg fprintf (stderr, "\nand is rounded to ");
1178fa80f29Smrg mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
1188fa80f29Smrg fprintf (stderr, "\n");
1198fa80f29Smrg exit (1);
1208fa80f29Smrg }
1218fa80f29Smrg
1228fa80f29Smrg mpc_clear (z);
1238fa80f29Smrg mpc_clear (t);
1248fa80f29Smrg mpc_clear (u);
1258fa80f29Smrg }
1268fa80f29Smrg
1278fa80f29Smrg
1288fa80f29Smrg static void
testsqr(long a,long b,mpfr_prec_t prec,mpc_rnd_t rnd)1298fa80f29Smrg testsqr (long a, long b, mpfr_prec_t prec, mpc_rnd_t rnd)
1308fa80f29Smrg {
1318fa80f29Smrg mpc_t x;
1328fa80f29Smrg
1338fa80f29Smrg mpc_init2 (x, prec);
1348fa80f29Smrg
1358fa80f29Smrg mpc_set_si_si (x, a, b, rnd);
1368fa80f29Smrg
1378fa80f29Smrg cmpsqr (x, rnd);
1388fa80f29Smrg
1398fa80f29Smrg mpc_clear (x);
1408fa80f29Smrg }
1418fa80f29Smrg
1428fa80f29Smrg
1438fa80f29Smrg static void
reuse_bug(void)1448fa80f29Smrg reuse_bug (void)
1458fa80f29Smrg {
1468fa80f29Smrg mpc_t z1;
1478fa80f29Smrg
1488fa80f29Smrg /* reuse bug found by Paul Zimmermann 20081021 */
1498fa80f29Smrg mpc_init2 (z1, 2);
1508fa80f29Smrg /* RE (z1^2) overflows, IM(z^2) = -0 */
151*39f28e1eSmrg mpfr_set_str (mpc_realref (z1), "0.11", 2, MPFR_RNDN);
152*39f28e1eSmrg mpfr_mul_2si (mpc_realref (z1), mpc_realref (z1), mpfr_get_emax (), MPFR_RNDN);
153*39f28e1eSmrg mpfr_set_ui (mpc_imagref (z1), 0, MPFR_RNDN);
1548fa80f29Smrg mpc_conj (z1, z1, MPC_RNDNN);
1558fa80f29Smrg mpc_sqr (z1, z1, MPC_RNDNN);
1568fa80f29Smrg if (!mpfr_inf_p (mpc_realref (z1)) || mpfr_signbit (mpc_realref (z1))
1578fa80f29Smrg ||!mpfr_zero_p (mpc_imagref (z1)) || !mpfr_signbit (mpc_imagref (z1)))
1588fa80f29Smrg {
1598fa80f29Smrg printf ("Error: Regression, bug 20081021 reproduced\n");
1608fa80f29Smrg MPC_OUT (z1);
1618fa80f29Smrg exit (1);
1628fa80f29Smrg }
1638fa80f29Smrg
1648fa80f29Smrg mpc_clear (z1);
1658fa80f29Smrg }
1668fa80f29Smrg
167*39f28e1eSmrg #define MPC_FUNCTION_CALL \
168*39f28e1eSmrg P[0].mpc_inex = mpc_sqr (P[1].mpc, P[2].mpc, P[3].mpc_rnd)
169*39f28e1eSmrg #define MPC_FUNCTION_CALL_REUSE_OP1 \
170*39f28e1eSmrg P[0].mpc_inex = mpc_sqr (P[1].mpc, P[1].mpc, P[3].mpc_rnd)
171*39f28e1eSmrg
172*39f28e1eSmrg #include "data_check.tpl"
173*39f28e1eSmrg #include "tgeneric.tpl"
174*39f28e1eSmrg
1758fa80f29Smrg int
main(void)1768fa80f29Smrg main (void)
1778fa80f29Smrg {
1788fa80f29Smrg test_start ();
1798fa80f29Smrg
1808fa80f29Smrg testsqr (247, -65, 8, 24);
1818fa80f29Smrg testsqr (5, -896, 3, 2);
1828fa80f29Smrg testsqr (-3, -512, 2, 16);
1838fa80f29Smrg testsqr (266013312, 121990769, 27, 0);
1848fa80f29Smrg testsqr (170, 9, 8, 0);
1858fa80f29Smrg testsqr (768, 85, 8, 16);
1868fa80f29Smrg testsqr (145, 1816, 8, 24);
1878fa80f29Smrg testsqr (0, 1816, 8, 24);
1888fa80f29Smrg testsqr (145, 0, 8, 24);
1898fa80f29Smrg
190*39f28e1eSmrg data_check_template ("sqr.dsc", "sqr.dat");
191*39f28e1eSmrg
192*39f28e1eSmrg tgeneric_template ("sqr.dsc", 2, 1024, 1, 1024);
1938fa80f29Smrg
1948fa80f29Smrg reuse_bug ();
1958fa80f29Smrg
1968fa80f29Smrg test_end ();
1978fa80f29Smrg
1988fa80f29Smrg return 0;
1998fa80f29Smrg }
200