Blame tests/tsqr.c

Packit 80c72f
/* tsqr -- test file for mpc_sqr.
Packit 80c72f
Packit 80c72f
Copyright (C) 2002, 2005, 2008, 2010, 2011 INRIA
Packit 80c72f
Packit 80c72f
This file is part of GNU MPC.
Packit 80c72f
Packit 80c72f
GNU MPC is free software; you can redistribute it and/or modify it under
Packit 80c72f
the terms of the GNU Lesser General Public License as published by the
Packit 80c72f
Free Software Foundation; either version 3 of the License, or (at your
Packit 80c72f
option) any later version.
Packit 80c72f
Packit 80c72f
GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
Packit 80c72f
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
Packit 80c72f
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
Packit 80c72f
more details.
Packit 80c72f
Packit 80c72f
You should have received a copy of the GNU Lesser General Public License
Packit 80c72f
along with this program. If not, see http://www.gnu.org/licenses/ .
Packit 80c72f
*/
Packit 80c72f
Packit 80c72f
#include <stdlib.h>
Packit 80c72f
#include "mpc-tests.h"
Packit 80c72f
Packit 80c72f
static void
Packit 80c72f
cmpsqr (mpc_srcptr x, mpc_rnd_t rnd)
Packit 80c72f
   /* computes the square of x with the specific function or by simple     */
Packit 80c72f
   /* multiplication using the rounding mode rnd and compares the results  */
Packit 80c72f
   /* and return values.                                                   */
Packit 80c72f
   /* In our current test suite, the real and imaginary parts of x have    */
Packit 80c72f
   /* the same precision, and we use this precision also for the result.   */
Packit 80c72f
   /* Furthermore, we check whether computing the square in the same       */
Packit 80c72f
   /* place yields the same result.                                        */
Packit 80c72f
   /* We also compute the result with four times the precision and check   */
Packit 80c72f
   /* whether the rounding is correct. Error reports in this part of the   */
Packit 80c72f
   /* algorithm might still be wrong, though, since there are two          */
Packit 80c72f
   /* consecutive roundings.                                               */
