biginteger.java

来自「《移动Agent技术》一书的所有章节源代码。」· Java 代码 · 共 1,801 行 · 第 1/3 页

JAVA
1,801
字号
        w[0] = (int)(u2 + (u1 >> 32) + w[0]);        return w;    }    /**     * return x with x = y * z - x is assumed to have enough space.     */	private int[] multiply(        int[]   x,        int[]   y,        int[]   z)	{        for (int i = z.length - 1; i >= 0; i--)        {            long    a = z[i] & IMASK;            long    value = 0;            for (int j = y.length - 1; j >= 0; j--)            {                value += a * (y[j] & IMASK) + (x[i + j + 1] & IMASK);                x[i + j + 1] = (int)value;                value >>>= 32;            }            x[i] = (int)value;        }        return x;    }	public BigInteger multiply(		BigInteger val)	{		if (sign == 0 || val.sign == 0) return BigInteger.ZERO;		int[]   res = new int[magnitude.length + val.magnitude.length];		return new BigInteger(sign * val.sign, multiply(res, magnitude, val.magnitude));	}	public BigInteger negate()	{		return new BigInteger(-sign, magnitude);	}	public BigInteger pow(		int exp)		throws ArithmeticException	{		if (exp < 0) throw new ArithmeticException("Negative exponent");		if (sign == 0) return (exp == 0 ? BigInteger.ONE : this);		BigInteger y, z;		y = BigInteger.ONE;		z = this;		while (exp != 0)        {			if ((exp & 0x1) == 1)            {                y = y.multiply(z);            }			exp >>= 1;			if (exp != 0)            {                z = z.multiply(z);            }        }		return y;	}    /**     * return x = x % y - done in place (y value preserved)     */    private int[] remainder(        int[]   x,        int[]   y)    {        int xyCmp = compareTo(0, x, 0, y);        if (xyCmp > 0)        {            int[]   c;            int     shift = bitLength(0, x) - bitLength(0, y);            if (shift > 1)            {                c = shiftLeft(y, shift - 1);            }            else            {                c = new int[x.length];                System.arraycopy(y, 0, c, c.length - y.length, y.length);            }            subtract(0, x, 0, c);            int xStart = 0;            int cStart = 0;            for (;;)            {                int cmp = compareTo(xStart, x, cStart, c);                while (cmp >= 0)                {                    subtract(xStart, x, cStart, c);                    cmp = compareTo(xStart, x, cStart, c);                }                xyCmp = compareTo(xStart, x, 0, y);                if (xyCmp > 0)                {                    if (x[xStart] == 0)                    {                        xStart++;                    }                    shift = bitLength(cStart, c) - bitLength(xStart, x);                    if (shift == 0)                    {                        c = shiftRightOne(cStart, c);                    }                    else                    {                        c = shiftRight(cStart, c, shift);                    }                    if (c[cStart] == 0)                    {                        cStart++;                    }                }                else if (xyCmp == 0)                {                    for (int i = xStart; i != x.length; i++)                    {                        x[i] = 0;                    }                    break;                }                else                {                    break;                }            }        }        else if (xyCmp == 0)        {            for (int i = 0; i != x.length; i++)            {                x[i] = 0;            }        }           return x;    }	public BigInteger remainder(		BigInteger val)		throws ArithmeticException	{		if (val.sign == 0)        {			throw new ArithmeticException("BigInteger: Divide by zero");        }		if (sign == 0)        {            return BigInteger.ZERO;        }        int[]   res = new int[this.magnitude.length];        System.arraycopy(this.magnitude, 0, res, 0, res.length);		return new BigInteger(sign, remainder(res, val.magnitude));	}    /**     * do a left shift - this returns a new array.     */    private int[] shiftLeft(        int[]   mag,        int     n)	{		int nInts = n >>> 5;		int nBits = n & 0x1f;		int magLen = mag.length;		int newMag[] = null;		if (nBits == 0)        {			newMag = new int[magLen + nInts];			for (int i = 0; i < magLen; i++)            {				newMag[i] = mag[i];            }        }        else        {            int i = 0;            int nBits2 = 32 - nBits;            int highBits = mag[0] >>> nBits2;            if (highBits != 0)            {                newMag = new int[magLen + nInts + 1];                newMag[i++] = highBits;            }            else            {                newMag = new int[magLen + nInts];            }            int m = mag[0];            for (int j = 0; j < magLen-1; j++)            {                int next = mag[j + 1];                newMag[i++] = (m << nBits) | (next >>> nBits2);                m = next;            }            newMag[i] = mag[magLen - 1] << nBits;        }                return newMag;    }	public BigInteger shiftLeft(		int n)	{		if (sign == 0 || magnitude.length == 0)        {            return ZERO;        }		if (n == 0)        {            return this;        }		if (n < 0)        {            return shiftRight(-n);        }	    return new BigInteger(sign, shiftLeft(magnitude, n));	}    /**     * do a right shift - this does it in place.     */    private int[] shiftRight(        int     start,        int[]   mag,        int     n)    {		int nInts = (n >>> 5) + start;		int nBits = n & 0x1f;		int magLen = mag.length;        if (nInts != start)        {            for (int i = magLen - 1; i >= nInts; i--)            {                mag[i] = mag[i - nInts];            }            for (int i = nInts - 1; i >= start; i--)            {                mag[i] = 0;            }        }        if (nBits != 0)        {            int nBits2 = 32 - nBits;            int m = mag[magLen - 1];            for (int i = magLen - 1; i >= nInts + 1; i--)            {                int next = mag[i - 1];                mag[i] = (m >>> nBits) | (next << nBits2);                m = next;            }            mag[nInts] >>>= nBits;        }        return mag;    }    /**     * do a right shift by one - this does it in place.     */    private int[] shiftRightOne(        int     start,        int[]   mag)    {		int magLen = mag.length;        int m = mag[magLen - 1];        for (int i = magLen - 1; i >= start + 1; i--)        {            int next = mag[i - 1];            mag[i] = (m >>> 1) | (next << 31);            m = next;        }        mag[start] >>>= 1;        return mag;    }	public BigInteger shiftRight(		int n)	{		if (n == 0)        {            return this;        }		if (n < 0)        {            return shiftLeft(-n);        }		if (n >= bitLength())        {			return (this.sign < 0 ? valueOf(-1) : BigInteger.ZERO);		}        int[]   res = new int[this.magnitude.length];                System.arraycopy(this.magnitude, 0, res, 0, res.length);		return new BigInteger(this.sign, shiftRight(0, res, n));	}	public int signum()	{		return sign;	}    /**     * returns x = x - y - we assume x is >= y     */    private int[] subtract(        int     xStart,        int[]   x,        int     yStart,        int[]   y)	{		int iT = x.length - 1;		int iV = y.length - 1;		long m;		int borrow = 0;		do        {			m = (((long)x[iT]) & IMASK) - (((long)y[iV--]) & IMASK) + borrow;			x[iT--] = (int)m;			if (m < 0)            {                borrow = -1;            }			else            {                borrow = 0;            }		}        while (iV >= yStart);        while (iT >= xStart)        {			m = (((long)x[iT]) & IMASK) + borrow;			x[iT--] = (int)m;			if (m < 0)            {                borrow = -1;            }			else            {                break;            }        }		return x;	}    public BigInteger subtract(		BigInteger val)	{		if (val.sign == 0 || val.magnitude.length == 0)        {            return this;        }		if (sign == 0 || magnitude.length == 0)        {		    return val.negate();        }		if (val.sign < 0)        {			if (this.sign > 0) return this.add(val.negate());        }		else        {			if (this.sign < 0) return this.add(val.negate());        }		BigInteger bigun, littlun;		int compare = compareTo(val);		if (compare == 0)        {            return ZERO;        }		if (compare < 0)        {			bigun = val;			littlun = this;        }		else        {			bigun = this;			littlun = val;        }		int res[] = new int[bigun.magnitude.length];        System.arraycopy(bigun.magnitude, 0, res, 0, res.length);		return new BigInteger(this.sign * compare, subtract(0, res, 0, littlun.magnitude));	}	public byte[] toByteArray()	{        int     bitLength = bitLength();		byte[]  bytes = new byte[bitLength / 8 + 1];		int bytesCopied = 4;		int mag = 0;		int ofs = magnitude.length-1;		for (int i = bytes.length-1; i >= 0; i--)        {			if (bytesCopied == 4 && ofs >= 0)            {                if (sign < 0)                {				    mag = -magnitude[ofs--];                }                else                {				    mag = magnitude[ofs--];                }				bytesCopied = 1;            }			else            {				mag >>>= 8;				bytesCopied++;            }			bytes[i] = (byte)mag;        }		return bytes;	}	public String toString()	{		return toString(10);	}	public String toString(int rdx)	{		// only radix 16 at the moment		if (magnitude == null)        {			return "null";        }		else if (sign == 0)        {			return "0";        }		String s = sign == -1 ? "-" : "";		String h;				for (int i = 0; i < magnitude.length; i++)        {			h = "0000000" + Integer.toHexString(magnitude[i]);			h = h.substring(h.length()-8);			s = s + h;        }		while (s.length() > 1 && s.charAt(0) == '0') s = s.substring(1);		if (s.length() == 0) s = "0";		return s;	}	public static final BigInteger ZERO = new BigInteger(0, new byte[0]);	public static final BigInteger ONE = valueOf(1);	private static final BigInteger TWO = valueOf(2);	public static BigInteger valueOf(		long val)	{		if (val == 0)        {            return BigInteger.ZERO;        }		// store val into a byte array		byte[] b = new byte[8];		for (int i = 0; i < 8; i++) {			b[7 - i] = (byte)val;			val >>= 8;			}		return new BigInteger(b);	}	private int max(int a, int b) {		if (a < b) return b;		return a;	}	public int getLowestSetBit()	{        if (this.equals(ZERO))        {            return -1;        }        int w = magnitude.length - 1;        while (w >= 0)        {            if (magnitude[w] != 0)            {                break;            }            w--;        }        int b = 31;        while (b > 0)        {            if ((magnitude[w] << b) == 0x80000000)            {                break;            }            b--;        }		return (((magnitude.length - 1) - w) * 32 + (31 - b));	}	public boolean testBit(		int n)		throws ArithmeticException	{		if (n < 0)         {            throw new ArithmeticException("Bit position must not be negative");        }        if ((n / 32) >= magnitude.length)        {            return sign < 0;        }		return ((magnitude[(magnitude.length - 1) - n / 32] >> (n % 32)) & 1) > 0;	}}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?