biginteger.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 585 行 · 第 1/2 页

JAVA
585
字号
/* * * * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */package com.sun.midp.pki;public class BigInteger {    private final static int MAX_CONSTANT = 16;    private static BigInteger posConst[] = new BigInteger[MAX_CONSTANT+1];    private static BigInteger negConst[] = new BigInteger[MAX_CONSTANT+1];    static {        for (int i = 1; i <= MAX_CONSTANT; i++) {            int[] magnitude = new int[1];            magnitude[0] = i;            posConst[i] = new BigInteger(magnitude,  1);            negConst[i] = new BigInteger(magnitude, -1);        }    }    /**     * The BigInteger constant zero.     */    public static final BigInteger ZERO = new BigInteger(new int[0], 0);    /**     * The signum of this BigInteger: -1 for negative, 0 for zero, or     * 1 for positive.  Note that the BigInteger zero <i>must</i> have     * a signum of 0.  This is necessary to ensures that there is exactly one     * representation for each BigInteger value.     *     * @serial     */    int signum;    /**     * The magnitude of this BigInteger, in <i>big-endian</i> order: the     * zeroth element of this array is the most-significant int of the     * magnitude.  The magnitude must be "minimal" in that the most-significant     * int ({@code mag[0]}) must be non-zero.  This is necessary to     * ensure that there is exactly one representation for each BigInteger     * value.  Note that this implies that the BigInteger zero has a     * zero-length mag array.     */    int[] mag;    /**     * The bitLength of this BigInteger, as returned by bitLength(), or -1     * (either value is acceptable).     *     * @serial     * @see #bitLength()     */    private int bitLength = -1;    /**     * The index of the lowest-order int in the magnitude of this BigInteger     * that contains a nonzero int, or -2 (either value is acceptable).  The     * least significant int has int-number 0, the next int in order of     * increasing significance has int-number 1, and so forth.     */    private int firstNonzeroIntNum = -2;    /**     * This mask is used to obtain the value of an int as if it were unsigned.     */    private final static long LONG_MASK = 0xffffffffL;    //Constructors    /**     * Translates a byte array containing the two's-complement binary     * representation of a BigInteger into a BigInteger.  The input array is     * assumed to be in <i>big-endian</i> byte-order: the most significant     * byte is in the zeroth element.     *     * @param  val big-endian two's-complement binary representation of     *         BigInteger.     * @throws NumberFormatException {@code val} is zero bytes long.     */    public BigInteger(byte[] val) {        if (val == null || val.length == 0) {            throw new NumberFormatException("Zero length BigInteger");        }        if (val[0] < 0) {            mag = makePositive(val);            signum = -1;        } else {            mag = stripLeadingZeroBytes(val);            signum = (mag.length == 0 ? 0 : 1);        }    }    /**     * Translates the sign-magnitude representation of a BigInteger into a     * BigInteger.  The sign is represented as an integer signum value: -1 for     * negative, 0 for zero, or 1 for positive.  The magnitude is a byte array     * in <i>big-endian</i> byte-order: the most significant byte is in the     * zeroth element.  A zero-length magnitude array is permissible, and will     * result in a BigInteger value of 0, whether signum is -1, 0 or 1.     *     * @param  signum signum of the number (-1 for negative, 0 for zero, 1     *         for positive).     * @param  magnitude big-endian binary representation of the magnitude of     *         the number.     * @throws NumberFormatException {@code signum} is not one of the three     *         legal values (-1, 0, and 1), or {@code signum} is 0 and     *         {@code magnitude} contains one or more non-zero bytes.     */    public BigInteger(int signum, byte[] magnitude) {        this.mag = stripLeadingZeroBytes(magnitude);        if (signum < -1 || signum > 1)            throw(new NumberFormatException("Invalid signum value"));        if (this.mag.length==0) {            this.signum = 0;        } else {            if (signum == 0)                throw(new NumberFormatException("signum-magnitude mismatch"));            this.signum = signum;        }    }    /**     * Constructs a BigInteger with the specified value, which may not be zero.     */    private BigInteger(long val) {        if (val < 0) {            signum = -1;            val = -val;        } else {            signum = 1;        }        int highWord = (int)(val >>> 32);        if (highWord==0) {            mag = new int[1];            mag[0] = (int)val;        } else {            mag = new int[2];            mag[0] = highWord;            mag[1] = (int)val;        }    }        /**     * This private constructor differs from its public cousin     * with the arguments reversed in two ways: it assumes that its     * arguments are correct, and it doesn't copy the magnitude array.     */    private BigInteger(int[] magnitude, int signum) {        this.signum = (magnitude.length == 0 ? 0 : signum);        this.mag = magnitude;    }        /**     * Returns a BigInteger whose value is equal to that of the     * specified {@code long}.  This "static factory method" is     * provided in preference to a ({@code long}) constructor     * because it allows for reuse of frequently used BigIntegers.     *     * @param  val value of the BigInteger to return.     * @return a BigInteger with the specified value.     */    public static BigInteger valueOf(long val) {        // If -MAX_CONSTANT < val < MAX_CONSTANT, return stashed constant        if (val == 0) {            return ZERO;        }        if (val > 0 && val <= MAX_CONSTANT) {            return posConst[(int) val];        } else if (val < 0 && val >= -MAX_CONSTANT) {            return negConst[(int) -val];        }        return new BigInteger(val);    }        /**     * Returns the signum function of this BigInteger.     *     * @return -1, 0 or 1 as the value of this BigInteger is negative, zero or     *         positive.     */    public int signum() {        return this.signum;    }    // Miscellaneous Bit Operations    /**     * Returns the number of bits in the minimal two's-complement     * representation of this BigInteger, <i>excluding</i> a sign bit.     * For positive BigIntegers, this is equivalent to the number of bits in     * the ordinary binary representation.  (Computes     * {@code (ceil(log2(this < 0 ? -this : this+1)))}.)     *     * @return number of bits in the minimal two's-complement     *         representation of this BigInteger, <i>excluding</i> a sign bit.     */    public int bitLength() {        /*         * Initialize bitLength field the first time this method is executed.         * This method depends on the atomicity of int modifies; without         * this guarantee, it would have to be synchronized.         */        if (bitLength == -1) {            if (signum == 0) {                bitLength = 0;            } else {                // Calculate the bit length of the magnitude                int magBitLength = ((mag.length-1) << 5) + bitLen(mag[0]);                if (signum < 0) {                    // Check if magnitude is a power of two                    boolean pow2 = (bitCnt(mag[0]) == 1);                    for(int i=1; i<mag.length && pow2; i++)                        pow2 = (mag[i]==0);                    bitLength = (pow2 ? magBitLength-1 : magBitLength);                } else {                    bitLength = magBitLength;                }            }        }        return bitLength;    }    /**     * bitLen(val) is the number of bits in val.     */    static int bitLen(int w) {        // Binary search - decision tree (5 tests, rarely 6)        return         (w < 1<<15 ?          (w < 1<<7 ?           (w < 1<<3 ?            (w < 1<<1 ? (w < 1<<0 ? (w<0 ? 32 : 0) : 1) : (w < 1<<2 ? 2 : 3)) :            (w < 1<<5 ? (w < 1<<4 ? 4 : 5) : (w < 1<<6 ? 6 : 7))) :           (w < 1<<11 ?            (w < 1<<9 ? (w < 1<<8 ? 8 : 9) : (w < 1<<10 ? 10 : 11)) :            (w < 1<<13 ? (w < 1<<12 ? 12 : 13) : (w < 1<<14 ? 14 : 15)))) :          (w < 1<<23 ?           (w < 1<<19 ?            (w < 1<<17 ? (w < 1<<16 ? 16 : 17) : (w < 1<<18 ? 18 : 19)) :            (w < 1<<21 ? (w < 1<<20 ? 20 : 21) : (w < 1<<22 ? 22 : 23))) :           (w < 1<<27 ?            (w < 1<<25 ? (w < 1<<24 ? 24 : 25) : (w < 1<<26 ? 26 : 27)) :            (w < 1<<29 ? (w < 1<<28 ? 28 : 29) : (w < 1<<30 ? 30 : 31)))));    }    static int bitCnt(int val) {        val -= (0xaaaaaaaa & val) >>> 1;        val = (val & 0x33333333) + ((val >>> 2) & 0x33333333);        val = val + (val >>> 4) & 0x0f0f0f0f;        val += val >>> 8;        val += val >>> 16;        return val & 0xff;    }    /**     * Compares this BigInteger with the specified BigInteger.  This     * method is provided in preference to individual methods for each     * of the six boolean comparison operators ({@literal <}, ==,     * {@literal >}, {@literal >=}, !=, {@literal <=}).  The suggested     * idiom for performing these comparisons is: {@code

⌨️ 快捷键说明

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