(root)/
gmp-6.3.0/
mpf/
eq.c
       1  /* mpf_eq -- Compare two floats up to a specified bit #.
       2  
       3  Copyright 1993, 1995, 1996, 2001, 2002, 2008, 2009, 2012 Free Software
       4  Foundation, Inc.
       5  
       6  This file is part of the GNU MP Library.
       7  
       8  The GNU MP Library is free software; you can redistribute it and/or modify
       9  it under the terms of either:
      10  
      11    * the GNU Lesser General Public License as published by the Free
      12      Software Foundation; either version 3 of the License, or (at your
      13      option) any later version.
      14  
      15  or
      16  
      17    * the GNU General Public License as published by the Free Software
      18      Foundation; either version 2 of the License, or (at your option) any
      19      later version.
      20  
      21  or both in parallel, as here.
      22  
      23  The GNU MP Library is distributed in the hope that it will be useful, but
      24  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      25  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      26  for more details.
      27  
      28  You should have received copies of the GNU General Public License and the
      29  GNU Lesser General Public License along with the GNU MP Library.  If not,
      30  see https://www.gnu.org/licenses/.  */
      31  
      32  #include "gmp-impl.h"
      33  #include "longlong.h"
      34  
      35  int
      36  mpf_eq (mpf_srcptr u, mpf_srcptr v, mp_bitcnt_t n_bits)
      37  {
      38    mp_srcptr up, vp, p;
      39    mp_size_t usize, vsize, minsize, maxsize, n_limbs, i, size;
      40    mp_exp_t uexp, vexp;
      41    mp_limb_t diff;
      42    int cnt;
      43  
      44    uexp = u->_mp_exp;
      45    vexp = v->_mp_exp;
      46  
      47    usize = u->_mp_size;
      48    vsize = v->_mp_size;
      49  
      50    /* 1. Are the signs different?  */
      51    if ((usize ^ vsize) >= 0)
      52      {
      53        /* U and V are both non-negative or both negative.  */
      54        if (usize == 0)
      55  	return vsize == 0;
      56        if (vsize == 0)
      57  	return 0;
      58  
      59        /* Fall out.  */
      60      }
      61    else
      62      {
      63        /* Either U or V is negative, but not both.  */
      64        return 0;
      65      }
      66  
      67    /* U and V have the same sign and are both non-zero.  */
      68  
      69    /* 2. Are the exponents different?  */
      70    if (uexp != vexp)
      71      return 0;
      72  
      73    usize = ABS (usize);
      74    vsize = ABS (vsize);
      75  
      76    up = u->_mp_d;
      77    vp = v->_mp_d;
      78  
      79    up += usize;			/* point just above most significant limb */
      80    vp += vsize;			/* point just above most significant limb */
      81  
      82    count_leading_zeros (cnt, up[-1]);
      83    if ((vp[-1] >> (GMP_LIMB_BITS - 1 - cnt)) != 1)
      84      return 0;			/* msb positions different */
      85  
      86    n_bits += cnt - GMP_NAIL_BITS;
      87    n_limbs = (n_bits + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS;
      88  
      89    usize = MIN (usize, n_limbs);
      90    vsize = MIN (vsize, n_limbs);
      91  
      92  #if 0
      93    /* Ignore zeros at the low end of U and V.  */
      94    while (up[0] == 0)
      95      up++, usize--;
      96    while (vp[0] == 0)
      97      vp++, vsize--;
      98  #endif
      99  
     100    minsize = MIN (usize, vsize);
     101    maxsize = usize + vsize - minsize;
     102  
     103    up -= minsize;		/* point at most significant common limb */
     104    vp -= minsize;		/* point at most significant common limb */
     105  
     106    /* Compare the most significant part which has explicit limbs for U and V. */
     107    for (i = minsize - 1; i > 0; i--)
     108      {
     109        if (up[i] != vp[i])
     110  	return 0;
     111      }
     112  
     113    n_bits -= (maxsize - 1) * GMP_NUMB_BITS;
     114  
     115    size = maxsize - minsize;
     116    if (size != 0)
     117      {
     118        if (up[0] != vp[0])
     119  	return 0;
     120  
     121        /* Now either U or V has its limbs consumed, i.e, continues with an
     122  	 infinite number of implicit zero limbs.  Check that the other operand
     123  	 has just zeros in the corresponding, relevant part.  */
     124  
     125        if (usize > vsize)
     126  	p = up - size;
     127        else
     128  	p = vp - size;
     129  
     130        for (i = size - 1; i > 0; i--)
     131  	{
     132  	  if (p[i] != 0)
     133  	    return 0;
     134  	}
     135  
     136        diff = p[0];
     137      }
     138    else
     139      {
     140        /* Both U or V has its limbs consumed.  */
     141  
     142        diff = up[0] ^ vp[0];
     143      }
     144  
     145    if (n_bits < GMP_NUMB_BITS)
     146      diff >>= GMP_NUMB_BITS - n_bits;
     147  
     148    return diff == 0;
     149  }