Blame src/cmp_abs.c

Packit Service 2e9770
/* mpc_cmp -- Compare two complex numbers.
Packit Service 2e9770
Packit Service 2e9770
Copyright (C) 2016 INRIA
Packit Service 2e9770
Packit Service 2e9770
This file is part of GNU MPC.
Packit Service 2e9770
Packit Service 2e9770
GNU MPC is free software; you can redistribute it and/or modify it under
Packit Service 2e9770
the terms of the GNU Lesser General Public License as published by the
Packit Service 2e9770
Free Software Foundation; either version 3 of the License, or (at your
Packit Service 2e9770
option) any later version.
Packit Service 2e9770
Packit Service 2e9770
GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
Packit Service 2e9770
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
Packit Service 2e9770
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
Packit Service 2e9770
more details.
Packit Service 2e9770
Packit Service 2e9770
You should have received a copy of the GNU Lesser General Public License
Packit Service 2e9770
along with this program. If not, see http://www.gnu.org/licenses/ .
Packit Service 2e9770
*/
Packit Service 2e9770
Packit Service 2e9770
#include "mpc-impl.h"
Packit Service 2e9770
Packit Service 2e9770
/* return mpfr_cmp (mpc_abs (a), mpc_abs (b)) */
Packit Service 2e9770
int
Packit Service 2e9770
mpc_cmp_abs (mpc_srcptr a, mpc_srcptr b)
Packit Service 2e9770
{
Packit Service 2e9770
   mpc_t z1, z2;
Packit Service 2e9770
   mpfr_t n1, n2;
Packit Service 2e9770
   mpfr_prec_t prec;
Packit Service 2e9770
   int inex1, inex2, ret;
Packit Service 2e9770
Packit Service 2e9770
   /* Handle numbers containing one NaN as mpfr_cmp. */
Packit Service 2e9770
   if (   mpfr_nan_p (mpc_realref (a)) || mpfr_nan_p (mpc_imagref (a))
Packit Service 2e9770
       || mpfr_nan_p (mpc_realref (b)) || mpfr_nan_p (mpc_imagref (b)))
Packit Service 2e9770
     {
Packit Service 2e9770
       mpfr_t nan;
Packit Service 2e9770
       mpfr_init (nan);
Packit Service 2e9770
       mpfr_set_nan (nan);
Packit Service 2e9770
       ret = mpfr_cmp (nan, nan);
Packit Service 2e9770
       mpfr_clear (nan);
Packit Service 2e9770
       return ret;
Packit Service 2e9770
     }
Packit Service 2e9770
Packit Service 2e9770
   /* Handle infinities. */
Packit Service 2e9770
   if (mpc_inf_p (a))
Packit Service 2e9770
      if (mpc_inf_p (b))
Packit Service 2e9770
         return 0;
Packit Service 2e9770
      else
Packit Service 2e9770
         return 1;
Packit Service 2e9770
   else if (mpc_inf_p (b))
Packit Service 2e9770
      return -1;
Packit Service 2e9770
Packit Service 2e9770
   /* Replace all parts of a and b by their absolute values, then order
Packit Service 2e9770
      them by size. */
Packit Service 2e9770
   z1 [0] = a [0];
Packit Service 2e9770
   z2 [0] = b [0];
Packit Service 2e9770
   if (mpfr_signbit (mpc_realref (a)))
Packit Service 2e9770
      MPFR_CHANGE_SIGN (mpc_realref (z1));
Packit Service 2e9770
   if (mpfr_signbit (mpc_imagref (a)))
Packit Service 2e9770
      MPFR_CHANGE_SIGN (mpc_imagref (z1));
Packit Service 2e9770
   if (mpfr_signbit (mpc_realref (b)))
Packit Service 2e9770
      MPFR_CHANGE_SIGN (mpc_realref (z2));
Packit Service 2e9770
   if (mpfr_signbit (mpc_imagref (b)))
Packit Service 2e9770
      MPFR_CHANGE_SIGN (mpc_imagref (z2));
Packit Service 2e9770
   if (mpfr_cmp (mpc_realref (z1), mpc_imagref (z1)) > 0)
Packit Service 2e9770
      mpfr_swap (mpc_realref (z1), mpc_imagref (z1));
Packit Service 2e9770
   if (mpfr_cmp (mpc_realref (z2), mpc_imagref (z2)) > 0)
Packit Service 2e9770
      mpfr_swap (mpc_realref (z2), mpc_imagref (z2));
Packit Service 2e9770
Packit Service 2e9770
   /* Handle cases in which only one part differs. */
Packit Service 2e9770
   if (mpfr_cmp (mpc_realref (z1), mpc_realref (z2)) == 0)
Packit Service 2e9770
      return mpfr_cmp (mpc_imagref (z1), mpc_imagref (z2));
Packit Service 2e9770
   if (mpfr_cmp (mpc_imagref (z1), mpc_imagref (z2)) == 0)
Packit Service 2e9770
      return mpfr_cmp (mpc_realref (z1), mpc_realref (z2));
Packit Service 2e9770
Packit Service 2e9770
   /* Implement the algorithm in algorithms.tex. */
Packit Service 2e9770
   mpfr_init (n1);
Packit Service 2e9770
   mpfr_init (n2);
Packit Service 2e9770
   prec = MPC_MAX (50, MPC_MAX (MPC_MAX_PREC (z1), MPC_MAX_PREC (z2)) / 100);
Packit Service 2e9770
   do {
Packit Service 2e9770
      mpfr_set_prec (n1, prec);
Packit Service 2e9770
      mpfr_set_prec (n2, prec);
Packit Service 2e9770
      inex1 = mpc_norm (n1, z1, MPFR_RNDD);
Packit Service 2e9770
      inex2 = mpc_norm (n2, z2, MPFR_RNDD);
Packit Service 2e9770
      ret = mpfr_cmp (n1, n2);
Packit Service 2e9770
      if (ret != 0)
Packit Service 2e9770
        goto end;
Packit Service 2e9770
      else
Packit Service 2e9770
         if (inex1 == 0) /* n1 = norm(z1) */
Packit Service 2e9770
            if (inex2)   /* n2 < norm(z2) */
Packit Service 2e9770
              {
Packit Service 2e9770
                ret = -1;
Packit Service 2e9770
                goto end;
Packit Service 2e9770
              }
Packit Service 2e9770
            else /* n2 = norm(z2) */
Packit Service 2e9770
              {
Packit Service 2e9770
                ret = 0;
Packit Service 2e9770
                goto end;
Packit Service 2e9770
              }
Packit Service 2e9770
         else /* n1 < norm(z1) */
Packit Service 2e9770
            if (inex2 == 0)
Packit Service 2e9770
              {
Packit Service 2e9770
                ret = 1;
Packit Service 2e9770
                goto end;
Packit Service 2e9770
              }
Packit Service 2e9770
      prec *= 2;
Packit Service 2e9770
   } while (1);
Packit Service 2e9770
 end:
Packit Service 2e9770
   mpfr_clear (n1);
Packit Service 2e9770
   mpfr_clear (n2);
Packit Service 2e9770
   return ret;
Packit Service 2e9770
}
Packit Service 2e9770