Packit 80c72f
{
Packit 80c72f
  mpc_t z, t, u;
Packit 80c72f
  int   inexact_z, inexact_t;
Packit 80c72f
Packit 80c72f
  mpc_init2 (z, MPC_MAX_PREC (x));
Packit 80c72f
  mpc_init2 (t, MPC_MAX_PREC (x));
Packit 80c72f
  mpc_init2 (u, 4 * MPC_MAX_PREC (x));
Packit 80c72f
Packit 80c72f
  inexact_z = mpc_sqr (z, x, rnd);
Packit 80c72f
  inexact_t = mpc_mul (t, x, x, rnd);
Packit 80c72f
Packit 80c72f
  if (mpc_cmp (z, t))
Packit 80c72f
    {
Packit 80c72f
      fprintf (stderr, "sqr and mul differ for rnd=(%s,%s) \nx=",
Packit 80c72f
               mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
Packit 80c72f
               mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
Packit 80c72f
      mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
Packit 80c72f
      fprintf (stderr, "\nmpc_sqr gives ");
Packit 80c72f
      mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
Packit 80c72f
      fprintf (stderr, "\nmpc_mul gives ");
Packit 80c72f
      mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
Packit 80c72f
      fprintf (stderr, "\n");
Packit 80c72f
      exit (1);
Packit 80c72f
    }
Packit 80c72f
  if (inexact_z != inexact_t)
Packit 80c72f
    {
Packit 80c72f
      fprintf (stderr, "The return values of sqr and mul differ for rnd=(%s,%s) \nx=  ",
Packit 80c72f
               mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
Packit 80c72f
               mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
Packit 80c72f
      mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
Packit 80c72f
      fprintf (stderr, "\nx^2=");
Packit 80c72f
      mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
Packit 80c72f
      fprintf (stderr, "\nmpc_sqr gives %i", inexact_z);
Packit 80c72f
      fprintf (stderr, "\nmpc_mul gives %i", inexact_t);
Packit 80c72f
      fprintf (stderr, "\n");
Packit 80c72f
      exit (1);
Packit 80c72f
    }
Packit 80c72f
Packit 80c72f
  mpc_set (t, x, MPC_RNDNN);
Packit 80c72f
  inexact_t = mpc_sqr (t, t, rnd);
Packit 80c72f
  if (mpc_cmp (z, t))
Packit 80c72f
    {
Packit 80c72f
      fprintf (stderr, "sqr and sqr in place differ for rnd=(%s,%s) \nx=",
Packit 80c72f
               mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
Packit 80c72f
               mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
Packit 80c72f
      mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
Packit 80c72f
      fprintf (stderr, "\nmpc_sqr          gives ");
Packit 80c72f
      mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
Packit 80c72f
      fprintf (stderr, "\nmpc_sqr in place gives ");
Packit 80c72f
      mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
Packit 80c72f
      fprintf (stderr, "\n");
Packit 80c72f
      exit (1);
Packit 80c72f
    }
Packit 80c72f
  if (inexact_z != inexact_t)
Packit 80c72f
    {
Packit 80c72f
      fprintf (stderr, "The return values of sqr and sqr in place differ for rnd=(%s,%s) \nx=  ",
Packit 80c72f
               mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
Packit 80c72f
               mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
Packit 80c72f
      mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
Packit 80c72f
      fprintf (stderr, "\nx^2=");
Packit 80c72f
      mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
Packit 80c72f
      fprintf (stderr, "\nmpc_sqr          gives %i", inexact_z);
Packit 80c72f
      fprintf (stderr, "\nmpc_sqr in place gives %i", inexact_t);
Packit 80c72f
      fprintf (stderr, "\n");
Packit 80c72f
      exit (1);
Packit 80c72f
    }
Packit 80c72f
Packit 80c72f
  mpc_sqr (u, x, rnd);
Packit 80c72f
  mpc_set (t, u, rnd);
Packit 80c72f
  if (mpc_cmp (z, t))
Packit 80c72f
    {
Packit 80c72f
      fprintf (stderr, "rounding in sqr might be incorrect for rnd=(%s,%s) \nx=",
Packit 80c72f
               mpfr_print_rnd_mode(MPC_RND_RE(rnd)),
Packit 80c72f
               mpfr_print_rnd_mode(MPC_RND_IM(rnd)));
Packit 80c72f
      mpc_out_str (stderr, 2, 0, x, MPC_RNDNN);
Packit 80c72f
      fprintf (stderr, "\nmpc_sqr                     gives ");
Packit 80c72f
      mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
Packit 80c72f
      fprintf (stderr, "\nmpc_sqr quadruple precision gives ");
Packit 80c72f
      mpc_out_str (stderr, 2, 0, u, MPC_RNDNN);
Packit 80c72f
      fprintf (stderr, "\nand is rounded to                 ");
Packit 80c72f
      mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
Packit 80c72f
      fprintf (stderr, "\n");
Packit 80c72f
      exit (1);
Packit 80c72f
    }
Packit 80c72f
Packit 80c72f
  mpc_clear (z);
Packit 80c72f
  mpc_clear (t);
Packit 80c72f
  mpc_clear (u);
Packit 80c72f
}
Packit 80c72f
Packit 80c72f
Packit 80c72f
static void
Packit 80c72f
testsqr (long a, long b, mpfr_prec_t prec, mpc_rnd_t rnd)
Packit 80c72f
{
Packit 80c72f
  mpc_t x;
Packit 80c72f
Packit 80c72f
  mpc_init2 (x, prec);
Packit 80c72f
Packit 80c72f
  mpc_set_si_si (x, a, b, rnd);
Packit 80c72f
Packit 80c72f
  cmpsqr (x, rnd);
Packit 80c72f
Packit 80c72f
  mpc_clear (x);
Packit 80c72f
}
Packit 80c72f
Packit 80c72f
Packit 80c72f
static void
Packit 80c72f
reuse_bug (void)
Packit 80c72f
{
Packit 80c72f
  mpc_t z1;
Packit 80c72f
Packit 80c72f
  /* reuse bug found by Paul Zimmermann 20081021 */
Packit 80c72f
  mpc_init2 (z1, 2);
Packit 80c72f
  /* RE (z1^2) overflows, IM(z^2) = -0 */
Packit 80c72f
  mpfr_set_str (mpc_realref (z1), "0.11", 2, GMP_RNDN);
Packit 80c72f
  mpfr_mul_2si (mpc_realref (z1), mpc_realref (z1), mpfr_get_emax (), GMP_RNDN);
Packit 80c72f
  mpfr_set_ui (mpc_imagref (z1), 0, GMP_RNDN);
Packit 80c72f
  mpc_conj (z1, z1, MPC_RNDNN);
Packit 80c72f
  mpc_sqr (z1, z1, MPC_RNDNN);
Packit 80c72f
  if (!mpfr_inf_p (mpc_realref (z1)) || mpfr_signbit (mpc_realref (z1))
Packit 80c72f
      ||!mpfr_zero_p (mpc_imagref (z1)) || !mpfr_signbit (mpc_imagref (z1)))
Packit 80c72f
    {
Packit 80c72f
      printf ("Error: Regression, bug 20081021 reproduced\n");
Packit 80c72f
      MPC_OUT (z1);
Packit 80c72f
      exit (1);
Packit 80c72f
    }
Packit 80c72f
Packit 80c72f
  mpc_clear (z1);
Packit 80c72f
}
Packit 80c72f
Packit 80c72f
int
Packit 80c72f
main (void)
Packit 80c72f
{
Packit 80c72f
  DECL_FUNC (CC, f, mpc_sqr);
Packit 80c72f
  test_start ();
Packit 80c72f
Packit 80c72f
  testsqr (247, -65, 8, 24);
Packit 80c72f
  testsqr (5, -896, 3, 2);
Packit 80c72f
  testsqr (-3, -512, 2, 16);
Packit 80c72f
  testsqr (266013312, 121990769, 27, 0);
Packit 80c72f
  testsqr (170, 9, 8, 0);
Packit 80c72f
  testsqr (768, 85, 8, 16);
Packit 80c72f
  testsqr (145, 1816, 8, 24);
Packit 80c72f
  testsqr (0, 1816, 8, 24);
Packit 80c72f
  testsqr (145, 0, 8, 24);
Packit 80c72f
Packit 80c72f
  data_check (f, "sqr.dat");
Packit 80c72f
  tgeneric (f, 2, 1024, 1, 0);
Packit 80c72f
Packit 80c72f
  reuse_bug ();
Packit 80c72f
Packit 80c72f
  test_end ();
Packit 80c72f
Packit 80c72f
  return 0;
Packit 80c72f
}