github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/mpf/eq.c (about)

     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.h"
    33  #include "gmp-impl.h"
    34  #include "longlong.h"
    35  
    36  int
    37  mpf_eq (mpf_srcptr u, mpf_srcptr v, mp_bitcnt_t n_bits)
    38  {
    39    mp_srcptr up, vp, p;
    40    mp_size_t usize, vsize, minsize, maxsize, n_limbs, i, size;
    41    mp_exp_t uexp, vexp;
    42    mp_limb_t diff;
    43    int cnt;
    44  
    45    uexp = u->_mp_exp;
    46    vexp = v->_mp_exp;
    47  
    48    usize = u->_mp_size;
    49    vsize = v->_mp_size;
    50  
    51    /* 1. Are the signs different?  */
    52    if ((usize ^ vsize) >= 0)
    53      {
    54        /* U and V are both non-negative or both negative.  */
    55        if (usize == 0)
    56  	return vsize == 0;
    57        if (vsize == 0)
    58  	return 0;
    59  
    60        /* Fall out.  */
    61      }
    62    else
    63      {
    64        /* Either U or V is negative, but not both.  */
    65        return 0;
    66      }
    67  
    68    /* U and V have the same sign and are both non-zero.  */
    69  
    70    /* 2. Are the exponents different?  */
    71    if (uexp != vexp)
    72      return 0;
    73  
    74    usize = ABS (usize);
    75    vsize = ABS (vsize);
    76  
    77    up = u->_mp_d;
    78    vp = v->_mp_d;
    79  
    80    up += usize;			/* point just above most significant limb */
    81    vp += vsize;			/* point just above most significant limb */
    82  
    83    count_leading_zeros (cnt, up[-1]);
    84    if ((vp[-1] >> (GMP_LIMB_BITS - 1 - cnt)) != 1)
    85      return 0;			/* msb positions different */
    86  
    87    n_bits += cnt - GMP_NAIL_BITS;
    88    n_limbs = (n_bits + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS;
    89  
    90    usize = MIN (usize, n_limbs);
    91    vsize = MIN (vsize, n_limbs);
    92  
    93  #if 0
    94    /* Ignore zeros at the low end of U and V.  */
    95    while (up[0] == 0)
    96      up++, usize--;
    97    while (vp[0] == 0)
    98      vp++, vsize--;
    99  #endif
   100  
   101    minsize = MIN (usize, vsize);
   102    maxsize = usize + vsize - minsize;
   103  
   104    up -= minsize;		/* point at most significant common limb */
   105    vp -= minsize;		/* point at most significant common limb */
   106  
   107    /* Compare the most significant part which has explicit limbs for U and V. */
   108    for (i = minsize - 1; i > 0; i--)
   109      {
   110        if (up[i] != vp[i])
   111  	return 0;
   112      }
   113  
   114    n_bits -= (maxsize - 1) * GMP_NUMB_BITS;
   115  
   116    size = maxsize - minsize;
   117    if (size != 0)
   118      {
   119        if (up[0] != vp[0])
   120  	return 0;
   121  
   122        /* Now either U or V has its limbs consumed, i.e, continues with an
   123  	 infinite number of implicit zero limbs.  Check that the other operand
   124  	 has just zeros in the corresponding, relevant part.  */
   125  
   126        if (usize > vsize)
   127  	p = up - size;
   128        else
   129  	p = vp - size;
   130  
   131        for (i = size - 1; i > 0; i--)
   132  	{
   133  	  if (p[i] != 0)
   134  	    return 0;
   135  	}
   136  
   137        diff = p[0];
   138      }
   139    else
   140      {
   141        /* Both U or V has its limbs consumed.  */
   142  
   143        diff = up[0] ^ vp[0];
   144      }
   145  
   146    if (n_bits < GMP_NUMB_BITS)
   147      diff >>= GMP_NUMB_BITS - n_bits;
   148  
   149    return diff == 0;
   150  }