All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.emul.java.math.BigInteger Maven / Gradle / Ivy

There is a newer version: 2.12.1
Show newest version
/*
 * Copyright 2009 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 *
 * INCLUDES MODIFICATIONS BY RICHARD ZSCHECH AS WELL AS GOOGLE.
 */
package java.math;

import static javaemul.internal.Coercions.ensureInt;
import static javaemul.internal.InternalPreconditions.checkCriticalArgument;
import static javaemul.internal.InternalPreconditions.checkNotNull;

import java.io.Serializable;
import java.util.Random;
import javaemul.internal.LongUtils;

/**
 * This class represents immutable integer numbers of arbitrary length. Large
 * numbers are typically used in security applications and therefore BigIntegers
 * offer dedicated functionality like the generation of large prime numbers or
 * the computation of modular inverse.
 * 

* Since the class was modeled to offer all the functionality as the * {@link Integer} class does, it provides even methods that operate bitwise on * a two's complement representation of large integers. Note however that the * implementations favors an internal representation where magnitude and sign * are treated separately. Hence such operations are inefficient and should be * discouraged. In simple words: Do NOT implement any bit fields based on * BigInteger. */ public class BigInteger extends Number implements Comparable, Serializable { /** * The {@code BigInteger} constant 1. */ public static final BigInteger ONE = new BigInteger(1, 1); /* Fields used for the internal representation. */ /** * The {@code BigInteger} constant 10. */ public static final BigInteger TEN = new BigInteger(1, 10); /** * The {@code BigInteger} constant 0. */ public static final BigInteger ZERO = new BigInteger(0, 0); /** * The {@code BigInteger} constant 0 used for comparison. */ static final int EQUALS = 0; /** * The {@code BigInteger} constant 1 used for comparison. */ static final int GREATER = 1; /** * The {@code BigInteger} constant -1 used for comparison. */ static final int LESS = -1; /** * The {@code BigInteger} constant -1. */ static final BigInteger MINUS_ONE = new BigInteger(-1, 1); /** * All the {@code BigInteger} numbers in the range [0,10] are cached. */ static final BigInteger[] SMALL_VALUES = { ZERO, ONE, new BigInteger(1, 2), new BigInteger(1, 3), new BigInteger(1, 4), new BigInteger(1, 5), new BigInteger(1, 6), new BigInteger(1, 7), new BigInteger(1, 8), new BigInteger(1, 9), TEN}; static final BigInteger[] TWO_POWS; /** * This is the serialVersionUID used by the sun implementation. */ private static final long serialVersionUID = -8287574255936472291L; static { TWO_POWS = new BigInteger[32]; for (int i = 0; i < TWO_POWS.length; i++) { TWO_POWS[i] = BigInteger.valueOf(1L << i); } } /** * Returns a random positive {@code BigInteger} instance in the range [0, * 2^(bitLength)-1] which is probably prime. The probability that the returned * {@code BigInteger} is prime is beyond (1-1/2^80). *

* Implementation Note: Currently {@code rnd} is ignored. * * @param bitLength length of the new {@code BigInteger} in bits. * @param rnd random generator used to generate the new {@code BigInteger}. * @return probably prime random {@code BigInteger} instance. * @throws ArithmeticException if {@code bitLength < 2}. */ public static BigInteger probablePrime(int bitLength, Random rnd) { return new BigInteger(bitLength, 100, rnd); } public static BigInteger valueOf(long val) { return val >= 0 ? BigInteger.fromBits(val) : BigInteger.fromBits(-val).negate(); } private static BigInteger fromBits(long bits) { int lowBits = (int) bits; int highBits = LongUtils.getHighBits(bits); if (highBits != 0) { return new BigInteger(1, lowBits, highBits); } if (lowBits > 10 || lowBits < 0) { return new BigInteger(1, lowBits); } return SMALL_VALUES[lowBits]; } static BigInteger getPowerOfTwo(int exp) { if (exp < TWO_POWS.length) { return TWO_POWS[exp]; } int intCount = exp >> 5; int bitN = exp & 31; int resDigits[] = new int[intCount + 1]; resDigits[intCount] = 1 << bitN; return new BigInteger(1, intCount + 1, resDigits); } /** * @see BigInteger#BigInteger(String, int) */ private static void setFromString(BigInteger bi, String val, int radix) { int sign; int[] digits; int numberLength; int stringLength = val.length(); int startChar; int endChar = stringLength; if (val.charAt(0) == '-') { sign = -1; startChar = 1; stringLength--; } else { sign = 1; startChar = 0; } /* * We use the following algorithm: split a string into portions of n * characters and convert each portion to an integer according to the radix. * Then convert an exp(radix, n) based number to binary using the * multiplication method. See D. Knuth, The Art of Computer Programming, * vol. 2. */ int charsPerInt = Conversion.digitFitInInt[radix]; int bigRadixDigitsLength = stringLength / charsPerInt; int topChars = stringLength % charsPerInt; if (topChars != 0) { bigRadixDigitsLength++; } digits = new int[bigRadixDigitsLength]; // Get the maximal power of radix that fits in int int bigRadix = Conversion.bigRadices[radix - 2]; // Parse an input string and accumulate the BigInteger's magnitude int digitIndex = 0; // index of digits array int substrEnd = startChar + ((topChars == 0) ? charsPerInt : topChars); int newDigit; for (int substrStart = startChar; substrStart < endChar; substrStart = substrEnd, substrEnd = substrStart + charsPerInt) { int bigRadixDigit = Integer.parseInt( val.substring(substrStart, substrEnd), radix); newDigit = Multiplication.multiplyByInt(digits, digitIndex, bigRadix); newDigit += Elementary.inplaceAdd(digits, digitIndex, bigRadixDigit); digits[digitIndex++] = newDigit; } numberLength = digitIndex; bi.sign = sign; bi.numberLength = numberLength; bi.digits = digits; bi.cutOffLeadingZeroes(); } /** * The magnitude of this big integer. This array is in little endian order and * each "digit" is a 32-bit unsigned integer. For example: {@code 13} is * represented as [ 13 ] {@code -13} is represented as [ 13 ] {@code 2^32 + * 13} is represented as [ 13, 1 ] {@code 2^64 + 13} is represented as [ 13, * 0, 1 ] {@code 2^31} is represented as [ Integer.MIN_VALUE ] The magnitude * array may be longer than strictly necessary, which results in additional * trailing zeros. * *

TODO(jat): consider changing to 24-bit integers for better performance * in browsers. */ transient int digits[]; /** * The length of this in measured in ints. Can be less than digits.length(). */ transient int numberLength; /** * The sign of this. */ transient int sign; private transient int firstNonzeroDigit = -2; /** * Cache for the hash code. */ private transient int hashCode = 0; /** * Constructs a new {@code BigInteger} from the given two's complement * representation. The most significant byte is the entry at index 0. The most * significant bit of this entry determines the sign of the new {@code * BigInteger} instance. The given array must not be empty. * * @param val two's complement representation of the new {@code BigInteger}. * @throws NullPointerException if {@code val == null}. * @throws NumberFormatException if the length of {@code val} is zero. */ public BigInteger(byte[] val) { if (val.length == 0) { // math.12=Zero length BigInteger throw new NumberFormatException("Zero length BigInteger"); //$NON-NLS-1$ } if (val[0] < 0) { sign = -1; putBytesNegativeToIntegers(val); } else { sign = 1; putBytesPositiveToIntegers(val); } cutOffLeadingZeroes(); } /** * Constructs a new {@code BigInteger} instance with the given sign and the * given magnitude. The sign is given as an integer (-1 for negative, 0 for * zero, 1 for positive). The magnitude is specified as a byte array. The most * significant byte is the entry at index 0. * * @param signum sign of the new {@code BigInteger} (-1 for negative, 0 for * zero, 1 for positive). * @param magnitude magnitude of the new {@code BigInteger} with the most * significant byte first. * @throws NullPointerException if {@code magnitude == null}. * @throws NumberFormatException if the sign is not one of -1, 0, 1 or if the * sign is zero and the magnitude contains non-zero entries. */ public BigInteger(int signum, byte[] magnitude) { checkNotNull(magnitude); if ((signum < -1) || (signum > 1)) { // math.13=Invalid signum value throw new NumberFormatException("Invalid signum value"); //$NON-NLS-1$ } if (signum == 0) { for (byte element : magnitude) { if (element != 0) { // math.14=signum-magnitude mismatch throw new NumberFormatException("signum-magnitude mismatch"); //$NON-NLS-1$ } } } if (magnitude.length == 0) { sign = 0; numberLength = 1; digits = new int[] {0}; } else { sign = signum; putBytesPositiveToIntegers(magnitude); cutOffLeadingZeroes(); } } /** * Constructs a random {@code BigInteger} instance in the range [0, * 2^(bitLength)-1] which is probably prime. The probability that the returned * {@code BigInteger} is prime is beyond (1-1/2^certainty). * * @param bitLength length of the new {@code BigInteger} in bits. * @param certainty tolerated primality uncertainty. * @param rnd is an optional random generator to be used. * @throws ArithmeticException if {@code bitLength} < 2. */ public BigInteger(int bitLength, int certainty, Random rnd) { if (bitLength < 2) { // math.1C=bitLength < 2 throw new ArithmeticException("bitLength < 2"); //$NON-NLS-1$ } BigInteger me = Primality.consBigInteger(bitLength, certainty, rnd); sign = me.sign; numberLength = me.numberLength; digits = me.digits; } /** * Constructs a random non-negative {@code BigInteger} instance in the range * [0, 2^(numBits)-1]. * * @param numBits maximum length of the new {@code BigInteger} in bits. * @param rnd is an optional random generator to be used. * @throws IllegalArgumentException if {@code numBits} < 0. */ public BigInteger(int numBits, Random rnd) { checkCriticalArgument(numBits >= 0, "numBits must be non-negative"); if (numBits == 0) { sign = 0; numberLength = 1; digits = new int[] {0}; } else { sign = 1; numberLength = (numBits + 31) >> 5; digits = new int[numberLength]; for (int i = 0; i < numberLength; i++) { digits[i] = rnd.nextInt(); } // Using only the necessary bits digits[numberLength - 1] >>>= (-numBits) & 31; cutOffLeadingZeroes(); } } /** * Constructs a new {@code BigInteger} instance from the string * representation. The string representation consists of an optional minus * sign followed by a non-empty sequence of decimal digits. * * @param val string representation of the new {@code BigInteger}. * @throws NullPointerException if {@code val == null}. * @throws NumberFormatException if {@code val} is not a valid representation * of a {@code BigInteger}. */ public BigInteger(String val) { this(val, 10); } /** * Constructs a new {@code BigInteger} instance from the string * representation. The string representation consists of an optional minus * sign followed by a non-empty sequence of digits in the specified radix. For * the conversion the method {@code Character.digit(char, radix)} is used. * * @param val string representation of the new {@code BigInteger}. * @param radix the base to be used for the conversion. * @throws NullPointerException if {@code val == null}. * @throws NumberFormatException if {@code val} is not a valid representation * of a {@code BigInteger} or if {@code radix < Character.MIN_RADIX} * or {@code radix > Character.MAX_RADIX}. */ public BigInteger(String val, int radix) { checkNotNull(val); if ((radix < Character.MIN_RADIX) || (radix > Character.MAX_RADIX)) { // math.11=Radix out of range throw new NumberFormatException("Radix out of range"); //$NON-NLS-1$ } if (val.isEmpty()) { // math.12=Zero length BigInteger throw new NumberFormatException("Zero length BigInteger"); //$NON-NLS-1$ } setFromString(this, val, radix); } /** * Constructs a number which array is of size 1. * * @param sign the sign of the number * @param value the only one digit of array */ BigInteger(int sign, int bits) { this(sign, 1, new int[] {bits}); } BigInteger(int sign, int lowBits, int highBits) { this(sign, 2, new int[] {lowBits, highBits}); } /** * Creates a new {@code BigInteger} with the given sign and magnitude. This constructor does not * create a copy, so any changes to the reference will affect the new number. * * @param signum The sign of the number represented by {@code digits} * @param digits The magnitude of the number */ BigInteger(int signum, int digits[]) { if (digits.length == 0) { sign = 0; numberLength = 1; this.digits = new int[] {0}; } else { sign = signum; numberLength = digits.length; this.digits = digits; cutOffLeadingZeroes(); } } /** * Constructs a number without to create new space. This construct should be used only if the * three fields of representation are known. * * @param sign the sign of the number * @param numberLength the length of the internal array * @param digits a reference of some array created before */ BigInteger(int sign, int numberLength, int[] digits) { this.sign = sign; this.numberLength = numberLength; this.digits = digits; } /** * Returns a (new) {@code BigInteger} whose value is the absolute value of * {@code this}. * * @return {@code abs(this)}. */ public BigInteger abs() { return sign < 0 ? negate() : this; } /** * Returns a new {@code BigInteger} whose value is {@code this + val}. * * @param val value to be added to {@code this}. * @return {@code this + val}. * @throws NullPointerException if {@code val == null}. */ public BigInteger add(BigInteger val) { return Elementary.add(this, val); } /** * Returns a new {@code BigInteger} whose value is {@code this & val}. *

* Implementation Note: Usage of this method is not recommended as the * current implementation is not efficient. * * @param val value to be and'ed with {@code this}. * @return {@code this & val}. * @throws NullPointerException if {@code val == null}. */ public BigInteger and(BigInteger val) { return Logical.and(this, val); } /** * Returns a new {@code BigInteger} whose value is {@code this & ~val}. * Evaluating {@code x.andNot(val)} returns the same result as {@code * x.and(val.not())}. *

* Implementation Note: Usage of this method is not recommended as the * current implementation is not efficient. * * @param val value to be not'ed and then and'ed with {@code this}. * @return {@code this & ~val}. * @throws NullPointerException if {@code val == null}. */ public BigInteger andNot(BigInteger val) { return Logical.andNot(this, val); } /** * Use {@code bitLength(0)} if you want to know the length of the binary value * in bits. *

* Returns the number of bits in the binary representation of {@code this} * which differ from the sign bit. If {@code this} is positive the result is * equivalent to the number of bits set in the binary representation of * {@code this}. If {@code this} is negative the result is equivalent to the * number of bits set in the binary representation of {@code -this-1}. *

* Implementation Note: Usage of this method is not recommended as the * current implementation is not efficient. * * @return number of bits in the binary representation of {@code this} which * differ from the sign bit */ public int bitCount() { return BitLevel.bitCount(this); } /** * Returns the length of the value's two's complement representation without * leading zeros for positive numbers / without leading ones for negative * values. *

* The two's complement representation of {@code this} will be at least * {@code bitLength() + 1} bits long. *

* The value will fit into an {@code int} if {@code bitLength() < 32} or into * a {@code long} if {@code bitLength() < 64}. * * @return the length of the minimal two's complement representation for * {@code this} without the sign bit. */ public int bitLength() { return BitLevel.bitLength(this); } /** * Converts value of this {@code BigInteger} to a {@code byte} if it fits it, * otherwise {@code ArithmeticException} is thrown. * * @return this {@code BigInteger} converted to a {@code byte}. * @throws ArithmeticException if the value of this {@code BigInteger} * does not fit in a {@code byte}. */ public byte byteValueExact() { if (numberLength <= 1 && bitLength() < Byte.SIZE) { return byteValue(); } throw new ArithmeticException("out of byte range"); } /** * Returns a new {@code BigInteger} which has the same binary representation * as {@code this} but with the bit at position n cleared. The result is * equivalent to {@code this & ~(2^n)}. *

* Implementation Note: Usage of this method is not recommended as the * current implementation is not efficient. * * @param n position where the bit in {@code this} has to be cleared. * @return {@code this & ~(2^n)}. * @throws ArithmeticException if {@code n < 0}. */ public BigInteger clearBit(int n) { if (testBit(n)) { return BitLevel.flipBit(this, n); } return this; } /** * Compares this {@code BigInteger} with {@code val}. Returns one of the three * values 1, 0, or -1. * * @param val value to be compared with {@code this}. * @return {@code 1} if {@code this > val}, {@code -1} if {@code this < val} , * {@code 0} if {@code this == val}. * @throws NullPointerException if {@code val == null}. */ @Override public int compareTo(BigInteger val) { if (sign > val.sign) { return GREATER; } if (sign < val.sign) { return LESS; } if (numberLength > val.numberLength) { return sign; } if (numberLength < val.numberLength) { return -val.sign; } // Equal sign and equal numberLength return (sign * Elementary.compareArrays(digits, val.digits, numberLength)); } /** * Returns a new {@code BigInteger} whose value is {@code this / divisor}. * * @param divisor value by which {@code this} is divided. * @return {@code this / divisor}. * @throws NullPointerException if {@code divisor == null}. * @throws ArithmeticException if {@code divisor == 0}. */ public BigInteger divide(BigInteger divisor) { if (divisor.sign == 0) { // math.17=BigInteger divide by zero throw new ArithmeticException("BigInteger divide by zero"); //$NON-NLS-1$ } int divisorSign = divisor.sign; if (divisor.isOne()) { return ((divisor.sign > 0) ? this : this.negate()); } int thisSign = sign; int thisLen = numberLength; int divisorLen = divisor.numberLength; if (thisLen + divisorLen == 2) { long val = (digits[0] & 0xFFFFFFFFL) / (divisor.digits[0] & 0xFFFFFFFFL); if (thisSign != divisorSign) { val = -val; } return valueOf(val); } int cmp = ((thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1) : Elementary.compareArrays(digits, divisor.digits, thisLen)); if (cmp == EQUALS) { return ((thisSign == divisorSign) ? ONE : MINUS_ONE); } if (cmp == LESS) { return ZERO; } int resLength = thisLen - divisorLen + 1; int resDigits[] = new int[resLength]; int resSign = ((thisSign == divisorSign) ? 1 : -1); if (divisorLen == 1) { Division.divideArrayByInt(resDigits, digits, thisLen, divisor.digits[0]); } else { Division.divide(resDigits, resLength, digits, thisLen, divisor.digits, divisorLen); } BigInteger result = new BigInteger(resSign, resLength, resDigits); result.cutOffLeadingZeroes(); return result; } /** * Returns a {@code BigInteger} array which contains {@code this / divisor} at * index 0 and {@code this % divisor} at index 1. * * @param divisor value by which {@code this} is divided. * @return {@code [this / divisor, this % divisor]}. * @throws NullPointerException if {@code divisor == null}. * @throws ArithmeticException if {@code divisor == 0}. * @see #divide * @see #remainder */ public BigInteger[] divideAndRemainder(BigInteger divisor) { int divisorSign = divisor.sign; if (divisorSign == 0) { // math.17=BigInteger divide by zero throw new ArithmeticException("BigInteger divide by zero"); //$NON-NLS-1$ } int divisorLen = divisor.numberLength; int[] divisorDigits = divisor.digits; if (divisorLen == 1) { return Division.divideAndRemainderByInteger(this, divisorDigits[0], divisorSign); } // res[0] is a quotient and res[1] is a remainder: int[] thisDigits = digits; int thisLen = numberLength; int cmp = (thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1) : Elementary.compareArrays(thisDigits, divisorDigits, thisLen); if (cmp < 0) { return new BigInteger[] {ZERO, this}; } int thisSign = sign; int quotientLength = thisLen - divisorLen + 1; int remainderLength = divisorLen; int quotientSign = ((thisSign == divisorSign) ? 1 : -1); int quotientDigits[] = new int[quotientLength]; int remainderDigits[] = Division.divide(quotientDigits, quotientLength, thisDigits, thisLen, divisorDigits, divisorLen); BigInteger result0 = new BigInteger(quotientSign, quotientLength, quotientDigits); BigInteger result1 = new BigInteger(thisSign, remainderLength, remainderDigits); result0.cutOffLeadingZeroes(); result1.cutOffLeadingZeroes(); return new BigInteger[] {result0, result1}; } /** * Returns this {@code BigInteger} as an double value. If {@code this} is too * big to be represented as an double, then {@code Double.POSITIVE_INFINITY} * or {@code Double.NEGATIVE_INFINITY} is returned. Note, that not all * integers x in the range [-Double.MAX_VALUE, Double.MAX_VALUE] can be * represented as a double. The double representation has a mantissa of length * 53. For example, 2^53+1 = 9007199254740993 is returned as double * 9007199254740992.0. * * @return this {@code BigInteger} as a double value */ @Override public double doubleValue() { return Double.parseDouble(this.toString()); } /** * Returns {@code true} if {@code x} is a BigInteger instance and if this * instance is equal to this {@code BigInteger}. * * @param x object to be compared with {@code this}. * @return true if {@code x} is a BigInteger and {@code this == x}, {@code * false} otherwise. */ @Override public boolean equals(Object x) { if (this == x) { return true; } if (x instanceof BigInteger) { BigInteger x1 = (BigInteger) x; return sign == x1.sign && numberLength == x1.numberLength && equalsArrays(x1.digits); } return false; } /** * Returns a new {@code BigInteger} which has the same binary representation * as {@code this} but with the bit at position n flipped. The result is * equivalent to {@code this ^ 2^n}. *

* Implementation Note: Usage of this method is not recommended as the * current implementation is not efficient. * * @param n position where the bit in {@code this} has to be flipped. * @return {@code this ^ 2^n}. * @throws ArithmeticException if {@code n < 0}. */ public BigInteger flipBit(int n) { if (n < 0) { // math.15=Negative bit address throw new ArithmeticException("Negative bit address"); //$NON-NLS-1$ } return BitLevel.flipBit(this, n); } /** * Returns this {@code BigInteger} as an float value. If {@code this} is too * big to be represented as an float, then {@code Float.POSITIVE_INFINITY} or * {@code Float.NEGATIVE_INFINITY} is returned. Note, that not all integers x * in the range [-Float.MAX_VALUE, Float.MAX_VALUE] can be represented as a * float. The float representation has a mantissa of length 24. For example, * 2^24+1 = 16777217 is returned as float 16777216.0. * * @return this {@code BigInteger} as a float value. */ @Override public float floatValue() { return Float.parseFloat(this.toString()); } /** * Returns a new {@code BigInteger} whose value is greatest common divisor of * {@code this} and {@code val}. If {@code this==0} and {@code val==0} then * zero is returned, otherwise the result is positive. * * @param val value with which the greatest common divisor is computed. * @return {@code gcd(this, val)}. * @throws NullPointerException if {@code val == null}. */ public BigInteger gcd(BigInteger val) { BigInteger val1 = this.abs(); BigInteger val2 = val.abs(); // To avoid a possible division by zero if (val1.signum() == 0) { return val2; } else if (val2.signum() == 0) { return val1; } // Optimization for small operands // (op2.bitLength() < 64) and (op1.bitLength() < 64) if (((val1.numberLength == 1) || ((val1.numberLength == 2) && (val1.digits[1] > 0))) && (val2.numberLength == 1 || (val2.numberLength == 2 && val2.digits[1] > 0))) { return BigInteger.valueOf(Division.gcdBinary(val1.longValue(), val2.longValue())); } return Division.gcdBinary(val1.copy(), val2.copy()); } /** * Returns the position of the lowest set bit in the two's complement * representation of this {@code BigInteger}. If all bits are zero (this=0) * then -1 is returned as result. *

* Implementation Note: Usage of this method is not recommended as the * current implementation is not efficient. * * @return position of lowest bit if {@code this != 0}, {@code -1} otherwise */ public int getLowestSetBit() { if (sign == 0) { return -1; } // (sign != 0) implies that exists some non zero digit int i = getFirstNonzeroDigit(); return ((i << 5) + Integer.numberOfTrailingZeros(digits[i])); } /** * Returns a hash code for this {@code BigInteger}. * * @return hash code for {@code this}. */ @Override public int hashCode() { if (hashCode != 0) { return hashCode; } for (int i = 0; i < digits.length; i++) { hashCode = (hashCode * 33 + (digits[i] & 0xffffffff)); } hashCode = hashCode * sign; return hashCode; } /** * Returns this {@code BigInteger} as an int value. If {@code this} is too big * to be represented as an int, then {@code this} % 2^32 is returned. * * @return this {@code BigInteger} as an int value. */ @Override public int intValue() { int i = digits[0]; // i is always positive except for Integer.MIN_VALUE because of int overflow return sign > 0 ? i : ensureInt(-i); } /** * Converts value of this {@code BigInteger} to an {@code int} if it fits it, * otherwise {@code ArithmeticException} is thrown. * * @return this {@code BigInteger} converted to an {@code int}. * @throws ArithmeticException if the value of this {@code BigInteger} * does not fit in an {@code int}. */ public int intValueExact() { if (numberLength <= 1 && bitLength() < Integer.SIZE) { return intValue(); } throw new ArithmeticException("out of int range"); } /** * Tests whether this {@code BigInteger} is probably prime. If {@code true} is * returned, then this is prime with a probability beyond (1-1/2^certainty). * If {@code false} is returned, then this is definitely composite. If the * argument {@code certainty} <= 0, then this method returns true. * * @param certainty tolerated primality uncertainty. * @return {@code true}, if {@code this} is probably prime, {@code false} * otherwise. */ public boolean isProbablePrime(int certainty) { return Primality.isProbablePrime(abs(), certainty); } /** * Returns this {@code BigInteger} as an long value. If {@code this} is too * big to be represented as an long, then {@code this} % 2^64 is returned. * * @return this {@code BigInteger} as a long value. */ @Override public long longValue() { long value = numberLength > 1 ? LongUtils.fromBits(digits[0], digits[1]) : LongUtils.fromBits(digits[0], 0); return sign > 0 ? value : -value; } /** * Converts value of this {@code BigInteger} to a {@code long} if it fits it, * otherwise {@code ArithmeticException} is thrown. * * @return this {@code BigInteger} converted to a {@code long}. * @throws ArithmeticException if the value of this {@code BigInteger} * does not fit in a {@code long}. */ public long longValueExact() { if (numberLength <= 2 && bitLength() < Long.SIZE) { return longValue(); } throw new ArithmeticException("out of long range"); } /** * Returns the maximum of this {@code BigInteger} and {@code val}. * * @param val value to be used to compute the maximum with {@code this} * @return {@code max(this, val)} * @throws NullPointerException if {@code val == null} */ public BigInteger max(BigInteger val) { return ((this.compareTo(val) == GREATER) ? this : val); } /** * Returns the minimum of this {@code BigInteger} and {@code val}. * * @param val value to be used to compute the minimum with {@code this}. * @return {@code min(this, val)}. * @throws NullPointerException if {@code val == null}. */ public BigInteger min(BigInteger val) { return ((this.compareTo(val) == LESS) ? this : val); } /** * Returns a new {@code BigInteger} whose value is {@code this mod m}. The * modulus {@code m} must be positive. The result is guaranteed to be in the * interval {@code [0, m)} (0 inclusive, m exclusive). The behavior of this * function is not equivalent to the behavior of the % operator defined for * the built-in {@code int}'s. * * @param m the modulus. * @return {@code this mod m}. * @throws NullPointerException if {@code m == null}. * @throws ArithmeticException if {@code m < 0}. */ public BigInteger mod(BigInteger m) { if (m.sign <= 0) { // math.18=BigInteger: modulus not positive throw new ArithmeticException("BigInteger: modulus not positive"); //$NON-NLS-1$ } BigInteger rem = remainder(m); return ((rem.sign < 0) ? rem.add(m) : rem); } // @Override // public double doubleValue() { // return Conversion.bigInteger2Double(this); // } /** * Returns a new {@code BigInteger} whose value is {@code 1/this mod m}. The * modulus {@code m} must be positive. The result is guaranteed to be in the * interval {@code [0, m)} (0 inclusive, m exclusive). If {@code this} is not * relatively prime to m, then an exception is thrown. * * @param m the modulus. * @return {@code 1/this mod m}. * @throws NullPointerException if {@code m == null} * @throws ArithmeticException if {@code m < 0 or} if {@code this} is not * relatively prime to {@code m} */ public BigInteger modInverse(BigInteger m) { if (m.sign <= 0) { // math.18=BigInteger: modulus not positive throw new ArithmeticException("BigInteger: modulus not positive"); //$NON-NLS-1$ } // If both are even, no inverse exists if (!(testBit(0) || m.testBit(0))) { // math.19=BigInteger not invertible. throw new ArithmeticException("BigInteger not invertible."); //$NON-NLS-1$ } if (m.isOne()) { return ZERO; } // From now on: (m > 1) BigInteger res = Division.modInverseMontgomery(abs().mod(m), m); if (res.sign == 0) { // math.19=BigInteger not invertible. throw new ArithmeticException("BigInteger not invertible."); //$NON-NLS-1$ } res = ((sign < 0) ? m.subtract(res) : res); return res; } /** * Returns a new {@code BigInteger} whose value is {@code this^exponent mod m} * . The modulus {@code m} must be positive. The result is guaranteed to be in * the interval {@code [0, m)} (0 inclusive, m exclusive). If the exponent is * negative, then {@code this.modInverse(m)^(-exponent) mod m)} is computed. * The inverse of this only exists if {@code this} is relatively prime to m, * otherwise an exception is thrown. * * @param exponent the exponent. * @param m the modulus. * @return {@code this^exponent mod val}. * @throws NullPointerException if {@code m == null} or {@code exponent == * null}. * @throws ArithmeticException if {@code m < 0} or if {@code exponent<0} and * this is not relatively prime to {@code m}. */ public BigInteger modPow(BigInteger exponent, BigInteger m) { if (m.sign <= 0) { // math.18=BigInteger: modulus not positive throw new ArithmeticException("BigInteger: modulus not positive"); //$NON-NLS-1$ } BigInteger base = this; if (m.isOne() | (exponent.sign > 0 & base.sign == 0)) { return BigInteger.ZERO; } if (base.sign == 0 && exponent.sign == 0) { return BigInteger.ONE; } if (exponent.sign < 0) { base = modInverse(m); exponent = exponent.negate(); } // From now on: (m > 0) and (exponent >= 0) BigInteger res = (m.testBit(0)) ? Division.oddModPow(base.abs(), exponent, m) : Division.evenModPow(base.abs(), exponent, m); if ((base.sign < 0) && exponent.testBit(0)) { // -b^e mod m == ((-1 mod m) * (b^e mod m)) mod m res = m.subtract(BigInteger.ONE).multiply(res).mod(m); } // else exponent is even, so base^exp is positive return res; } /** * Returns a new {@code BigInteger} whose value is {@code this * val}. * * @param val value to be multiplied with {@code this}. * @return {@code this * val}. * @throws NullPointerException if {@code val == null}. */ public BigInteger multiply(BigInteger val) { // This let us to throw NullPointerException when val == null if (val.sign == 0 || sign == 0) { return ZERO; } return Multiplication.multiply(this, val); } /** * Returns a new {@code BigInteger} whose value is the {@code -this}. * * @return {@code -this}. */ public BigInteger negate() { return sign == 0 ? this : new BigInteger(-sign, numberLength, digits); } /** * Returns the smallest integer x > {@code this} which is probably prime as a * {@code BigInteger} instance. The probability that the returned {@code * BigInteger} is prime is beyond (1-1/2^80). * * @return smallest integer > {@code this} which is robably prime. * @throws ArithmeticException if {@code this < 0}. */ public BigInteger nextProbablePrime() { if (sign < 0) { // math.1A=start < 0: {0} throw new ArithmeticException("start < 0: " + this); //$NON-NLS-1$ } return Primality.nextProbablePrime(this); } /** * Returns a new {@code BigInteger} whose value is {@code ~this}. The result * of this operation is {@code -this-1}. *

* Implementation Note: Usage of this method is not recommended as the * current implementation is not efficient. * * @return {@code ~this}. */ public BigInteger not() { return Logical.not(this); } /** * Returns a new {@code BigInteger} whose value is {@code this | val}. *

* Implementation Note: Usage of this method is not recommended as the * current implementation is not efficient. * * @param val value to be or'ed with {@code this}. * @return {@code this | val}. * @throws NullPointerException if {@code val == null}. */ public BigInteger or(BigInteger val) { return Logical.or(this, val); } /** * Returns a new {@code BigInteger} whose value is {@code this ^ exp}. * * @param exp exponent to which {@code this} is raised. * @return {@code this ^ exp}. * @throws ArithmeticException if {@code exp < 0}. */ public BigInteger pow(int exp) { if (exp < 0) { // math.16=Negative exponent throw new ArithmeticException("Negative exponent"); //$NON-NLS-1$ } if (exp == 0) { return ONE; } else if (exp == 1 || equals(ONE) || equals(ZERO)) { return this; } // if even take out 2^x factor which we can // calculate by shifting. if (!testBit(0)) { int x = 1; while (!testBit(x)) { x++; } return getPowerOfTwo(x * exp).multiply(this.shiftRight(x).pow(exp)); } return Multiplication.pow(this, exp); } /** * Returns a new {@code BigInteger} whose value is {@code this % divisor}. * Regarding signs this methods has the same behavior as the % operator on * int's, i.e. the sign of the remainder is the same as the sign of this. * * @param divisor value by which {@code this} is divided. * @return {@code this % divisor}. * @throws NullPointerException if {@code divisor == null}. * @throws ArithmeticException if {@code divisor == 0}. */ public BigInteger remainder(BigInteger divisor) { if (divisor.sign == 0) { // math.17=BigInteger divide by zero throw new ArithmeticException("BigInteger divide by zero"); //$NON-NLS-1$ } int thisLen = numberLength; int divisorLen = divisor.numberLength; if (((thisLen != divisorLen) ? ((thisLen > divisorLen) ? 1 : -1) : Elementary.compareArrays(digits, divisor.digits, thisLen)) == LESS) { return this; } int resLength = divisorLen; int resDigits[] = new int[resLength]; if (resLength == 1) { resDigits[0] = Division.remainderArrayByInt(digits, thisLen, divisor.digits[0]); } else { int qLen = thisLen - divisorLen + 1; resDigits = Division.divide(null, qLen, digits, thisLen, divisor.digits, divisorLen); } BigInteger result = new BigInteger(sign, resLength, resDigits); result.cutOffLeadingZeroes(); return result; } /** * Returns a new {@code BigInteger} which has the same binary representation * as {@code this} but with the bit at position n set. The result is * equivalent to {@code this | 2^n}. *

* Implementation Note: Usage of this method is not recommended as the * current implementation is not efficient. * * @param n position where the bit in {@code this} has to be set. * @return {@code this | 2^n}. * @throws ArithmeticException if {@code n < 0}. */ public BigInteger setBit(int n) { if (!testBit(n)) { return BitLevel.flipBit(this, n); } return this; } /** * Returns a new {@code BigInteger} whose value is {@code this << n}. The * result is equivalent to {@code this * 2^n} if n >= 0. The shift distance * may be negative which means that {@code this} is shifted right. The result * then corresponds to {@code floor(this / 2^(-n))}. *

* Implementation Note: Usage of this method on negative values is not * recommended as the current implementation is not efficient. * * @param n shift distance. * @return {@code this << n} if {@code n >= 0}; {@code this >> (-n)}. * otherwise */ public BigInteger shiftLeft(int n) { if ((n == 0) || (sign == 0)) { return this; } return ((n > 0) ? BitLevel.shiftLeft(this, n) : BitLevel.shiftRight(this, -n)); } /** * Returns a new {@code BigInteger} whose value is {@code this >> n}. For * negative arguments, the result is also negative. The shift distance may be * negative which means that {@code this} is shifted left. *

* Implementation Note: Usage of this method on negative values is not * recommended as the current implementation is not efficient. * * @param n shift distance * @return {@code this >> n} if {@code n >= 0}; {@code this << (-n)} otherwise */ public BigInteger shiftRight(int n) { if ((n == 0) || (sign == 0)) { return this; } return ((n > 0) ? BitLevel.shiftRight(this, n) : BitLevel.shiftLeft(this, -n)); } /** * Converts value of this {@code BigInteger} to a {@code short} if it fits it, * otherwise {@code ArithmeticException} is thrown. * * @return this {@code BigInteger} converted to a {@code short}. * @throws ArithmeticException if the value of this {@code BigInteger} * does not fit in a {@code short}. */ public short shortValueExact() { if (numberLength <= 1 && bitLength() < Short.SIZE) { return shortValue(); } throw new ArithmeticException("out of short range"); } /** * Returns the sign of this {@code BigInteger}. * * @return {@code -1} if {@code this < 0}, {@code 0} if {@code this == 0}, * {@code 1} if {@code this > 0}. */ public int signum() { return sign; } /** * Returns a new {@code BigInteger} whose value is {@code this - val}. * * @param val value to be subtracted from {@code this}. * @return {@code this - val}. * @throws NullPointerException if {@code val == null}. */ public BigInteger subtract(BigInteger val) { return Elementary.subtract(this, val); } /** * Tests whether the bit at position n in {@code this} is set. The result is * equivalent to {@code this & (2^n) != 0}. *

* Implementation Note: Usage of this method is not recommended as the * current implementation is not efficient. * * @param n position where the bit in {@code this} has to be inspected. * @return {@code this & (2^n) != 0}. * @throws ArithmeticException if {@code n < 0}. */ public boolean testBit(int n) { if (n == 0) { return ((digits[0] & 1) != 0); } if (n < 0) { // math.15=Negative bit address throw new ArithmeticException("Negative bit address"); //$NON-NLS-1$ } int intCount = n >> 5; if (intCount >= numberLength) { return (sign < 0); } int digit = digits[intCount]; n = (1 << (n & 31)); // int with 1 set to the needed position if (sign < 0) { int firstNonZeroDigit = getFirstNonzeroDigit(); if (intCount < firstNonZeroDigit) { return false; } else if (firstNonZeroDigit == intCount) { digit = -digit; } else { digit = ~digit; } } return ((digit & n) != 0); } /** * Returns the two's complement representation of this BigInteger in a byte * array. * * @return two's complement representation of {@code this}. */ public byte[] toByteArray() { if (this.sign == 0) { return new byte[] {0}; } BigInteger temp = this; int bitLen = bitLength(); int iThis = getFirstNonzeroDigit(); int bytesLen = (bitLen >> 3) + 1; /* * Puts the little-endian int array representing the magnitude of this * BigInteger into the big-endian byte array. */ byte[] bytes = new byte[bytesLen]; int firstByteNumber = 0; int highBytes; int digitIndex = 0; int bytesInInteger = 4; int digit; int hB; if (bytesLen - (numberLength << 2) == 1) { bytes[0] = (byte) ((sign < 0) ? -1 : 0); highBytes = 4; firstByteNumber++; } else { hB = bytesLen & 3; highBytes = (hB == 0) ? 4 : hB; } digitIndex = iThis; bytesLen -= iThis << 2; if (sign < 0) { digit = -temp.digits[digitIndex]; digitIndex++; if (digitIndex == numberLength) { bytesInInteger = highBytes; } for (int i = 0; i < bytesInInteger; i++, digit >>= 8) { bytes[--bytesLen] = (byte) digit; } while (bytesLen > firstByteNumber) { digit = ~temp.digits[digitIndex]; digitIndex++; if (digitIndex == numberLength) { bytesInInteger = highBytes; } for (int i = 0; i < bytesInInteger; i++, digit >>= 8) { bytes[--bytesLen] = (byte) digit; } } } else { while (bytesLen > firstByteNumber) { digit = temp.digits[digitIndex]; digitIndex++; if (digitIndex == numberLength) { bytesInInteger = highBytes; } for (int i = 0; i < bytesInInteger; i++, digit >>= 8) { bytes[--bytesLen] = (byte) digit; } } } return bytes; } /** * Returns a string representation of this {@code BigInteger} in decimal form. * * @return a string representation of {@code this} in decimal form. */ @Override public String toString() { return Conversion.toDecimalScaledString(this, 0); } /** * Returns a string containing a string representation of this {@code * BigInteger} with base radix. If {@code radix} is less than * {@link Character#MIN_RADIX} or greater than {@link Character#MAX_RADIX} * then a decimal representation is returned. The characters of the string * representation are generated with method {@link Character#forDigit}. * * @param radix base to be used for the string representation. * @return a string representation of this with radix 10. */ public String toString(int radix) { return Conversion.bigInteger2String(this, radix); } /** * Returns a new {@code BigInteger} whose value is {@code this ^ val}. *

* Implementation Note: Usage of this method is not recommended as the * current implementation is not efficient. * * @param val value to be xor'ed with {@code this} * @return {@code this ^ val} * @throws NullPointerException if {@code val == null} */ public BigInteger xor(BigInteger val) { return Logical.xor(this, val); } /* * Returns a copy of the current instance to achieve immutability */ BigInteger copy() { int[] copyDigits = new int[numberLength]; System.arraycopy(digits, 0, copyDigits, 0, numberLength); return new BigInteger(sign, numberLength, copyDigits); } /* Private Methods */ /** * Decreases {@code numberLength} if there are zero high elements. */ final void cutOffLeadingZeroes() { while ((numberLength > 0) && (digits[--numberLength] == 0)) { // Empty } if (digits[numberLength++] == 0) { sign = 0; } } boolean equalsArrays(final int[] b) { int i; for (i = numberLength - 1; (i >= 0) && (digits[i] == b[i]); i--) { // Empty } return i < 0; } int getFirstNonzeroDigit() { if (firstNonzeroDigit == -2) { int i; if (this.sign == 0) { i = -1; } else { for (i = 0; digits[i] == 0; i++) { // Empty } } firstNonzeroDigit = i; } return firstNonzeroDigit; } /** * Tests if {@code this.abs()} is equals to {@code ONE}. */ boolean isOne() { return ((numberLength == 1) && (digits[0] == 1)); } BigInteger shiftLeftOneBit() { return (sign == 0) ? this : BitLevel.shiftLeftOneBit(this); } void unCache() { firstNonzeroDigit = -2; } /** * Puts a big-endian byte array into a little-endian applying two complement. */ private void putBytesNegativeToIntegers(byte[] byteValues) { int bytesLen = byteValues.length; int highBytes = bytesLen & 3; numberLength = (bytesLen >> 2) + ((highBytes == 0) ? 0 : 1); digits = new int[numberLength]; int i = 0; // Setting the sign digits[numberLength - 1] = -1; // Put bytes to the int array starting from the end of the byte array while (bytesLen > highBytes) { digits[i] = (byteValues[--bytesLen] & 0xFF) | (byteValues[--bytesLen] & 0xFF) << 8 | (byteValues[--bytesLen] & 0xFF) << 16 | (byteValues[--bytesLen] & 0xFF) << 24; if (digits[i] != 0) { digits[i] = -digits[i]; firstNonzeroDigit = i; i++; while (bytesLen > highBytes) { digits[i] = (byteValues[--bytesLen] & 0xFF) | (byteValues[--bytesLen] & 0xFF) << 8 | (byteValues[--bytesLen] & 0xFF) << 16 | (byteValues[--bytesLen] & 0xFF) << 24; digits[i] = ~digits[i]; i++; } break; } i++; } if (highBytes != 0) { // Put the first bytes in the highest element of the int array if (firstNonzeroDigit != -2) { for (int j = 0; j < bytesLen; j++) { digits[i] = (digits[i] << 8) | (byteValues[j] & 0xFF); } digits[i] = ~digits[i]; } else { for (int j = 0; j < bytesLen; j++) { digits[i] = (digits[i] << 8) | (byteValues[j] & 0xFF); } digits[i] = -digits[i]; } } } /** * Puts a big-endian byte array into a little-endian int array. */ private void putBytesPositiveToIntegers(byte[] byteValues) { int bytesLen = byteValues.length; int highBytes = bytesLen & 3; numberLength = (bytesLen >> 2) + ((highBytes == 0) ? 0 : 1); digits = new int[numberLength]; int i = 0; // Put bytes to the int array starting from the end of the byte array while (bytesLen > highBytes) { digits[i++] = (byteValues[--bytesLen] & 0xFF) | (byteValues[--bytesLen] & 0xFF) << 8 | (byteValues[--bytesLen] & 0xFF) << 16 | (byteValues[--bytesLen] & 0xFF) << 24; } // Put the first bytes in the highest element of the int array for (int j = 0; j < bytesLen; j++) { digits[i] = (digits[i] << 8) | (byteValues[j] & 0xFF); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy