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 + -
显示快捷键?