xref: /dragonfly/contrib/gmp/mpf/cmp_si.c (revision d2d4b659)
14b6a78b7SSimon Schubert /* mpf_cmp_si -- Compare a float with a signed integer.
24b6a78b7SSimon Schubert 
34b6a78b7SSimon Schubert Copyright 1993, 1994, 1995, 1999, 2000, 2001, 2002, 2004 Free Software
44b6a78b7SSimon Schubert Foundation, Inc.
54b6a78b7SSimon Schubert 
64b6a78b7SSimon Schubert This file is part of the GNU MP Library.
74b6a78b7SSimon Schubert 
84b6a78b7SSimon Schubert The GNU MP Library is free software; you can redistribute it and/or modify
94b6a78b7SSimon Schubert it under the terms of the GNU Lesser General Public License as published by
104b6a78b7SSimon Schubert the Free Software Foundation; either version 3 of the License, or (at your
114b6a78b7SSimon Schubert option) any later version.
124b6a78b7SSimon Schubert 
134b6a78b7SSimon Schubert The GNU MP Library is distributed in the hope that it will be useful, but
144b6a78b7SSimon Schubert WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
154b6a78b7SSimon Schubert or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
164b6a78b7SSimon Schubert License for more details.
174b6a78b7SSimon Schubert 
184b6a78b7SSimon Schubert You should have received a copy of the GNU Lesser General Public License
194b6a78b7SSimon Schubert along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
204b6a78b7SSimon Schubert 
214b6a78b7SSimon Schubert #include "gmp.h"
224b6a78b7SSimon Schubert #include "gmp-impl.h"
234b6a78b7SSimon Schubert 
244b6a78b7SSimon Schubert int
mpf_cmp_si(mpf_srcptr u,long int vval)25*d2d4b659SJohn Marino mpf_cmp_si (mpf_srcptr u, long int vval) __GMP_NOTHROW
264b6a78b7SSimon Schubert {
274b6a78b7SSimon Schubert   mp_srcptr up;
284b6a78b7SSimon Schubert   mp_size_t usize;
294b6a78b7SSimon Schubert   mp_exp_t uexp;
304b6a78b7SSimon Schubert   mp_limb_t ulimb;
314b6a78b7SSimon Schubert   int usign;
32*d2d4b659SJohn Marino   unsigned long abs_vval;
334b6a78b7SSimon Schubert 
344b6a78b7SSimon Schubert   uexp = u->_mp_exp;
354b6a78b7SSimon Schubert   usize = u->_mp_size;
364b6a78b7SSimon Schubert 
374b6a78b7SSimon Schubert   /* 1. Are the signs different?  */
384b6a78b7SSimon Schubert   if ((usize < 0) == (vval < 0)) /* don't use xor, type size may differ */
394b6a78b7SSimon Schubert     {
404b6a78b7SSimon Schubert       /* U and V are both non-negative or both negative.  */
414b6a78b7SSimon Schubert       if (usize == 0)
424b6a78b7SSimon Schubert 	/* vval >= 0 */
434b6a78b7SSimon Schubert 	return -(vval != 0);
444b6a78b7SSimon Schubert       if (vval == 0)
454b6a78b7SSimon Schubert 	/* usize >= 0 */
464b6a78b7SSimon Schubert 	return usize != 0;
474b6a78b7SSimon Schubert       /* Fall out.  */
484b6a78b7SSimon Schubert     }
494b6a78b7SSimon Schubert   else
504b6a78b7SSimon Schubert     {
514b6a78b7SSimon Schubert       /* Either U or V is negative, but not both.  */
524b6a78b7SSimon Schubert       return usize >= 0 ? 1 : -1;
534b6a78b7SSimon Schubert     }
544b6a78b7SSimon Schubert 
554b6a78b7SSimon Schubert   /* U and V have the same sign and are both non-zero.  */
564b6a78b7SSimon Schubert 
574b6a78b7SSimon Schubert   usign = usize >= 0 ? 1 : -1;
584b6a78b7SSimon Schubert   usize = ABS (usize);
59*d2d4b659SJohn Marino   abs_vval = ABS_CAST (unsigned long, vval);
604b6a78b7SSimon Schubert 
614b6a78b7SSimon Schubert   /* 2. Are the exponents different (V's exponent == 1)?  */
624b6a78b7SSimon Schubert #if GMP_NAIL_BITS != 0
63*d2d4b659SJohn Marino   if (uexp > 1 + (abs_vval > GMP_NUMB_MAX))
644b6a78b7SSimon Schubert     return usign;
65*d2d4b659SJohn Marino   if (uexp < 1 + (abs_vval > GMP_NUMB_MAX))
664b6a78b7SSimon Schubert     return -usign;
674b6a78b7SSimon Schubert #else
684b6a78b7SSimon Schubert   if (uexp > 1)
694b6a78b7SSimon Schubert     return usign;
704b6a78b7SSimon Schubert   if (uexp < 1)
714b6a78b7SSimon Schubert     return -usign;
724b6a78b7SSimon Schubert #endif
734b6a78b7SSimon Schubert 
744b6a78b7SSimon Schubert   up = u->_mp_d;
754b6a78b7SSimon Schubert 
764b6a78b7SSimon Schubert   ulimb = up[usize - 1];
774b6a78b7SSimon Schubert #if GMP_NAIL_BITS != 0
784b6a78b7SSimon Schubert   if (usize >= 2 && uexp == 2)
794b6a78b7SSimon Schubert     {
804b6a78b7SSimon Schubert       if ((ulimb >> GMP_NAIL_BITS) != 0)
814b6a78b7SSimon Schubert 	return usign;
824b6a78b7SSimon Schubert       ulimb = (ulimb << GMP_NUMB_BITS) | up[usize - 2];
834b6a78b7SSimon Schubert       usize--;
844b6a78b7SSimon Schubert     }
854b6a78b7SSimon Schubert #endif
864b6a78b7SSimon Schubert   usize--;
874b6a78b7SSimon Schubert 
884b6a78b7SSimon Schubert   /* 3. Compare the most significant mantissa limb with V.  */
89*d2d4b659SJohn Marino   if (ulimb > abs_vval)
904b6a78b7SSimon Schubert     return usign;
91*d2d4b659SJohn Marino   else if (ulimb < abs_vval)
924b6a78b7SSimon Schubert     return -usign;
934b6a78b7SSimon Schubert 
944b6a78b7SSimon Schubert   /* Ignore zeroes at the low end of U.  */
954b6a78b7SSimon Schubert   while (*up == 0)
964b6a78b7SSimon Schubert     {
974b6a78b7SSimon Schubert       up++;
984b6a78b7SSimon Schubert       usize--;
994b6a78b7SSimon Schubert     }
1004b6a78b7SSimon Schubert 
1014b6a78b7SSimon Schubert   /* 4. Now, if the number of limbs are different, we have a difference
1024b6a78b7SSimon Schubert      since we have made sure the trailing limbs are not zero.  */
1034b6a78b7SSimon Schubert   if (usize > 0)
1044b6a78b7SSimon Schubert     return usign;
1054b6a78b7SSimon Schubert 
1064b6a78b7SSimon Schubert   /* Wow, we got zero even if we tried hard to avoid it.  */
1074b6a78b7SSimon Schubert   return 0;
1084b6a78b7SSimon Schubert }
109