Annotation of OpenXM_contrib/gmp/mpfr/cmp.c, Revision 1.1
1.1 ! maekawa 1: /* mpfr_cmp -- compare two floating-point numbers
! 2:
! 3: Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
! 4:
! 5: This file is part of the MPFR Library.
! 6:
! 7: The MPFR Library is free software; you can redistribute it and/or modify
! 8: it under the terms of the GNU Library General Public License as published by
! 9: the Free Software Foundation; either version 2 of the License, or (at your
! 10: option) any later version.
! 11:
! 12: The MPFR Library is distributed in the hope that it will be useful, but
! 13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 14: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
! 15: License for more details.
! 16:
! 17: You should have received a copy of the GNU Library General Public License
! 18: along with the MPFR Library; see the file COPYING.LIB. If not, write to
! 19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
! 20: MA 02111-1307, USA. */
! 21:
! 22: #include <stdio.h>
! 23: #include "gmp.h"
! 24: #include "gmp-impl.h"
! 25: #include "longlong.h"
! 26: #include "mpfr.h"
! 27:
! 28: /* returns 0 iff b = c
! 29: a positive value iff b > c
! 30: a negative value iff b < c
! 31:
! 32: More precisely, in case b and c are of same sign, the absolute value
! 33: of the result is one plus the absolute difference between the exponents
! 34: of b and c, i.e. one plus the number of bits shifts to align b and c
! 35: (this value is useful in mpfr_sub).
! 36:
! 37: */
! 38:
! 39: /* #define DEBUG */
! 40:
! 41: /* compares b and sign(s)*c */
! 42: int
! 43: #if __STDC__
! 44: mpfr_cmp3 ( mpfr_srcptr b, mpfr_srcptr c, long int s)
! 45: #else
! 46: mpfr_cmp3(b, c, s)
! 47: mpfr_srcptr b;
! 48: mpfr_srcptr c;
! 49: long int s;
! 50: #endif
! 51: {
! 52: long int diff_exp;
! 53: unsigned long bn, cn;
! 54: mp_limb_t *bp, *cp;
! 55:
! 56: if (!NOTZERO(b) && !NOTZERO(c)) { return 0; }
! 57: s = s*SIGN(b)*SIGN(c);
! 58: if (s<0) return(SIGN(b));
! 59:
! 60: /* now signs are equal */
! 61:
! 62: diff_exp = EXP(b)-EXP(c);
! 63: s = (SIGN(b)>0) ? 1 : -1;
! 64:
! 65: if (diff_exp>0) return(s*(1+diff_exp));
! 66: else if (diff_exp<0) return(s*(-1+diff_exp));
! 67: /* both signs and exponents are equal */
! 68:
! 69: bn = (PREC(b)-1)/mp_bits_per_limb+1;
! 70: cn = (PREC(c)-1)/mp_bits_per_limb+1;
! 71: bp = MANT(b); cp = MANT(c);
! 72:
! 73: while (bn && cn) {
! 74: if (bp[--bn] != cp[--cn])
! 75: return((bp[bn]>cp[cn]) ? s : -s);
! 76: }
! 77:
! 78: if (bn) { while (bn) if (bp[--bn]) return(s); }
! 79: else if (cn) while (cn) if (cp[--cn]) return(-s);
! 80:
! 81: return 0;
! 82: }
! 83:
! 84: /* returns the number of cancelled bits when one subtracts abs(c) from abs(b).
! 85: Assumes b>=c, which implies EXP(b)>=EXP(c).
! 86: if b=c, returns prec(b).
! 87: */
! 88: int
! 89: #if __STDC__
! 90: mpfr_cmp2 ( mpfr_srcptr b, mpfr_srcptr c )
! 91: #else
! 92: mpfr_cmp2(b, c)
! 93: mpfr_srcptr b;
! 94: mpfr_srcptr c;
! 95: #endif
! 96: {
! 97: long int d, bn, cn, k, z;
! 98: mp_limb_t *bp, *cp, t, u=0, cc=0;
! 99:
! 100: #ifdef DEBUG
! 101: printf("b="); mpfr_print_raw(b); putchar('\n');
! 102: printf("c="); mpfr_print_raw(c); putchar('\n');
! 103: #endif
! 104: if (NOTZERO(c)==0) return (NOTZERO(b)) ? 0 : PREC(b);
! 105: d = EXP(b)-EXP(c);
! 106: k = 0; /* result can be d or d+1 if d>1, or >= d otherwise */
! 107: /* k is the number of identical bits in the high part,
! 108: then z is the number of possibly cancelled bits */
! 109: #ifdef DEBUG
! 110: if (d<0) { printf("assumption EXP(b)<EXP(c) violated\n"); exit(1); }
! 111: #endif
! 112: bn = (PREC(b)-1)/mp_bits_per_limb;
! 113: cn = (PREC(c)-1)/mp_bits_per_limb;
! 114: bp = MANT(b); cp = MANT(c);
! 115: /* subtract c from b from most significant to less significant limbs,
! 116: and first determines first non zero limb difference */
! 117: if (d)
! 118: {
! 119: cc = bp[bn--];
! 120: if (d<mp_bits_per_limb)
! 121: cc -= cp[cn]>>d;
! 122: }
! 123: else { /* d=0 */
! 124: while (bn>=0 && cn>=0 && (cc=(bp[bn--]-cp[cn--]))==0) {
! 125: k+=mp_bits_per_limb;
! 126: }
! 127:
! 128: if (cc==0) { /* either bn<0 or cn<0 */
! 129: while (bn>=0 && (cc=bp[bn--])==0) k+=mp_bits_per_limb;
! 130: }
! 131: /* now bn<0 or cc<>0 */
! 132: if (cc==0 && bn<0) return(PREC(b));
! 133: }
! 134:
! 135: /* the first non-zero limb difference is cc, and the number
! 136: of cancelled bits in the upper limbs is k */
! 137:
! 138: count_leading_zeros(u, cc);
! 139: k += u;
! 140:
! 141: if (cc != (1<<(mp_bits_per_limb-u-1))) return k;
! 142:
! 143: /* now cc is an exact power of two */
! 144: if (cc != 1)
! 145: /* We just need to compare the following limbs */
! 146: /* until two of them differ. The result is either k or k+1. */
! 147: {
! 148: /* First flush all the unmatched limbs of b ; they all have to
! 149: be 0 in order for the process to go on */
! 150: while (bn >= 0)
! 151: {
! 152: if (cn < 0) { return k; }
! 153: t = bp[bn--];
! 154: if (d < mp_bits_per_limb)
! 155: {
! 156: if (d)
! 157: {
! 158: u = cp[cn--] << (mp_bits_per_limb - d);
! 159: if (cn >= 0) u+=(cp[cn]>>d);
! 160: }
! 161: else u = cp[cn--];
! 162:
! 163: if (t > u || (t == u && cn < 0)) return k;
! 164: if (t < u) return k+1;
! 165: }
! 166: else
! 167: if (t) return k; else d -= mp_bits_per_limb;
! 168: }
! 169:
! 170: /* bn < 0; if some limb of c is nonzero, return k+1, otherwise return k*/
! 171:
! 172: if (cn>=0 && (cp[cn--] << (mp_bits_per_limb - d))) { return k+1; }
! 173:
! 174: while (cn >= 0)
! 175: if (cp[cn--]) return k+1;
! 176: return k;
! 177: }
! 178:
! 179: /* cc = 1. Too bad. */
! 180: z = 0; /* number of possibly cancelled bits - 1 */
! 181: /* thus result is either k if low(b) >= low(c)
! 182: or k+z+1 if low(b) < low(c) */
! 183: if (d > mp_bits_per_limb) { return k; }
! 184:
! 185: while (bn >= 0)
! 186: {
! 187: if (cn < 0) { return k; }
! 188:
! 189: if (d)
! 190: {
! 191: u = cp[cn--] << (mp_bits_per_limb - d);
! 192: if (cn >= 0) u+=(cp[cn]>>d);
! 193: }
! 194: else u = cp[cn--];
! 195:
! 196: /* bp[bn--] > cp[cn--] : no borrow possible, k unchanged
! 197: bp[bn--] = cp[cn--] : need to consider next limbs
! 198: bp[bn--] < cp[cn--] : borrow
! 199: */
! 200: if ((cc = bp[bn--]) != u) {
! 201: if (cc>u) return k;
! 202: else { count_leading_zeros(u, cc-u); return k + 1 + z + u; }
! 203: }
! 204: else z += mp_bits_per_limb;
! 205: }
! 206:
! 207: if (cn >= 0)
! 208: count_leading_zeros(cc, ~(cp[cn--] << (mp_bits_per_limb - d)));
! 209: else { cc = 0; }
! 210:
! 211: k += cc;
! 212: if (cc < d) return k;
! 213:
! 214: while (cn >= 0 && !~cp[cn--]) { z += mp_bits_per_limb; }
! 215: if (cn >= 0) { count_leading_zeros(cc, ~cp[cn--]); return (k + z + cc); }
! 216:
! 217: return k; /* We **need** that the nonsignificant limbs of c are set
! 218: to zero there */
! 219: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>