mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Adds java.math support
This commit is contained in:
parent
08c912e80f
commit
e5a4e3fa62
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright 2014 Alexey Andreev.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package org.teavm.classlib.java.lang;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class TArithmeticException extends TRuntimeException {
|
||||
private static final long serialVersionUID = 8084592456171302650L;
|
||||
|
||||
public TArithmeticException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public TArithmeticException(TString message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,353 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
/**
|
||||
* Static library that provides all the <b>bit level</b> operations for
|
||||
* {@link TBigInteger}. The operations are:
|
||||
* <ul type="circle">
|
||||
* <li>Left Shifting</li>
|
||||
* <li>Right Shifting</li>
|
||||
* <li>Bit clearing</li>
|
||||
* <li>Bit setting</li>
|
||||
* <li>Bit counting</li>
|
||||
* <li>Bit testing</li>
|
||||
* <li>Getting of the lowest bit set</li>
|
||||
* </ul>
|
||||
* All operations are provided in immutable way, and some in both mutable and
|
||||
* immutable.
|
||||
*/
|
||||
class TBitLevel {
|
||||
|
||||
/** Just to denote that this class can't be instantiated. */
|
||||
private TBitLevel() {}
|
||||
|
||||
/** @see TBigInteger#bitLength() */
|
||||
static int bitLength(TBigInteger val) {
|
||||
if (val.sign == 0) {
|
||||
return 0;
|
||||
}
|
||||
int bLength = (val.numberLength << 5);
|
||||
int highDigit = val.digits[val.numberLength - 1];
|
||||
|
||||
if (val.sign < 0) {
|
||||
int i = val.getFirstNonzeroDigit();
|
||||
// We reduce the problem to the positive case.
|
||||
if (i == val.numberLength - 1) {
|
||||
highDigit--;
|
||||
}
|
||||
}
|
||||
// Subtracting all sign bits
|
||||
bLength -= Integer.numberOfLeadingZeros(highDigit);
|
||||
return bLength;
|
||||
}
|
||||
|
||||
/** @see TBigInteger#bitCount() */
|
||||
static int bitCount(TBigInteger val) {
|
||||
int bCount = 0;
|
||||
|
||||
if (val.sign == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i = val.getFirstNonzeroDigit();
|
||||
if (val.sign > 0) {
|
||||
for ( ; i < val.numberLength; i++) {
|
||||
bCount += Integer.bitCount(val.digits[i]);
|
||||
}
|
||||
} else {// (sign < 0)
|
||||
// this digit absorbs the carry
|
||||
bCount += Integer.bitCount(-val.digits[i]);
|
||||
for (i++; i < val.numberLength; i++) {
|
||||
bCount += Integer.bitCount(~val.digits[i]);
|
||||
}
|
||||
// We take the complement sum:
|
||||
bCount = (val.numberLength << 5) - bCount;
|
||||
}
|
||||
return bCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a fast bit testing for positive numbers. The bit to to be tested
|
||||
* must be in the range {@code [0, val.bitLength()-1]}
|
||||
*/
|
||||
static boolean testBit(TBigInteger val, int n) {
|
||||
// PRE: 0 <= n < val.bitLength()
|
||||
return ((val.digits[n >> 5] & (1 << (n & 31))) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there are 1s in the lowest bits of this BigInteger
|
||||
*
|
||||
* @param numberOfBits the number of the lowest bits to check
|
||||
* @return false if all bits are 0s, true otherwise
|
||||
*/
|
||||
static boolean nonZeroDroppedBits(int numberOfBits, int digits[]) {
|
||||
int intCount = numberOfBits >> 5;
|
||||
int bitCount = numberOfBits & 31;
|
||||
int i;
|
||||
|
||||
for (i = 0; (i < intCount) && (digits[i] == 0); i++) {
|
||||
// do nothing
|
||||
}
|
||||
return ((i != intCount) || (digits[i] << (32 - bitCount) != 0));
|
||||
}
|
||||
|
||||
/** @see TBigInteger#shiftLeft(int) */
|
||||
static TBigInteger shiftLeft(TBigInteger source, int count) {
|
||||
int intCount = count >> 5;
|
||||
count &= 31; // %= 32
|
||||
int resLength = source.numberLength + intCount
|
||||
+ ( ( count == 0 ) ? 0 : 1 );
|
||||
int resDigits[] = new int[resLength];
|
||||
|
||||
shiftLeft(resDigits, source.digits, intCount, count);
|
||||
TBigInteger result = new TBigInteger(source.sign, resLength, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs {@code val <<= count}.
|
||||
*/
|
||||
// val should have enough place (and one digit more)
|
||||
static void inplaceShiftLeft(TBigInteger val, int count) {
|
||||
int intCount = count >> 5; // count of integers
|
||||
val.numberLength += intCount
|
||||
+ ( Integer
|
||||
.numberOfLeadingZeros(val.digits[val.numberLength - 1])
|
||||
- ( count & 31 ) >= 0 ? 0 : 1 );
|
||||
shiftLeft(val.digits, val.digits, intCount, count & 31);
|
||||
val.cutOffLeadingZeroes();
|
||||
val.unCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstractly shifts left an array of integers in little endian (i.e. shift
|
||||
* it right). Total shift distance in bits is intCount * 32 + count
|
||||
*
|
||||
* @param result the destination array
|
||||
* @param source the source array
|
||||
* @param intCount the shift distance in integers
|
||||
* @param count an additional shift distance in bits
|
||||
*/
|
||||
static void shiftLeft(int result[], int source[], int intCount, int count) {
|
||||
if (count == 0) {
|
||||
System.arraycopy(source, 0, result, intCount, result.length
|
||||
- intCount);
|
||||
} else {
|
||||
int rightShiftCount = 32 - count;
|
||||
|
||||
result[result.length - 1] = 0;
|
||||
for (int i = result.length - 1; i > intCount; i--) {
|
||||
result[i] |= source[i - intCount - 1] >>> rightShiftCount;
|
||||
result[i - 1] = source[i - intCount - 1] << count;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < intCount; i++) {
|
||||
result[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shifts the source digits left one bit, creating a value whose magnitude
|
||||
* is doubled.
|
||||
*
|
||||
* @param result an array of digits that will hold the computed result when
|
||||
* this method returns. The size of this array is {@code srcLen + 1},
|
||||
* and the format is the same as {@link TBigInteger#digits}.
|
||||
* @param source the array of digits to shift left, in the same format as
|
||||
* {@link TBigInteger#digits}.
|
||||
* @param srcLen the length of {@code source}; may be less than {@code
|
||||
* source.length}
|
||||
*/
|
||||
static void shiftLeftOneBit(int result[], int source[], int srcLen) {
|
||||
int carry = 0;
|
||||
for (int i = 0; i < srcLen; i++) {
|
||||
int val = source[i];
|
||||
result[i] = (val << 1) | carry;
|
||||
carry = val >>> 31;
|
||||
}
|
||||
if (carry != 0) {
|
||||
result[srcLen] = carry;
|
||||
}
|
||||
}
|
||||
|
||||
static TBigInteger shiftLeftOneBit(TBigInteger source) {
|
||||
int srcLen = source.numberLength;
|
||||
int resLen = srcLen + 1;
|
||||
int resDigits[] = new int[resLen];
|
||||
shiftLeftOneBit(resDigits, source.digits, srcLen);
|
||||
TBigInteger result = new TBigInteger(source.sign, resLen, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @see TBigInteger#shiftRight(int) */
|
||||
static TBigInteger shiftRight(TBigInteger source, int count) {
|
||||
int intCount = count >> 5; // count of integers
|
||||
count &= 31; // count of remaining bits
|
||||
if (intCount >= source.numberLength) {
|
||||
return ((source.sign < 0) ? TBigInteger.MINUS_ONE : TBigInteger.ZERO);
|
||||
}
|
||||
int i;
|
||||
int resLength = source.numberLength - intCount;
|
||||
int resDigits[] = new int[resLength + 1];
|
||||
|
||||
shiftRight(resDigits, resLength, source.digits, intCount, count);
|
||||
if (source.sign < 0) {
|
||||
// Checking if the dropped bits are zeros (the remainder equals to
|
||||
// 0)
|
||||
for (i = 0; (i < intCount) && (source.digits[i] == 0); i++) {
|
||||
// do nothing
|
||||
}
|
||||
// If the remainder is not zero, add 1 to the result
|
||||
if ((i < intCount)
|
||||
|| ((count > 0) && ((source.digits[i] << (32 - count)) != 0))) {
|
||||
for (i = 0; (i < resLength) && (resDigits[i] == -1); i++) {
|
||||
resDigits[i] = 0;
|
||||
}
|
||||
if (i == resLength) {
|
||||
resLength++;
|
||||
}
|
||||
resDigits[i]++;
|
||||
}
|
||||
}
|
||||
TBigInteger result = new TBigInteger(source.sign, resLength, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs {@code val >>= count} where {@code val} is a positive number.
|
||||
*/
|
||||
static void inplaceShiftRight(TBigInteger val, int count) {
|
||||
int sign = val.signum();
|
||||
if (count == 0 || val.signum() == 0)
|
||||
return;
|
||||
int intCount = count >> 5; // count of integers
|
||||
val.numberLength -= intCount;
|
||||
if (!shiftRight(val.digits, val.numberLength, val.digits, intCount,
|
||||
count & 31)
|
||||
&& sign < 0) {
|
||||
// remainder not zero: add one to the result
|
||||
int i;
|
||||
for (i = 0; ( i < val.numberLength ) && ( val.digits[i] == -1 ); i++) {
|
||||
val.digits[i] = 0;
|
||||
}
|
||||
if (i == val.numberLength) {
|
||||
val.numberLength++;
|
||||
}
|
||||
val.digits[i]++;
|
||||
}
|
||||
val.cutOffLeadingZeroes();
|
||||
val.unCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shifts right an array of integers. Total shift distance in bits is
|
||||
* intCount * 32 + count.
|
||||
*
|
||||
* @param result
|
||||
* the destination array
|
||||
* @param resultLen
|
||||
* the destination array's length
|
||||
* @param source
|
||||
* the source array
|
||||
* @param intCount
|
||||
* the number of elements to be shifted
|
||||
* @param count
|
||||
* the number of bits to be shifted
|
||||
* @return dropped bit's are all zero (i.e. remaider is zero)
|
||||
*/
|
||||
static boolean shiftRight(int result[], int resultLen, int source[],
|
||||
int intCount, int count) {
|
||||
int i;
|
||||
boolean allZero = true;
|
||||
for (i = 0; i < intCount; i++)
|
||||
allZero &= source[i] == 0;
|
||||
if (count == 0) {
|
||||
System.arraycopy(source, intCount, result, 0, resultLen);
|
||||
i = resultLen;
|
||||
} else {
|
||||
int leftShiftCount = 32 - count;
|
||||
|
||||
allZero &= ( source[i] << leftShiftCount ) == 0;
|
||||
for (i = 0; i < resultLen - 1; i++) {
|
||||
result[i] = ( source[i + intCount] >>> count )
|
||||
| ( source[i + intCount + 1] << leftShiftCount );
|
||||
}
|
||||
result[i] = ( source[i + intCount] >>> count );
|
||||
i++;
|
||||
}
|
||||
|
||||
return allZero;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a flipBit on the BigInteger, returning a BigInteger with the the
|
||||
* specified bit flipped.
|
||||
* @param intCount: the index of the element of the digits array where the operation will be performed
|
||||
* @param bitNumber: the bit's position in the intCount element
|
||||
*/
|
||||
static TBigInteger flipBit(TBigInteger val, int n){
|
||||
int resSign = (val.sign == 0) ? 1 : val.sign;
|
||||
int intCount = n >> 5;
|
||||
int bitN = n & 31;
|
||||
int resLength = Math.max(intCount + 1, val.numberLength) + 1;
|
||||
int resDigits[] = new int[resLength];
|
||||
int i;
|
||||
|
||||
int bitNumber = 1 << bitN;
|
||||
System.arraycopy(val.digits, 0, resDigits, 0, val.numberLength);
|
||||
|
||||
if (val.sign < 0) {
|
||||
if (intCount >= val.numberLength) {
|
||||
resDigits[intCount] = bitNumber;
|
||||
} else {
|
||||
//val.sign<0 y intCount < val.numberLength
|
||||
int firstNonZeroDigit = val.getFirstNonzeroDigit();
|
||||
if (intCount > firstNonZeroDigit) {
|
||||
resDigits[intCount] ^= bitNumber;
|
||||
} else if (intCount < firstNonZeroDigit) {
|
||||
resDigits[intCount] = -bitNumber;
|
||||
for (i=intCount + 1; i < firstNonZeroDigit; i++) {
|
||||
resDigits[i]=-1;
|
||||
}
|
||||
resDigits[i] = resDigits[i]--;
|
||||
} else {
|
||||
i = intCount;
|
||||
resDigits[i] = -((-resDigits[intCount]) ^ bitNumber);
|
||||
if (resDigits[i] == 0) {
|
||||
for (i++; resDigits[i] == -1 ; i++) {
|
||||
resDigits[i] = 0;
|
||||
}
|
||||
resDigits[i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {//case where val is positive
|
||||
resDigits[intCount] ^= bitNumber;
|
||||
}
|
||||
TBigInteger result = new TBigInteger(resSign, resLength, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,458 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
/**
|
||||
* Static library that provides {@link TBigInteger} base conversion from/to any
|
||||
* integer represented in an {@link java.lang.String} Object.
|
||||
*/
|
||||
class TConversion {
|
||||
|
||||
/** Just to denote that this class can't be instantiated */
|
||||
private TConversion() {}
|
||||
|
||||
/**
|
||||
* Holds the maximal exponent for each radix, so that radix<sup>digitFitInInt[radix]</sup>
|
||||
* fit in an {@code int} (32 bits).
|
||||
*/
|
||||
static final int[] digitFitInInt = { -1, -1, 31, 19, 15, 13, 11,
|
||||
11, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 5 };
|
||||
|
||||
/**
|
||||
* bigRadices values are precomputed maximal powers of radices (integer
|
||||
* numbers from 2 to 36) that fit into unsigned int (32 bits). bigRadices[0] =
|
||||
* 2 ^ 31, bigRadices[8] = 10 ^ 9, etc.
|
||||
*/
|
||||
|
||||
static final int bigRadices[] = { -2147483648, 1162261467,
|
||||
1073741824, 1220703125, 362797056, 1977326743, 1073741824,
|
||||
387420489, 1000000000, 214358881, 429981696, 815730721, 1475789056,
|
||||
170859375, 268435456, 410338673, 612220032, 893871739, 1280000000,
|
||||
1801088541, 113379904, 148035889, 191102976, 244140625, 308915776,
|
||||
387420489, 481890304, 594823321, 729000000, 887503681, 1073741824,
|
||||
1291467969, 1544804416, 1838265625, 60466176 };
|
||||
|
||||
|
||||
/** @see TBigInteger#toString(int) */
|
||||
static String bigInteger2String(TBigInteger val, int radix) {
|
||||
int sign = val.sign;
|
||||
int numberLength = val.numberLength;
|
||||
int digits[] = val.digits;
|
||||
|
||||
if (sign == 0) {
|
||||
return "0"; //$NON-NLS-1$
|
||||
}
|
||||
if (numberLength == 1) {
|
||||
int highDigit = digits[numberLength - 1];
|
||||
long v = highDigit & 0xFFFFFFFFL;
|
||||
if (sign < 0) {
|
||||
v = -v;
|
||||
}
|
||||
return Long.toString(v, radix);
|
||||
}
|
||||
if ((radix == 10) || (radix < Character.MIN_RADIX)
|
||||
|| (radix > Character.MAX_RADIX)) {
|
||||
return val.toString();
|
||||
}
|
||||
double bitsForRadixDigit;
|
||||
bitsForRadixDigit = Math.log(radix) / Math.log(2);
|
||||
int resLengthInChars = (int) (val.abs().bitLength() / bitsForRadixDigit + ((sign < 0) ? 1
|
||||
: 0)) + 1;
|
||||
|
||||
char result[] = new char[resLengthInChars];
|
||||
int currentChar = resLengthInChars;
|
||||
int resDigit;
|
||||
if (radix != 16) {
|
||||
int temp[] = new int[numberLength];
|
||||
System.arraycopy(digits, 0, temp, 0, numberLength);
|
||||
int tempLen = numberLength;
|
||||
int charsPerInt = digitFitInInt[radix];
|
||||
int i;
|
||||
// get the maximal power of radix that fits in int
|
||||
int bigRadix = bigRadices[radix - 2];
|
||||
while (true) {
|
||||
// divide the array of digits by bigRadix and convert remainders
|
||||
// to characters collecting them in the char array
|
||||
resDigit = TDivision.divideArrayByInt(temp, temp, tempLen,
|
||||
bigRadix);
|
||||
int previous = currentChar;
|
||||
do {
|
||||
result[--currentChar] = Character.forDigit(
|
||||
resDigit % radix, radix);
|
||||
} while (((resDigit /= radix) != 0) && (currentChar != 0));
|
||||
int delta = charsPerInt - previous + currentChar;
|
||||
for (i = 0; i < delta && currentChar > 0; i++) {
|
||||
result[--currentChar] = '0';
|
||||
}
|
||||
for (i = tempLen - 1; (i > 0) && (temp[i] == 0); i--) {
|
||||
// do nothing
|
||||
}
|
||||
tempLen = i + 1;
|
||||
if ((tempLen == 1) && (temp[0] == 0)) { // the quotient is 0
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// radix == 16
|
||||
for (int i = 0; i < numberLength; i++) {
|
||||
for (int j = 0; (j < 8) && (currentChar > 0); j++) {
|
||||
resDigit = digits[i] >> (j << 2) & 0xf;
|
||||
result[--currentChar] = Character.forDigit(resDigit, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (result[currentChar] == '0') {
|
||||
currentChar++;
|
||||
}
|
||||
if (sign == -1) {
|
||||
result[--currentChar] = '-';
|
||||
}
|
||||
return new String(result, currentChar, resLengthInChars - currentChar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the correspondent {@code String} representation of {@code val}
|
||||
* being scaled by {@code scale}.
|
||||
*
|
||||
* @see TBigInteger#toString()
|
||||
* @see TBigDecimal#toString()
|
||||
*/
|
||||
static String toDecimalScaledString(TBigInteger val, int scale) {
|
||||
int sign = val.sign;
|
||||
int numberLength = val.numberLength;
|
||||
int digits[] = val.digits;
|
||||
int resLengthInChars;
|
||||
int currentChar;
|
||||
char result[];
|
||||
|
||||
if (sign == 0) {
|
||||
switch (scale) {
|
||||
case 0:
|
||||
return "0"; //$NON-NLS-1$
|
||||
case 1:
|
||||
return "0.0"; //$NON-NLS-1$
|
||||
case 2:
|
||||
return "0.00"; //$NON-NLS-1$
|
||||
case 3:
|
||||
return "0.000"; //$NON-NLS-1$
|
||||
case 4:
|
||||
return "0.0000"; //$NON-NLS-1$
|
||||
case 5:
|
||||
return "0.00000"; //$NON-NLS-1$
|
||||
case 6:
|
||||
return "0.000000"; //$NON-NLS-1$
|
||||
default:
|
||||
StringBuilder result1 = new StringBuilder();
|
||||
if (scale < 0) {
|
||||
result1.append("0E+"); //$NON-NLS-1$
|
||||
} else {
|
||||
result1.append("0E"); //$NON-NLS-1$
|
||||
}
|
||||
result1.append(-scale);
|
||||
return result1.toString();
|
||||
}
|
||||
}
|
||||
// one 32-bit unsigned value may contains 10 decimal digits
|
||||
resLengthInChars = numberLength * 10 + 1 + 7;
|
||||
// Explanation why +1+7:
|
||||
// +1 - one char for sign if needed.
|
||||
// +7 - For "special case 2" (see below) we have 7 free chars for
|
||||
// inserting necessary scaled digits.
|
||||
result = new char[resLengthInChars + 1];
|
||||
// allocated [resLengthInChars+1] characters.
|
||||
// a free latest character may be used for "special case 1" (see
|
||||
// below)
|
||||
currentChar = resLengthInChars;
|
||||
if (numberLength == 1) {
|
||||
int highDigit = digits[0];
|
||||
if (highDigit < 0) {
|
||||
long v = highDigit & 0xFFFFFFFFL;
|
||||
do {
|
||||
long prev = v;
|
||||
v /= 10;
|
||||
result[--currentChar] = (char) (0x0030 + ((int) (prev - v * 10)));
|
||||
} while (v != 0);
|
||||
} else {
|
||||
int v = highDigit;
|
||||
do {
|
||||
int prev = v;
|
||||
v /= 10;
|
||||
result[--currentChar] = (char) (0x0030 + (prev - v * 10));
|
||||
} while (v != 0);
|
||||
}
|
||||
} else {
|
||||
int temp[] = new int[numberLength];
|
||||
int tempLen = numberLength;
|
||||
System.arraycopy(digits, 0, temp, 0, tempLen);
|
||||
BIG_LOOP: while (true) {
|
||||
// divide the array of digits by bigRadix and convert
|
||||
// remainders
|
||||
// to characters collecting them in the char array
|
||||
long result11 = 0;
|
||||
for (int i1 = tempLen - 1; i1 >= 0; i1--) {
|
||||
long temp1 = (result11 << 32)
|
||||
+ (temp[i1] & 0xFFFFFFFFL);
|
||||
long res = divideLongByBillion(temp1);
|
||||
temp[i1] = (int) res;
|
||||
result11 = (int) (res >> 32);
|
||||
}
|
||||
int resDigit = (int) result11;
|
||||
int previous = currentChar;
|
||||
do {
|
||||
result[--currentChar] = (char) (0x0030 + (resDigit % 10));
|
||||
} while (((resDigit /= 10) != 0) && (currentChar != 0));
|
||||
int delta = 9 - previous + currentChar;
|
||||
for (int i = 0; (i < delta) && (currentChar > 0); i++) {
|
||||
result[--currentChar] = '0';
|
||||
}
|
||||
int j = tempLen - 1;
|
||||
for (; temp[j] == 0; j--) {
|
||||
if (j == 0) { // means temp[0] == 0
|
||||
break BIG_LOOP;
|
||||
}
|
||||
}
|
||||
tempLen = j + 1;
|
||||
}
|
||||
while (result[currentChar] == '0') {
|
||||
currentChar++;
|
||||
}
|
||||
}
|
||||
boolean negNumber = (sign < 0);
|
||||
int exponent = resLengthInChars - currentChar - scale - 1;
|
||||
if (scale == 0) {
|
||||
if (negNumber) {
|
||||
result[--currentChar] = '-';
|
||||
}
|
||||
return new String(result, currentChar, resLengthInChars
|
||||
- currentChar);
|
||||
}
|
||||
if ((scale > 0) && (exponent >= -6)) {
|
||||
if (exponent >= 0) {
|
||||
// special case 1
|
||||
int insertPoint = currentChar + exponent;
|
||||
for (int j = resLengthInChars - 1; j >= insertPoint; j--) {
|
||||
result[j + 1] = result[j];
|
||||
}
|
||||
result[++insertPoint] = '.';
|
||||
if (negNumber) {
|
||||
result[--currentChar] = '-';
|
||||
}
|
||||
return new String(result, currentChar, resLengthInChars
|
||||
- currentChar + 1);
|
||||
}
|
||||
// special case 2
|
||||
for (int j = 2; j < -exponent + 1; j++) {
|
||||
result[--currentChar] = '0';
|
||||
}
|
||||
result[--currentChar] = '.';
|
||||
result[--currentChar] = '0';
|
||||
if (negNumber) {
|
||||
result[--currentChar] = '-';
|
||||
}
|
||||
return new String(result, currentChar, resLengthInChars
|
||||
- currentChar);
|
||||
}
|
||||
int startPoint = currentChar + 1;
|
||||
int endPoint = resLengthInChars;
|
||||
StringBuilder result1 = new StringBuilder(16 + endPoint - startPoint);
|
||||
if (negNumber) {
|
||||
result1.append('-');
|
||||
}
|
||||
if (endPoint - startPoint >= 1) {
|
||||
result1.append(result[currentChar]);
|
||||
result1.append('.');
|
||||
result1.append(result, currentChar + 1, resLengthInChars
|
||||
- currentChar - 1);
|
||||
} else {
|
||||
result1.append(result, currentChar, resLengthInChars
|
||||
- currentChar);
|
||||
}
|
||||
result1.append('E');
|
||||
if (exponent > 0) {
|
||||
result1.append('+');
|
||||
}
|
||||
result1.append(Integer.toString(exponent));
|
||||
return result1.toString();
|
||||
}
|
||||
|
||||
/* can process only 32-bit numbers */
|
||||
static String toDecimalScaledString(long value, int scale) {
|
||||
int resLengthInChars;
|
||||
int currentChar;
|
||||
char result[];
|
||||
boolean negNumber = value < 0;
|
||||
if(negNumber) {
|
||||
value = -value;
|
||||
}
|
||||
if (value == 0) {
|
||||
switch (scale) {
|
||||
case 0: return "0"; //$NON-NLS-1$
|
||||
case 1: return "0.0"; //$NON-NLS-1$
|
||||
case 2: return "0.00"; //$NON-NLS-1$
|
||||
case 3: return "0.000"; //$NON-NLS-1$
|
||||
case 4: return "0.0000"; //$NON-NLS-1$
|
||||
case 5: return "0.00000"; //$NON-NLS-1$
|
||||
case 6: return "0.000000"; //$NON-NLS-1$
|
||||
default:
|
||||
StringBuilder result1 = new StringBuilder();
|
||||
if (scale < 0) {
|
||||
result1.append("0E+"); //$NON-NLS-1$
|
||||
} else {
|
||||
result1.append("0E"); //$NON-NLS-1$
|
||||
}
|
||||
result1.append( (scale == Integer.MIN_VALUE) ? "2147483648" : Integer.toString(-scale)); //$NON-NLS-1$
|
||||
return result1.toString();
|
||||
}
|
||||
}
|
||||
// one 32-bit unsigned value may contains 10 decimal digits
|
||||
resLengthInChars = 18;
|
||||
// Explanation why +1+7:
|
||||
// +1 - one char for sign if needed.
|
||||
// +7 - For "special case 2" (see below) we have 7 free chars for
|
||||
// inserting necessary scaled digits.
|
||||
result = new char[resLengthInChars+1];
|
||||
// Allocated [resLengthInChars+1] characters.
|
||||
// a free latest character may be used for "special case 1" (see below)
|
||||
currentChar = resLengthInChars;
|
||||
long v = value;
|
||||
do {
|
||||
long prev = v;
|
||||
v /= 10;
|
||||
result[--currentChar] = (char) (0x0030 + (prev - v * 10));
|
||||
} while (v != 0);
|
||||
|
||||
long exponent = (long)resLengthInChars - (long)currentChar - scale - 1L;
|
||||
if (scale == 0) {
|
||||
if (negNumber) {
|
||||
result[--currentChar] = '-';
|
||||
}
|
||||
return new String(result, currentChar, resLengthInChars - currentChar);
|
||||
}
|
||||
if (scale > 0 && exponent >= -6) {
|
||||
if (exponent >= 0) {
|
||||
// special case 1
|
||||
int insertPoint = currentChar + (int) exponent ;
|
||||
for(int j=resLengthInChars-1; j>=insertPoint; j--) {
|
||||
result[j+1] = result[j];
|
||||
}
|
||||
result[++insertPoint]='.';
|
||||
if (negNumber) {
|
||||
result[--currentChar] = '-';
|
||||
}
|
||||
return new String(result, currentChar, resLengthInChars - currentChar + 1);
|
||||
}
|
||||
// special case 2
|
||||
for (int j = 2; j < -exponent + 1; j++) {
|
||||
result[--currentChar] = '0';
|
||||
}
|
||||
result[--currentChar] = '.';
|
||||
result[--currentChar] = '0';
|
||||
if (negNumber) {
|
||||
result[--currentChar] = '-';
|
||||
}
|
||||
return new String(result, currentChar, resLengthInChars - currentChar);
|
||||
}
|
||||
int startPoint = currentChar + 1;
|
||||
int endPoint = resLengthInChars;
|
||||
StringBuilder result1 = new StringBuilder(16+endPoint-startPoint);
|
||||
if (negNumber) {
|
||||
result1.append('-');
|
||||
}
|
||||
if (endPoint - startPoint >= 1) {
|
||||
result1.append(result[currentChar]);
|
||||
result1.append('.');
|
||||
result1.append(result,currentChar+1,resLengthInChars - currentChar-1);
|
||||
} else {
|
||||
result1.append(result,currentChar,resLengthInChars - currentChar);
|
||||
}
|
||||
result1.append('E');
|
||||
if (exponent > 0) {
|
||||
result1.append('+');
|
||||
}
|
||||
result1.append(Long.toString(exponent));
|
||||
return result1.toString();
|
||||
}
|
||||
|
||||
static long divideLongByBillion(long a) {
|
||||
long quot;
|
||||
long rem;
|
||||
|
||||
if (a >= 0) {
|
||||
long bLong = 1000000000L;
|
||||
quot = (a / bLong);
|
||||
rem = (a % bLong);
|
||||
} else {
|
||||
/*
|
||||
* Make the dividend positive shifting it right by 1 bit then get
|
||||
* the quotient an remainder and correct them properly
|
||||
*/
|
||||
long aPos = a >>> 1;
|
||||
long bPos = 1000000000L >>> 1;
|
||||
quot = aPos / bPos;
|
||||
rem = aPos % bPos;
|
||||
// double the remainder and add 1 if 'a' is odd
|
||||
rem = (rem << 1) + (a & 1);
|
||||
}
|
||||
return ((rem << 32) | (quot & 0xFFFFFFFFL));
|
||||
}
|
||||
|
||||
/** @see TBigInteger#doubleValue() */
|
||||
static double bigInteger2Double(TBigInteger val) {
|
||||
// val.bitLength() < 64
|
||||
if ((val.numberLength < 2)
|
||||
|| ((val.numberLength == 2) && (val.digits[1] > 0))) {
|
||||
return val.longValue();
|
||||
}
|
||||
// val.bitLength() >= 33 * 32 > 1024
|
||||
if (val.numberLength > 32) {
|
||||
return ((val.sign > 0) ? Double.POSITIVE_INFINITY
|
||||
: Double.NEGATIVE_INFINITY);
|
||||
}
|
||||
int bitLen = val.abs().bitLength();
|
||||
long exponent = bitLen - 1;
|
||||
int delta = bitLen - 54;
|
||||
// We need 54 top bits from this, the 53th bit is always 1 in lVal.
|
||||
long lVal = val.abs().shiftRight(delta).longValue();
|
||||
/*
|
||||
* Take 53 bits from lVal to mantissa. The least significant bit is
|
||||
* needed for rounding.
|
||||
*/
|
||||
long mantissa = lVal & 0x1FFFFFFFFFFFFFL;
|
||||
if (exponent == 1023) {
|
||||
if (mantissa == 0X1FFFFFFFFFFFFFL) {
|
||||
return ((val.sign > 0) ? Double.POSITIVE_INFINITY
|
||||
: Double.NEGATIVE_INFINITY);
|
||||
}
|
||||
if (mantissa == 0x1FFFFFFFFFFFFEL) {
|
||||
return ((val.sign > 0) ? Double.MAX_VALUE : -Double.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
// Round the mantissa
|
||||
if (((mantissa & 1) == 1)
|
||||
&& (((mantissa & 2) == 2) || TBitLevel.nonZeroDroppedBits(delta,
|
||||
val.digits))) {
|
||||
mantissa += 2;
|
||||
}
|
||||
mantissa >>= 1; // drop the rounding bit
|
||||
long resSign = (val.sign < 0) ? 0x8000000000000000L : 0;
|
||||
exponent = ((1023 + exponent) << 52) & 0x7FF0000000000000L;
|
||||
long result = resSign | exponent | mantissa;
|
||||
return Double.longBitsToDouble(result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,952 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
/**
|
||||
* Static library that provides all operations related with division and modular
|
||||
* arithmetic to {@link TBigInteger}. Some methods are provided in both mutable
|
||||
* and immutable way. There are several variants provided listed below:
|
||||
*
|
||||
* <ul type="circle">
|
||||
* <li><b>Division</b>
|
||||
* <ul type="circle">
|
||||
* <li>{@link TBigInteger} division and remainder by {@link TBigInteger}.</li>
|
||||
* <li>{@link TBigInteger} division and remainder by {@code int}.</li>
|
||||
* <li><i>gcd</i> between {@link TBigInteger} numbers.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li><b>Modular arithmetic </b>
|
||||
* <ul type="circle">
|
||||
* <li>Modular exponentiation between {@link TBigInteger} numbers.</li>
|
||||
* <li>Modular inverse of a {@link TBigInteger} numbers.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
class TDivision {
|
||||
|
||||
/**
|
||||
* Divides the array 'a' by the array 'b' and gets the quotient and the
|
||||
* remainder. Implements the Knuth's division algorithm. See D. Knuth, The
|
||||
* Art of Computer Programming, vol. 2. Steps D1-D8 correspond the steps in
|
||||
* the algorithm description.
|
||||
*
|
||||
* @param quot
|
||||
* the quotient
|
||||
* @param quotLength
|
||||
* the quotient's length
|
||||
* @param a
|
||||
* the dividend
|
||||
* @param aLength
|
||||
* the dividend's length
|
||||
* @param b
|
||||
* the divisor
|
||||
* @param bLength
|
||||
* the divisor's length
|
||||
* @return the remainder
|
||||
*/
|
||||
static int[] divide(int quot[], int quotLength, int a[], int aLength, int b[], int bLength) {
|
||||
|
||||
int normA[] = new int[aLength + 1]; // the normalized dividend
|
||||
// an extra byte is needed for correct shift
|
||||
int normB[] = new int[bLength + 1]; // the normalized divisor;
|
||||
int normBLength = bLength;
|
||||
/*
|
||||
* Step D1: normalize a and b and put the results to a1 and b1 the
|
||||
* normalized divisor's first digit must be >= 2^31
|
||||
*/
|
||||
int divisorShift = Integer.numberOfLeadingZeros(b[bLength - 1]);
|
||||
if (divisorShift != 0) {
|
||||
TBitLevel.shiftLeft(normB, b, 0, divisorShift);
|
||||
TBitLevel.shiftLeft(normA, a, 0, divisorShift);
|
||||
} else {
|
||||
System.arraycopy(a, 0, normA, 0, aLength);
|
||||
System.arraycopy(b, 0, normB, 0, bLength);
|
||||
}
|
||||
int firstDivisorDigit = normB[normBLength - 1];
|
||||
// Step D2: set the quotient index
|
||||
int i = quotLength - 1;
|
||||
int j = aLength;
|
||||
|
||||
while (i >= 0) {
|
||||
// Step D3: calculate a guess digit guessDigit
|
||||
int guessDigit = 0;
|
||||
if (normA[j] == firstDivisorDigit) {
|
||||
// set guessDigit to the largest unsigned int value
|
||||
guessDigit = -1;
|
||||
} else {
|
||||
long product = (((normA[j] & 0xffffffffL) << 32) + (normA[j - 1] & 0xffffffffL));
|
||||
long res = TDivision.divideLongByInt(product, firstDivisorDigit);
|
||||
guessDigit = (int) res; // the quotient of divideLongByInt
|
||||
int rem = (int) (res >> 32); // the remainder of
|
||||
// divideLongByInt
|
||||
// decrease guessDigit by 1 while leftHand > rightHand
|
||||
if (guessDigit != 0) {
|
||||
long leftHand = 0;
|
||||
long rightHand = 0;
|
||||
boolean rOverflowed = false;
|
||||
guessDigit++; // to have the proper value in the loop
|
||||
// below
|
||||
do {
|
||||
guessDigit--;
|
||||
if (rOverflowed) {
|
||||
break;
|
||||
}
|
||||
// leftHand always fits in an unsigned long
|
||||
leftHand = (guessDigit & 0xffffffffL) * (normB[normBLength - 2] & 0xffffffffL);
|
||||
/*
|
||||
* rightHand can overflow; in this case the loop
|
||||
* condition will be true in the next step of the loop
|
||||
*/
|
||||
rightHand = ((long) rem << 32) + (normA[j - 2] & 0xffffffffL);
|
||||
long longR = (rem & 0xffffffffL) + (firstDivisorDigit & 0xffffffffL);
|
||||
/*
|
||||
* checks that longR does not fit in an unsigned int;
|
||||
* this ensures that rightHand will overflow unsigned
|
||||
* long in the next step
|
||||
*/
|
||||
if (Integer.numberOfLeadingZeros((int) (longR >>> 32)) < 32) {
|
||||
rOverflowed = true;
|
||||
} else {
|
||||
rem = (int) longR;
|
||||
}
|
||||
} while (((leftHand ^ 0x8000000000000000L) > (rightHand ^ 0x8000000000000000L)));
|
||||
}
|
||||
}
|
||||
// Step D4: multiply normB by guessDigit and subtract the production
|
||||
// from normA.
|
||||
if (guessDigit != 0) {
|
||||
int borrow = TDivision.multiplyAndSubtract(normA, j - normBLength, normB, normBLength, guessDigit);
|
||||
// Step D5: check the borrow
|
||||
if (borrow != 0) {
|
||||
// Step D6: compensating addition
|
||||
guessDigit--;
|
||||
long carry = 0;
|
||||
for (int k = 0; k < normBLength; k++) {
|
||||
carry += (normA[j - normBLength + k] & 0xffffffffL) + (normB[k] & 0xffffffffL);
|
||||
normA[j - normBLength + k] = (int) carry;
|
||||
carry >>>= 32;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (quot != null) {
|
||||
quot[i] = guessDigit;
|
||||
}
|
||||
// Step D7
|
||||
j--;
|
||||
i--;
|
||||
}
|
||||
/*
|
||||
* Step D8: we got the remainder in normA. Denormalize it id needed
|
||||
*/
|
||||
if (divisorShift != 0) {
|
||||
// reuse normB
|
||||
TBitLevel.shiftRight(normB, normBLength, normA, 0, divisorShift);
|
||||
return normB;
|
||||
}
|
||||
System.arraycopy(normA, 0, normB, 0, bLength);
|
||||
return normA;
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides an array by an integer value. Implements the Knuth's division
|
||||
* algorithm. See D. Knuth, The Art of Computer Programming, vol. 2.
|
||||
*
|
||||
* @param dest
|
||||
* the quotient
|
||||
* @param src
|
||||
* the dividend
|
||||
* @param srcLength
|
||||
* the length of the dividend
|
||||
* @param divisor
|
||||
* the divisor
|
||||
* @return remainder
|
||||
*/
|
||||
static int divideArrayByInt(int dest[], int src[], final int srcLength, final int divisor) {
|
||||
|
||||
long rem = 0;
|
||||
long bLong = divisor & 0xffffffffL;
|
||||
|
||||
for (int i = srcLength - 1; i >= 0; i--) {
|
||||
long temp = (rem << 32) | (src[i] & 0xffffffffL);
|
||||
long quot;
|
||||
if (temp >= 0) {
|
||||
quot = (temp / bLong);
|
||||
rem = (temp % bLong);
|
||||
} else {
|
||||
/*
|
||||
* make the dividend positive shifting it right by 1 bit then
|
||||
* get the quotient an remainder and correct them properly
|
||||
*/
|
||||
long aPos = temp >>> 1;
|
||||
long bPos = divisor >>> 1;
|
||||
quot = aPos / bPos;
|
||||
rem = aPos % bPos;
|
||||
// double the remainder and add 1 if a is odd
|
||||
rem = (rem << 1) + (temp & 1);
|
||||
if ((divisor & 1) != 0) {
|
||||
// the divisor is odd
|
||||
if (quot <= rem) {
|
||||
rem -= quot;
|
||||
} else {
|
||||
if (quot - rem <= bLong) {
|
||||
rem += bLong - quot;
|
||||
quot -= 1;
|
||||
} else {
|
||||
rem += (bLong << 1) - quot;
|
||||
quot -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dest[i] = (int) (quot & 0xffffffffL);
|
||||
}
|
||||
return (int) rem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides an array by an integer value. Implements the Knuth's division
|
||||
* algorithm. See D. Knuth, The Art of Computer Programming, vol. 2.
|
||||
*
|
||||
* @param src
|
||||
* the dividend
|
||||
* @param srcLength
|
||||
* the length of the dividend
|
||||
* @param divisor
|
||||
* the divisor
|
||||
* @return remainder
|
||||
*/
|
||||
static int remainderArrayByInt(int src[], final int srcLength, final int divisor) {
|
||||
|
||||
long result = 0;
|
||||
|
||||
for (int i = srcLength - 1; i >= 0; i--) {
|
||||
long temp = (result << 32) + (src[i] & 0xffffffffL);
|
||||
long res = divideLongByInt(temp, divisor);
|
||||
result = (int) (res >> 32);
|
||||
}
|
||||
return (int) result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides a <code>BigInteger</code> by a signed <code>int</code> and
|
||||
* returns the remainder.
|
||||
*
|
||||
* @param dividend
|
||||
* the BigInteger to be divided. Must be non-negative.
|
||||
* @param divisor
|
||||
* a signed int
|
||||
* @return divide % divisor
|
||||
*/
|
||||
static int remainder(TBigInteger dividend, int divisor) {
|
||||
return remainderArrayByInt(dividend.digits, dividend.numberLength, divisor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides an unsigned long a by an unsigned int b. It is supposed that the
|
||||
* most significant bit of b is set to 1, i.e. b < 0
|
||||
*
|
||||
* @param a
|
||||
* the dividend
|
||||
* @param b
|
||||
* the divisor
|
||||
* @return the long value containing the unsigned integer remainder in the
|
||||
* left half and the unsigned integer quotient in the right half
|
||||
*/
|
||||
static long divideLongByInt(long a, int b) {
|
||||
long quot;
|
||||
long rem;
|
||||
long bLong = b & 0xffffffffL;
|
||||
|
||||
if (a >= 0) {
|
||||
quot = (a / bLong);
|
||||
rem = (a % bLong);
|
||||
} else {
|
||||
/*
|
||||
* Make the dividend positive shifting it right by 1 bit then get
|
||||
* the quotient an remainder and correct them properly
|
||||
*/
|
||||
long aPos = a >>> 1;
|
||||
long bPos = b >>> 1;
|
||||
quot = aPos / bPos;
|
||||
rem = aPos % bPos;
|
||||
// double the remainder and add 1 if a is odd
|
||||
rem = (rem << 1) + (a & 1);
|
||||
if ((b & 1) != 0) { // the divisor is odd
|
||||
if (quot <= rem) {
|
||||
rem -= quot;
|
||||
} else {
|
||||
if (quot - rem <= bLong) {
|
||||
rem += bLong - quot;
|
||||
quot -= 1;
|
||||
} else {
|
||||
rem += (bLong << 1) - quot;
|
||||
quot -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (rem << 32) | (quot & 0xffffffffL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the quotient and the remainder after a division by an
|
||||
* {@code int} number.
|
||||
*
|
||||
* @return an array of the form {@code [quotient, remainder]}.
|
||||
*/
|
||||
static TBigInteger[] divideAndRemainderByInteger(TBigInteger val, int divisor, int divisorSign) {
|
||||
// res[0] is a quotient and res[1] is a remainder:
|
||||
int[] valDigits = val.digits;
|
||||
int valLen = val.numberLength;
|
||||
int valSign = val.sign;
|
||||
if (valLen == 1) {
|
||||
long a = (valDigits[0] & 0xffffffffL);
|
||||
long b = (divisor & 0xffffffffL);
|
||||
long quo = a / b;
|
||||
long rem = a % b;
|
||||
if (valSign != divisorSign) {
|
||||
quo = -quo;
|
||||
}
|
||||
if (valSign < 0) {
|
||||
rem = -rem;
|
||||
}
|
||||
return new TBigInteger[] { TBigInteger.valueOf(quo), TBigInteger.valueOf(rem) };
|
||||
}
|
||||
int quotientLength = valLen;
|
||||
int quotientSign = ((valSign == divisorSign) ? 1 : -1);
|
||||
int quotientDigits[] = new int[quotientLength];
|
||||
int remainderDigits[];
|
||||
remainderDigits = new int[] { TDivision.divideArrayByInt(quotientDigits, valDigits, valLen, divisor) };
|
||||
TBigInteger result0 = new TBigInteger(quotientSign, quotientLength, quotientDigits);
|
||||
TBigInteger result1 = new TBigInteger(valSign, 1, remainderDigits);
|
||||
result0.cutOffLeadingZeroes();
|
||||
result1.cutOffLeadingZeroes();
|
||||
return new TBigInteger[] { result0, result1 };
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies an array by int and subtracts it from a subarray of another
|
||||
* array.
|
||||
*
|
||||
* @param a
|
||||
* the array to subtract from
|
||||
* @param start
|
||||
* the start element of the subarray of a
|
||||
* @param b
|
||||
* the array to be multiplied and subtracted
|
||||
* @param bLen
|
||||
* the length of b
|
||||
* @param c
|
||||
* the multiplier of b
|
||||
* @return the carry element of subtraction
|
||||
*/
|
||||
static int multiplyAndSubtract(int a[], int start, int b[], int bLen, int c) {
|
||||
long carry0 = 0;
|
||||
long carry1 = 0;
|
||||
|
||||
for (int i = 0; i < bLen; i++) {
|
||||
carry0 = TMultiplication.unsignedMultAddAdd(b[i], c, (int) carry0, 0);
|
||||
carry1 = (a[start + i] & 0xffffffffL) - (carry0 & 0xffffffffL) + carry1;
|
||||
a[start + i] = (int) carry1;
|
||||
carry1 >>= 32; // -1 or 0
|
||||
carry0 >>>= 32;
|
||||
}
|
||||
|
||||
carry1 = (a[start + bLen] & 0xffffffffL) - carry0 + carry1;
|
||||
a[start + bLen] = (int) carry1;
|
||||
return (int) (carry1 >> 32); // -1 or 0
|
||||
}
|
||||
|
||||
/**
|
||||
* @param m
|
||||
* a positive modulus Return the greatest common divisor of op1
|
||||
* and op2,
|
||||
*
|
||||
* @param op1
|
||||
* must be greater than zero
|
||||
* @param op2
|
||||
* must be greater than zero
|
||||
* @see TBigInteger#gcd(TBigInteger)
|
||||
* @return {@code GCD(op1, op2)}
|
||||
*/
|
||||
static TBigInteger gcdBinary(TBigInteger op1, TBigInteger op2) {
|
||||
// PRE: (op1 > 0) and (op2 > 0)
|
||||
|
||||
/*
|
||||
* Divide both number the maximal possible times by 2 without rounding
|
||||
* gcd(2*a, 2*b) = 2 * gcd(a,b)
|
||||
*/
|
||||
int lsb1 = op1.getLowestSetBit();
|
||||
int lsb2 = op2.getLowestSetBit();
|
||||
int pow2Count = Math.min(lsb1, lsb2);
|
||||
|
||||
TBitLevel.inplaceShiftRight(op1, lsb1);
|
||||
TBitLevel.inplaceShiftRight(op2, lsb2);
|
||||
|
||||
TBigInteger swap;
|
||||
// I want op2 > op1
|
||||
if (op1.compareTo(op2) == TBigInteger.GREATER) {
|
||||
swap = op1;
|
||||
op1 = op2;
|
||||
op2 = swap;
|
||||
}
|
||||
|
||||
do { // INV: op2 >= op1 && both are odd unless op1 = 0
|
||||
|
||||
// Optimization for small operands
|
||||
// (op2.bitLength() < 64) implies by INV (op1.bitLength() < 64)
|
||||
if ((op2.numberLength == 1) || ((op2.numberLength == 2) && (op2.digits[1] > 0))) {
|
||||
op2 = TBigInteger.valueOf(TDivision.gcdBinary(op1.longValue(), op2.longValue()));
|
||||
break;
|
||||
}
|
||||
|
||||
// Implements one step of the Euclidean algorithm
|
||||
// To reduce one operand if it's much smaller than the other one
|
||||
if (op2.numberLength > op1.numberLength * 1.2) {
|
||||
op2 = op2.remainder(op1);
|
||||
if (op2.signum() != 0) {
|
||||
TBitLevel.inplaceShiftRight(op2, op2.getLowestSetBit());
|
||||
}
|
||||
} else {
|
||||
|
||||
// Use Knuth's algorithm of successive subtract and shifting
|
||||
do {
|
||||
TElementary.inplaceSubtract(op2, op1); // both are odd
|
||||
TBitLevel.inplaceShiftRight(op2, op2.getLowestSetBit());
|
||||
} while (op2.compareTo(op1) >= TBigInteger.EQUALS);
|
||||
}
|
||||
// now op1 >= op2
|
||||
swap = op2;
|
||||
op2 = op1;
|
||||
op1 = swap;
|
||||
} while (op1.sign != 0);
|
||||
return op2.shiftLeft(pow2Count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the same as {@link #gcdBinary(TBigInteger, TBigInteger)}, but
|
||||
* with numbers of 63 bits, represented in positives values of {@code long}
|
||||
* type.
|
||||
*
|
||||
* @param op1
|
||||
* a positive number
|
||||
* @param op2
|
||||
* a positive number
|
||||
* @see #gcdBinary(TBigInteger, TBigInteger)
|
||||
* @return <code>GCD(op1, op2)</code>
|
||||
*/
|
||||
static long gcdBinary(long op1, long op2) {
|
||||
// PRE: (op1 > 0) and (op2 > 0)
|
||||
int lsb1 = Long.numberOfTrailingZeros(op1);
|
||||
int lsb2 = Long.numberOfTrailingZeros(op2);
|
||||
int pow2Count = Math.min(lsb1, lsb2);
|
||||
|
||||
if (lsb1 != 0) {
|
||||
op1 >>>= lsb1;
|
||||
}
|
||||
if (lsb2 != 0) {
|
||||
op2 >>>= lsb2;
|
||||
}
|
||||
do {
|
||||
if (op1 >= op2) {
|
||||
op1 -= op2;
|
||||
op1 >>>= Long.numberOfTrailingZeros(op1);
|
||||
} else {
|
||||
op2 -= op1;
|
||||
op2 >>>= Long.numberOfTrailingZeros(op2);
|
||||
}
|
||||
} while (op1 != 0);
|
||||
return (op2 << pow2Count);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a.modInverse(p) Based on: Savas, E; Koc, C "The Montgomery
|
||||
* Modular Inverse - Revised"
|
||||
*/
|
||||
static TBigInteger modInverseMontgomery(TBigInteger a, TBigInteger p) {
|
||||
|
||||
if (a.sign == 0) {
|
||||
// ZERO hasn't inverse
|
||||
throw new ArithmeticException("BigInteger not invertible");
|
||||
}
|
||||
|
||||
if (!p.testBit(0)) {
|
||||
// montgomery inverse require even modulo
|
||||
return modInverseHars(a, p);
|
||||
}
|
||||
|
||||
int m = p.numberLength * 32;
|
||||
// PRE: a \in [1, p - 1]
|
||||
TBigInteger u, v, r, s;
|
||||
u = p.copy(); // make copy to use inplace method
|
||||
v = a.copy();
|
||||
int max = Math.max(v.numberLength, u.numberLength);
|
||||
r = new TBigInteger(1, 1, new int[max + 1]);
|
||||
s = new TBigInteger(1, 1, new int[max + 1]);
|
||||
s.digits[0] = 1;
|
||||
// s == 1 && v == 0
|
||||
|
||||
int k = 0;
|
||||
|
||||
int lsbu = u.getLowestSetBit();
|
||||
int lsbv = v.getLowestSetBit();
|
||||
int toShift;
|
||||
|
||||
if (lsbu > lsbv) {
|
||||
TBitLevel.inplaceShiftRight(u, lsbu);
|
||||
TBitLevel.inplaceShiftRight(v, lsbv);
|
||||
TBitLevel.inplaceShiftLeft(r, lsbv);
|
||||
k += lsbu - lsbv;
|
||||
} else {
|
||||
TBitLevel.inplaceShiftRight(u, lsbu);
|
||||
TBitLevel.inplaceShiftRight(v, lsbv);
|
||||
TBitLevel.inplaceShiftLeft(s, lsbu);
|
||||
k += lsbv - lsbu;
|
||||
}
|
||||
|
||||
r.sign = 1;
|
||||
while (v.signum() > 0) {
|
||||
// INV v >= 0, u >= 0, v odd, u odd (except last iteration when v is
|
||||
// even (0))
|
||||
|
||||
while (u.compareTo(v) > TBigInteger.EQUALS) {
|
||||
TElementary.inplaceSubtract(u, v);
|
||||
toShift = u.getLowestSetBit();
|
||||
TBitLevel.inplaceShiftRight(u, toShift);
|
||||
TElementary.inplaceAdd(r, s);
|
||||
TBitLevel.inplaceShiftLeft(s, toShift);
|
||||
k += toShift;
|
||||
}
|
||||
|
||||
while (u.compareTo(v) <= TBigInteger.EQUALS) {
|
||||
TElementary.inplaceSubtract(v, u);
|
||||
if (v.signum() == 0)
|
||||
break;
|
||||
toShift = v.getLowestSetBit();
|
||||
TBitLevel.inplaceShiftRight(v, toShift);
|
||||
TElementary.inplaceAdd(s, r);
|
||||
TBitLevel.inplaceShiftLeft(r, toShift);
|
||||
k += toShift;
|
||||
}
|
||||
}
|
||||
if (!u.isOne()) {
|
||||
throw new ArithmeticException("BigInteger not invertible.");
|
||||
}
|
||||
if (r.compareTo(p) >= TBigInteger.EQUALS) {
|
||||
TElementary.inplaceSubtract(r, p);
|
||||
}
|
||||
|
||||
r = p.subtract(r);
|
||||
|
||||
// Have pair: ((BigInteger)r, (Integer)k) where r == a^(-1) * 2^k mod
|
||||
// (module)
|
||||
int n1 = calcN(p);
|
||||
if (k > m) {
|
||||
r = monPro(r, TBigInteger.ONE, p, n1);
|
||||
k = k - m;
|
||||
}
|
||||
|
||||
r = monPro(r, TBigInteger.getPowerOfTwo(m - k), p, n1);
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the first digit of the inverse
|
||||
*/
|
||||
private static int calcN(TBigInteger a) {
|
||||
long m0 = a.digits[0] & 0xFFFFFFFFL;
|
||||
long n2 = 1L; // this is a'[0]
|
||||
long powerOfTwo = 2L;
|
||||
do {
|
||||
if (((m0 * n2) & powerOfTwo) != 0) {
|
||||
n2 |= powerOfTwo;
|
||||
}
|
||||
powerOfTwo <<= 1;
|
||||
} while (powerOfTwo < 0x100000000L);
|
||||
n2 = -n2;
|
||||
return (int) (n2 & 0xFFFFFFFFL);
|
||||
}
|
||||
|
||||
static TBigInteger squareAndMultiply(TBigInteger x2, TBigInteger a2, TBigInteger exponent, TBigInteger modulus,
|
||||
int n2) {
|
||||
TBigInteger res = x2;
|
||||
for (int i = exponent.bitLength() - 1; i >= 0; i--) {
|
||||
res = monPro(res, res, modulus, n2);
|
||||
if (TBitLevel.testBit(exponent, i)) {
|
||||
res = monPro(res, a2, modulus, n2);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the "Shifting Euclidean modular inverse algorithm". "Laszlo
|
||||
* Hars - Modular Inverse Algorithms Without Multiplications for
|
||||
* Cryptographic Applications"
|
||||
*
|
||||
* @see TBigInteger#modInverse(TBigInteger)
|
||||
* @param a
|
||||
* a positive number
|
||||
* @param m
|
||||
* a positive modulus
|
||||
*/
|
||||
static TBigInteger modInverseHars(TBigInteger a, TBigInteger m) {
|
||||
// PRE: (a > 0) and (m > 0)
|
||||
TBigInteger u, v, r, s, temp;
|
||||
// u = MAX(a,m), v = MIN(a,m)
|
||||
if (a.compareTo(m) == TBigInteger.LESS) {
|
||||
u = m;
|
||||
v = a;
|
||||
r = TBigInteger.ZERO;
|
||||
s = TBigInteger.ONE;
|
||||
} else {
|
||||
v = m;
|
||||
u = a;
|
||||
s = TBigInteger.ZERO;
|
||||
r = TBigInteger.ONE;
|
||||
}
|
||||
int uLen = u.bitLength();
|
||||
int vLen = v.bitLength();
|
||||
int f = uLen - vLen;
|
||||
|
||||
while (vLen > 1) {
|
||||
if (u.sign == v.sign) {
|
||||
u = u.subtract(v.shiftLeft(f));
|
||||
r = r.subtract(s.shiftLeft(f));
|
||||
} else {
|
||||
u = u.add(v.shiftLeft(f));
|
||||
r = r.add(s.shiftLeft(f));
|
||||
}
|
||||
uLen = u.abs().bitLength();
|
||||
vLen = v.abs().bitLength();
|
||||
f = uLen - vLen;
|
||||
if (f < 0) {
|
||||
// SWAP(u,v)
|
||||
temp = u;
|
||||
u = v;
|
||||
v = temp;
|
||||
// SWAP(r,s)
|
||||
temp = r;
|
||||
r = s;
|
||||
s = temp;
|
||||
|
||||
f = -f;
|
||||
vLen = uLen;
|
||||
}
|
||||
}
|
||||
if (v.sign == 0) {
|
||||
return TBigInteger.ZERO;
|
||||
}
|
||||
if (v.sign < 0) {
|
||||
s = s.negate();
|
||||
}
|
||||
if (s.compareTo(m) == TBigInteger.GREATER) {
|
||||
return s.subtract(m);
|
||||
}
|
||||
if (s.sign < 0) {
|
||||
return s.add(m);
|
||||
}
|
||||
return s; // a^(-1) mod m
|
||||
}
|
||||
|
||||
/*
|
||||
* Implements the Montgomery modular exponentiation based in <i>The sliding
|
||||
* windows algorithm and the MongomeryReduction</i>.
|
||||
*
|
||||
* @ar.org.fitc.ref
|
||||
* "A. Menezes,P. van Oorschot, S. Vanstone - Handbook of Applied Cryptography"
|
||||
* ;
|
||||
*
|
||||
* @see #oddModPow(BigInteger, BigInteger, BigInteger)
|
||||
*/
|
||||
static TBigInteger slidingWindow(TBigInteger x2, TBigInteger a2, TBigInteger exponent, TBigInteger modulus, int n2) {
|
||||
// fill odd low pows of a2
|
||||
TBigInteger pows[] = new TBigInteger[8];
|
||||
TBigInteger res = x2;
|
||||
int lowexp;
|
||||
TBigInteger x3;
|
||||
int acc3;
|
||||
pows[0] = a2;
|
||||
|
||||
x3 = monPro(a2, a2, modulus, n2);
|
||||
for (int i = 1; i <= 7; i++) {
|
||||
pows[i] = monPro(pows[i - 1], x3, modulus, n2);
|
||||
}
|
||||
|
||||
for (int i = exponent.bitLength() - 1; i >= 0; i--) {
|
||||
if (TBitLevel.testBit(exponent, i)) {
|
||||
lowexp = 1;
|
||||
acc3 = i;
|
||||
|
||||
for (int j = Math.max(i - 3, 0); j <= i - 1; j++) {
|
||||
if (TBitLevel.testBit(exponent, j)) {
|
||||
if (j < acc3) {
|
||||
acc3 = j;
|
||||
lowexp = (lowexp << (i - j)) ^ 1;
|
||||
} else {
|
||||
lowexp = lowexp ^ (1 << (j - acc3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = acc3; j <= i; j++) {
|
||||
res = monPro(res, res, modulus, n2);
|
||||
}
|
||||
res = monPro(pows[(lowexp - 1) >> 1], res, modulus, n2);
|
||||
i = acc3;
|
||||
} else {
|
||||
res = monPro(res, res, modulus, n2);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs modular exponentiation using the Montgomery Reduction. It
|
||||
* requires that all parameters be positive and the modulus be odd. >
|
||||
*
|
||||
* @see TBigInteger#modPow(TBigInteger, TBigInteger)
|
||||
* @see #monPro(TBigInteger, TBigInteger, TBigInteger, int)
|
||||
* @see #slidingWindow(TBigInteger, TBigInteger, TBigInteger, TBigInteger,
|
||||
* int)
|
||||
* @see #squareAndMultiply(TBigInteger, TBigInteger, TBigInteger,
|
||||
* TBigInteger, int)
|
||||
*/
|
||||
static TBigInteger oddModPow(TBigInteger base, TBigInteger exponent, TBigInteger modulus) {
|
||||
// PRE: (base > 0), (exponent > 0), (modulus > 0) and (odd modulus)
|
||||
int k = (modulus.numberLength << 5); // r = 2^k
|
||||
// n-residue of base [base * r (mod modulus)]
|
||||
TBigInteger a2 = base.shiftLeft(k).mod(modulus);
|
||||
// n-residue of base [1 * r (mod modulus)]
|
||||
TBigInteger x2 = TBigInteger.getPowerOfTwo(k).mod(modulus);
|
||||
TBigInteger res;
|
||||
// Compute (modulus[0]^(-1)) (mod 2^32) for odd modulus
|
||||
|
||||
int n2 = calcN(modulus);
|
||||
if (modulus.numberLength == 1) {
|
||||
res = squareAndMultiply(x2, a2, exponent, modulus, n2);
|
||||
} else {
|
||||
res = slidingWindow(x2, a2, exponent, modulus, n2);
|
||||
}
|
||||
|
||||
return monPro(res, TBigInteger.ONE, modulus, n2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs modular exponentiation using the Montgomery Reduction. It
|
||||
* requires that all parameters be positive and the modulus be even. Based
|
||||
* <i>The square and multiply algorithm and the Montgomery Reduction C. K.
|
||||
* Koc - Montgomery Reduction with Even Modulus</i>. The square and multiply
|
||||
* algorithm and the Montgomery Reduction.
|
||||
*
|
||||
* @ar.org.fitc.ref "C. K. Koc - Montgomery Reduction with Even Modulus"
|
||||
* @see TBigInteger#modPow(TBigInteger, TBigInteger)
|
||||
*/
|
||||
static TBigInteger evenModPow(TBigInteger base, TBigInteger exponent, TBigInteger modulus) {
|
||||
// PRE: (base > 0), (exponent > 0), (modulus > 0) and (modulus even)
|
||||
// STEP 1: Obtain the factorization 'modulus'= q * 2^j.
|
||||
int j = modulus.getLowestSetBit();
|
||||
TBigInteger q = modulus.shiftRight(j);
|
||||
|
||||
// STEP 2: Compute x1 := base^exponent (mod q).
|
||||
TBigInteger x1 = oddModPow(base, exponent, q);
|
||||
|
||||
// STEP 3: Compute x2 := base^exponent (mod 2^j).
|
||||
TBigInteger x2 = pow2ModPow(base, exponent, j);
|
||||
|
||||
// STEP 4: Compute q^(-1) (mod 2^j) and y := (x2-x1) * q^(-1) (mod 2^j)
|
||||
TBigInteger qInv = modPow2Inverse(q, j);
|
||||
TBigInteger y = (x2.subtract(x1)).multiply(qInv);
|
||||
inplaceModPow2(y, j);
|
||||
if (y.sign < 0) {
|
||||
y = y.add(TBigInteger.getPowerOfTwo(j));
|
||||
}
|
||||
// STEP 5: Compute and return: x1 + q * y
|
||||
return x1.add(q.multiply(y));
|
||||
}
|
||||
|
||||
/**
|
||||
* It requires that all parameters be positive.
|
||||
*
|
||||
* @return {@code base<sup>exponent</sup> mod (2<sup>j</sup>)}.
|
||||
* @see TBigInteger#modPow(TBigInteger, TBigInteger)
|
||||
*/
|
||||
static TBigInteger pow2ModPow(TBigInteger base, TBigInteger exponent, int j) {
|
||||
// PRE: (base > 0), (exponent > 0) and (j > 0)
|
||||
TBigInteger res = TBigInteger.ONE;
|
||||
TBigInteger e = exponent.copy();
|
||||
TBigInteger baseMod2toN = base.copy();
|
||||
TBigInteger res2;
|
||||
/*
|
||||
* If 'base' is odd then it's coprime with 2^j and phi(2^j) = 2^(j-1);
|
||||
* so we can reduce reduce the exponent (mod 2^(j-1)).
|
||||
*/
|
||||
if (base.testBit(0)) {
|
||||
inplaceModPow2(e, j - 1);
|
||||
}
|
||||
inplaceModPow2(baseMod2toN, j);
|
||||
|
||||
for (int i = e.bitLength() - 1; i >= 0; i--) {
|
||||
res2 = res.copy();
|
||||
inplaceModPow2(res2, j);
|
||||
res = res.multiply(res2);
|
||||
if (TBitLevel.testBit(e, i)) {
|
||||
res = res.multiply(baseMod2toN);
|
||||
inplaceModPow2(res, j);
|
||||
}
|
||||
}
|
||||
inplaceModPow2(res, j);
|
||||
return res;
|
||||
}
|
||||
|
||||
private static void monReduction(int[] res, TBigInteger modulus, int n2) {
|
||||
|
||||
/* res + m*modulus_digits */
|
||||
int[] modulus_digits = modulus.digits;
|
||||
int modulusLen = modulus.numberLength;
|
||||
long outerCarry = 0;
|
||||
|
||||
for (int i = 0; i < modulusLen; i++) {
|
||||
long innnerCarry = 0;
|
||||
int m = (int) TMultiplication.unsignedMultAddAdd(res[i], n2, 0, 0);
|
||||
for (int j = 0; j < modulusLen; j++) {
|
||||
innnerCarry = TMultiplication.unsignedMultAddAdd(m, modulus_digits[j], res[i + j], (int) innnerCarry);
|
||||
res[i + j] = (int) innnerCarry;
|
||||
innnerCarry >>>= 32;
|
||||
}
|
||||
|
||||
outerCarry += (res[i + modulusLen] & 0xFFFFFFFFL) + innnerCarry;
|
||||
res[i + modulusLen] = (int) outerCarry;
|
||||
outerCarry >>>= 32;
|
||||
}
|
||||
|
||||
res[modulusLen << 1] = (int) outerCarry;
|
||||
|
||||
/* res / r */
|
||||
for (int j = 0; j < modulusLen + 1; j++) {
|
||||
res[j] = res[j + modulusLen];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the Montgomery Product of two integers represented by
|
||||
* {@code int} arrays. The arrays are supposed in <i>little endian</i>
|
||||
* notation.
|
||||
*
|
||||
* @param a
|
||||
* The first factor of the product.
|
||||
* @param b
|
||||
* The second factor of the product.
|
||||
* @param modulus
|
||||
* The modulus of the operations. Z<sub>modulus</sub>.
|
||||
* @param n2
|
||||
* The digit modulus'[0].
|
||||
* @ar.org.fitc.ref "C. K. Koc - Analyzing and Comparing Montgomery
|
||||
* Multiplication Algorithms"
|
||||
* @see #modPowOdd(TBigInteger, TBigInteger, TBigInteger)
|
||||
*/
|
||||
static TBigInteger monPro(TBigInteger a, TBigInteger b, TBigInteger modulus, int n2) {
|
||||
int modulusLen = modulus.numberLength;
|
||||
int res[] = new int[(modulusLen << 1) + 1];
|
||||
TMultiplication.multArraysPAP(a.digits, Math.min(modulusLen, a.numberLength), b.digits,
|
||||
Math.min(modulusLen, b.numberLength), res);
|
||||
monReduction(res, modulus, n2);
|
||||
return finalSubtraction(res, modulus);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the final reduction of the Montgomery algorithm.
|
||||
*
|
||||
* @see monPro(BigInteger, BigInteger, BigInteger, long)
|
||||
* @see monSquare(BigInteger, BigInteger, long)
|
||||
*/
|
||||
static TBigInteger finalSubtraction(int res[], TBigInteger modulus) {
|
||||
|
||||
// skipping leading zeros
|
||||
int modulusLen = modulus.numberLength;
|
||||
boolean doSub = res[modulusLen] != 0;
|
||||
if (!doSub) {
|
||||
int modulusDigits[] = modulus.digits;
|
||||
doSub = true;
|
||||
for (int i = modulusLen - 1; i >= 0; i--) {
|
||||
if (res[i] != modulusDigits[i]) {
|
||||
doSub = (res[i] != 0) && ((res[i] & 0xFFFFFFFFL) > (modulusDigits[i] & 0xFFFFFFFFL));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TBigInteger result = new TBigInteger(1, modulusLen + 1, res);
|
||||
|
||||
// if (res >= modulusDigits) compute (res - modulusDigits)
|
||||
if (doSub) {
|
||||
TElementary.inplaceSubtract(result, modulus);
|
||||
}
|
||||
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param x
|
||||
* an odd positive number.
|
||||
* @param n
|
||||
* the exponent by which 2 is raised.
|
||||
* @return {@code x<sup>-1</sup> (mod 2<sup>n</sup>)}.
|
||||
*/
|
||||
static TBigInteger modPow2Inverse(TBigInteger x, int n) {
|
||||
// PRE: (x > 0), (x is odd), and (n > 0)
|
||||
TBigInteger y = new TBigInteger(1, new int[1 << n]);
|
||||
y.numberLength = 1;
|
||||
y.digits[0] = 1;
|
||||
y.sign = 1;
|
||||
|
||||
for (int i = 1; i < n; i++) {
|
||||
if (TBitLevel.testBit(x.multiply(y), i)) {
|
||||
// Adding 2^i to y (setting the i-th bit)
|
||||
y.digits[i >> 5] |= (1 << (i & 31));
|
||||
}
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs {@code x = x mod (2<sup>n</sup>)}.
|
||||
*
|
||||
* @param x
|
||||
* a positive number, it will store the result.
|
||||
* @param n
|
||||
* a positive exponent of {@code 2}.
|
||||
*/
|
||||
static void inplaceModPow2(TBigInteger x, int n) {
|
||||
// PRE: (x > 0) and (n >= 0)
|
||||
int fd = n >> 5;
|
||||
int leadingZeros;
|
||||
|
||||
if ((x.numberLength < fd) || (x.bitLength() <= n)) {
|
||||
return;
|
||||
}
|
||||
leadingZeros = 32 - (n & 31);
|
||||
x.numberLength = fd + 1;
|
||||
x.digits[fd] &= (leadingZeros < 32) ? (-1 >>> leadingZeros) : 0;
|
||||
x.cutOffLeadingZeroes();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,432 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
/**
|
||||
* Static library that provides the basic arithmetic mutable operations for
|
||||
* {@link TBigInteger}. The operations provided are listed below.
|
||||
* <ul type="circle">
|
||||
* <li>Addition.</li>
|
||||
* <li>Subtraction.</li>
|
||||
* <li>Comparison.</li>
|
||||
* </ul>
|
||||
* In addition to this, some <i><b>Inplace</b></i> (mutable) methods are
|
||||
* provided.
|
||||
*/
|
||||
class TElementary {
|
||||
|
||||
/** Just to denote that this class can't be instantiated */
|
||||
private TElementary() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two arrays. All elements are treated as unsigned integers. The
|
||||
* magnitude is the bit chain of elements in big-endian order.
|
||||
*
|
||||
* @param a
|
||||
* the first array
|
||||
* @param b
|
||||
* the second array
|
||||
* @param size
|
||||
* the size of arrays
|
||||
* @return 1 if a > b, -1 if a < b, 0 if a == b
|
||||
*/
|
||||
static int compareArrays(final int[] a, final int[] b, final int size) {
|
||||
int i;
|
||||
for (i = size - 1; (i >= 0) && (a[i] == b[i]); i--) {
|
||||
// do nothing
|
||||
}
|
||||
return ((i < 0) ? TBigInteger.EQUALS : (a[i] & 0xFFFFFFFFL) < (b[i] & 0xFFFFFFFFL) ? TBigInteger.LESS
|
||||
: TBigInteger.GREATER);
|
||||
}
|
||||
|
||||
/** @see TBigInteger#add(TBigInteger) */
|
||||
static TBigInteger add(TBigInteger op1, TBigInteger op2) {
|
||||
int resDigits[];
|
||||
int resSign;
|
||||
int op1Sign = op1.sign;
|
||||
int op2Sign = op2.sign;
|
||||
|
||||
if (op1Sign == 0) {
|
||||
return op2;
|
||||
}
|
||||
if (op2Sign == 0) {
|
||||
return op1;
|
||||
}
|
||||
int op1Len = op1.numberLength;
|
||||
int op2Len = op2.numberLength;
|
||||
|
||||
if (op1Len + op2Len == 2) {
|
||||
long a = (op1.digits[0] & 0xFFFFFFFFL);
|
||||
long b = (op2.digits[0] & 0xFFFFFFFFL);
|
||||
long res;
|
||||
int valueLo;
|
||||
int valueHi;
|
||||
|
||||
if (op1Sign == op2Sign) {
|
||||
res = a + b;
|
||||
valueLo = (int) res;
|
||||
valueHi = (int) (res >>> 32);
|
||||
return ((valueHi == 0) ? new TBigInteger(op1Sign, valueLo) : new TBigInteger(op1Sign, 2, new int[] {
|
||||
valueLo, valueHi }));
|
||||
}
|
||||
return TBigInteger.valueOf((op1Sign < 0) ? (b - a) : (a - b));
|
||||
} else if (op1Sign == op2Sign) {
|
||||
resSign = op1Sign;
|
||||
// an augend should not be shorter than addend
|
||||
resDigits = (op1Len >= op2Len) ? add(op1.digits, op1Len, op2.digits, op2Len) : add(op2.digits, op2Len,
|
||||
op1.digits, op1Len);
|
||||
} else { // signs are different
|
||||
int cmp = ((op1Len != op2Len) ? ((op1Len > op2Len) ? 1 : -1)
|
||||
: compareArrays(op1.digits, op2.digits, op1Len));
|
||||
|
||||
if (cmp == TBigInteger.EQUALS) {
|
||||
return TBigInteger.ZERO;
|
||||
}
|
||||
// a minuend should not be shorter than subtrahend
|
||||
if (cmp == TBigInteger.GREATER) {
|
||||
resSign = op1Sign;
|
||||
resDigits = subtract(op1.digits, op1Len, op2.digits, op2Len);
|
||||
} else {
|
||||
resSign = op2Sign;
|
||||
resDigits = subtract(op2.digits, op2Len, op1.digits, op1Len);
|
||||
}
|
||||
}
|
||||
TBigInteger res = new TBigInteger(resSign, resDigits.length, resDigits);
|
||||
res.cutOffLeadingZeroes();
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs {@code res = a + b}.
|
||||
*/
|
||||
private static void add(int res[], int a[], int aSize, int b[], int bSize) {
|
||||
// PRE: a.length < max(aSize, bSize)
|
||||
|
||||
int i;
|
||||
long carry = (a[0] & 0xFFFFFFFFL) + (b[0] & 0xFFFFFFFFL);
|
||||
|
||||
res[0] = (int) carry;
|
||||
carry >>= 32;
|
||||
|
||||
if (aSize >= bSize) {
|
||||
for (i = 1; i < bSize; i++) {
|
||||
carry += (a[i] & 0xFFFFFFFFL) + (b[i] & 0xFFFFFFFFL);
|
||||
res[i] = (int) carry;
|
||||
carry >>= 32;
|
||||
}
|
||||
for (; i < aSize; i++) {
|
||||
carry += a[i] & 0xFFFFFFFFL;
|
||||
res[i] = (int) carry;
|
||||
carry >>= 32;
|
||||
}
|
||||
} else {
|
||||
for (i = 1; i < aSize; i++) {
|
||||
carry += (a[i] & 0xFFFFFFFFL) + (b[i] & 0xFFFFFFFFL);
|
||||
res[i] = (int) carry;
|
||||
carry >>= 32;
|
||||
}
|
||||
for (; i < bSize; i++) {
|
||||
carry += b[i] & 0xFFFFFFFFL;
|
||||
res[i] = (int) carry;
|
||||
carry >>= 32;
|
||||
}
|
||||
}
|
||||
if (carry != 0) {
|
||||
res[i] = (int) carry;
|
||||
}
|
||||
}
|
||||
|
||||
/** @see TBigInteger#subtract(TBigInteger) */
|
||||
static TBigInteger subtract(TBigInteger op1, TBigInteger op2) {
|
||||
int resSign;
|
||||
int resDigits[];
|
||||
int op1Sign = op1.sign;
|
||||
int op2Sign = op2.sign;
|
||||
|
||||
if (op2Sign == 0) {
|
||||
return op1;
|
||||
}
|
||||
if (op1Sign == 0) {
|
||||
return op2.negate();
|
||||
}
|
||||
int op1Len = op1.numberLength;
|
||||
int op2Len = op2.numberLength;
|
||||
if (op1Len + op2Len == 2) {
|
||||
long a = (op1.digits[0] & 0xFFFFFFFFL);
|
||||
long b = (op2.digits[0] & 0xFFFFFFFFL);
|
||||
if (op1Sign < 0) {
|
||||
a = -a;
|
||||
}
|
||||
if (op2Sign < 0) {
|
||||
b = -b;
|
||||
}
|
||||
return TBigInteger.valueOf(a - b);
|
||||
}
|
||||
int cmp = ((op1Len != op2Len) ? ((op1Len > op2Len) ? 1 : -1) : TElementary.compareArrays(op1.digits, op2.digits,
|
||||
op1Len));
|
||||
|
||||
if (cmp == TBigInteger.LESS) {
|
||||
resSign = -op2Sign;
|
||||
resDigits = (op1Sign == op2Sign) ? subtract(op2.digits, op2Len, op1.digits, op1Len) : add(op2.digits,
|
||||
op2Len, op1.digits, op1Len);
|
||||
} else {
|
||||
resSign = op1Sign;
|
||||
if (op1Sign == op2Sign) {
|
||||
if (cmp == TBigInteger.EQUALS) {
|
||||
return TBigInteger.ZERO;
|
||||
}
|
||||
resDigits = subtract(op1.digits, op1Len, op2.digits, op2Len);
|
||||
} else {
|
||||
resDigits = add(op1.digits, op1Len, op2.digits, op2Len);
|
||||
}
|
||||
}
|
||||
TBigInteger res = new TBigInteger(resSign, resDigits.length, resDigits);
|
||||
res.cutOffLeadingZeroes();
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs {@code res = a - b}. It is assumed the magnitude of a is not
|
||||
* less than the magnitude of b.
|
||||
*/
|
||||
private static void subtract(int res[], int a[], int aSize, int b[], int bSize) {
|
||||
// PRE: a[] >= b[]
|
||||
int i;
|
||||
long borrow = 0;
|
||||
|
||||
for (i = 0; i < bSize; i++) {
|
||||
borrow += (a[i] & 0xFFFFFFFFL) - (b[i] & 0xFFFFFFFFL);
|
||||
res[i] = (int) borrow;
|
||||
borrow >>= 32; // -1 or 0
|
||||
}
|
||||
for (; i < aSize; i++) {
|
||||
borrow += a[i] & 0xFFFFFFFFL;
|
||||
res[i] = (int) borrow;
|
||||
borrow >>= 32; // -1 or 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Addss the value represented by {@code b} to the value represented by
|
||||
* {@code a}. It is assumed the magnitude of a is not less than the
|
||||
* magnitude of b.
|
||||
*
|
||||
* @return {@code a + b}
|
||||
*/
|
||||
private static int[] add(int a[], int aSize, int b[], int bSize) {
|
||||
// PRE: a[] >= b[]
|
||||
int res[] = new int[aSize + 1];
|
||||
add(res, a, aSize, b, bSize);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs {@code op1 += op2}. {@code op1} must have enough place to store
|
||||
* the result (i.e. {@code op1.bitLength() >= op2.bitLength()}). Both should
|
||||
* be positive (i.e. {@code op1 >= op2}).
|
||||
*
|
||||
* @param op1
|
||||
* the input minuend, and the output result.
|
||||
* @param op2
|
||||
* the addend
|
||||
*/
|
||||
static void inplaceAdd(TBigInteger op1, TBigInteger op2) {
|
||||
// PRE: op1 >= op2 > 0
|
||||
add(op1.digits, op1.digits, op1.numberLength, op2.digits, op2.numberLength);
|
||||
op1.numberLength = Math.min(Math.max(op1.numberLength, op2.numberLength) + 1, op1.digits.length);
|
||||
op1.cutOffLeadingZeroes();
|
||||
op1.unCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an integer value to the array of integers remembering carry.
|
||||
*
|
||||
* @return a possible generated carry (0 or 1)
|
||||
*/
|
||||
static int inplaceAdd(int a[], final int aSize, final int addend) {
|
||||
long carry = addend & 0xFFFFFFFFL;
|
||||
|
||||
for (int i = 0; (carry != 0) && (i < aSize); i++) {
|
||||
carry += a[i] & 0xFFFFFFFFL;
|
||||
a[i] = (int) carry;
|
||||
carry >>= 32;
|
||||
}
|
||||
return (int) carry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs: {@code op1 += addend}. The number must to have place to hold a
|
||||
* possible carry.
|
||||
*/
|
||||
static void inplaceAdd(TBigInteger op1, final int addend) {
|
||||
int carry = inplaceAdd(op1.digits, op1.numberLength, addend);
|
||||
if (carry == 1) {
|
||||
op1.digits[op1.numberLength] = 1;
|
||||
op1.numberLength++;
|
||||
}
|
||||
op1.unCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs {@code op1 -= op2}. {@code op1} must have enough place to store
|
||||
* the result (i.e. {@code op1.bitLength() >= op2.bitLength()}). Both should
|
||||
* be positive (what implies that {@code op1 >= op2}).
|
||||
*
|
||||
* @param op1
|
||||
* the input minuend, and the output result.
|
||||
* @param op2
|
||||
* the subtrahend
|
||||
*/
|
||||
static void inplaceSubtract(TBigInteger op1, TBigInteger op2) {
|
||||
// PRE: op1 >= op2 > 0
|
||||
subtract(op1.digits, op1.digits, op1.numberLength, op2.digits, op2.numberLength);
|
||||
op1.cutOffLeadingZeroes();
|
||||
op1.unCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs {@code res = b - a}
|
||||
*/
|
||||
private static void inverseSubtract(int res[], int a[], int aSize, int b[], int bSize) {
|
||||
int i;
|
||||
long borrow = 0;
|
||||
if (aSize < bSize) {
|
||||
for (i = 0; i < aSize; i++) {
|
||||
borrow += (b[i] & 0xFFFFFFFFL) - (a[i] & 0xFFFFFFFFL);
|
||||
res[i] = (int) borrow;
|
||||
borrow >>= 32; // -1 or 0
|
||||
}
|
||||
for (; i < bSize; i++) {
|
||||
borrow += b[i] & 0xFFFFFFFFL;
|
||||
res[i] = (int) borrow;
|
||||
borrow >>= 32; // -1 or 0
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < bSize; i++) {
|
||||
borrow += (b[i] & 0xFFFFFFFFL) - (a[i] & 0xFFFFFFFFL);
|
||||
res[i] = (int) borrow;
|
||||
borrow >>= 32; // -1 or 0
|
||||
}
|
||||
for (; i < aSize; i++) {
|
||||
borrow -= a[i] & 0xFFFFFFFFL;
|
||||
res[i] = (int) borrow;
|
||||
borrow >>= 32; // -1 or 0
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts the value represented by {@code b} from the value represented
|
||||
* by {@code a}. It is assumed the magnitude of a is not less than the
|
||||
* magnitude of b.
|
||||
*
|
||||
* @return {@code a - b}
|
||||
*/
|
||||
private static int[] subtract(int a[], int aSize, int b[], int bSize) {
|
||||
// PRE: a[] >= b[]
|
||||
int res[] = new int[aSize];
|
||||
subtract(res, a, aSize, b, bSize);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as
|
||||
*
|
||||
* @link #inplaceSubtract(BigInteger, BigInteger), but without the
|
||||
* restriction of non-positive values
|
||||
* @param op1
|
||||
* should have enough space to save the result
|
||||
* @param op2
|
||||
*/
|
||||
static void completeInPlaceSubtract(TBigInteger op1, TBigInteger op2) {
|
||||
int resultSign = op1.compareTo(op2);
|
||||
if (op1.sign == 0) {
|
||||
System.arraycopy(op2.digits, 0, op1.digits, 0, op2.numberLength);
|
||||
op1.sign = -op2.sign;
|
||||
} else if (op1.sign != op2.sign) {
|
||||
add(op1.digits, op1.digits, op1.numberLength, op2.digits, op2.numberLength);
|
||||
op1.sign = resultSign;
|
||||
} else {
|
||||
int sign = unsignedArraysCompare(op1.digits, op2.digits, op1.numberLength, op2.numberLength);
|
||||
if (sign > 0) {
|
||||
subtract(op1.digits, op1.digits, op1.numberLength, op2.digits, op2.numberLength);
|
||||
// op1.sign remains equal
|
||||
} else {
|
||||
inverseSubtract(op1.digits, op1.digits, op1.numberLength, op2.digits, op2.numberLength);
|
||||
op1.sign = -op1.sign;
|
||||
}
|
||||
}
|
||||
op1.numberLength = Math.max(op1.numberLength, op2.numberLength) + 1;
|
||||
op1.cutOffLeadingZeroes();
|
||||
op1.unCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as @link #inplaceAdd(BigInteger, BigInteger), but without the
|
||||
* restriction of non-positive values
|
||||
*
|
||||
* @param op1
|
||||
* any number
|
||||
* @param op2
|
||||
* any number
|
||||
*/
|
||||
static void completeInPlaceAdd(TBigInteger op1, TBigInteger op2) {
|
||||
if (op1.sign == 0)
|
||||
System.arraycopy(op2.digits, 0, op1.digits, 0, op2.numberLength);
|
||||
else if (op2.sign == 0)
|
||||
return;
|
||||
else if (op1.sign == op2.sign)
|
||||
add(op1.digits, op1.digits, op1.numberLength, op2.digits, op2.numberLength);
|
||||
else {
|
||||
int sign = unsignedArraysCompare(op1.digits, op2.digits, op1.numberLength, op2.numberLength);
|
||||
if (sign > 0)
|
||||
subtract(op1.digits, op1.digits, op1.numberLength, op2.digits, op2.numberLength);
|
||||
else {
|
||||
inverseSubtract(op1.digits, op1.digits, op1.numberLength, op2.digits, op2.numberLength);
|
||||
op1.sign = -op1.sign;
|
||||
}
|
||||
}
|
||||
op1.numberLength = Math.max(op1.numberLength, op2.numberLength) + 1;
|
||||
op1.cutOffLeadingZeroes();
|
||||
op1.unCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two arrays, representing unsigned integer in little-endian
|
||||
* order. Returns +1,0,-1 if a is - respective - greater, equal or lesser
|
||||
* then b
|
||||
*/
|
||||
private static int unsignedArraysCompare(int[] a, int[] b, int aSize, int bSize) {
|
||||
if (aSize > bSize)
|
||||
return 1;
|
||||
else if (aSize < bSize)
|
||||
return -1;
|
||||
|
||||
else {
|
||||
int i;
|
||||
for (i = aSize - 1; i >= 0 && a[i] == b[i]; i--) {
|
||||
// do nothing
|
||||
}
|
||||
return i < 0 ? TBigInteger.EQUALS : ((a[i] & 0xFFFFFFFFL) < (b[i] & 0xFFFFFFFFL) ? TBigInteger.LESS
|
||||
: TBigInteger.GREATER);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,808 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
/**
|
||||
* The library implements some logical operations over {@code BigInteger}. The
|
||||
* operations provided are listed below.
|
||||
* <ul type="circle">
|
||||
* <li>not</li>
|
||||
* <li>and</li>
|
||||
* <li>andNot</li>
|
||||
* <li>or</li>
|
||||
* <li>xor</li>
|
||||
* </ul>
|
||||
*/
|
||||
class TLogical {
|
||||
|
||||
/** Just to denote that this class can't be instantiated. */
|
||||
|
||||
private TLogical() {}
|
||||
|
||||
|
||||
/** @see TBigInteger#not() */
|
||||
static TBigInteger not(TBigInteger val) {
|
||||
if (val.sign == 0) {
|
||||
return TBigInteger.MINUS_ONE;
|
||||
}
|
||||
if (val.equals(TBigInteger.MINUS_ONE)) {
|
||||
return TBigInteger.ZERO;
|
||||
}
|
||||
int resDigits[] = new int[val.numberLength + 1];
|
||||
int i;
|
||||
|
||||
if (val.sign > 0) {
|
||||
// ~val = -val + 1
|
||||
if (val.digits[val.numberLength - 1] != -1) {
|
||||
for (i = 0; val.digits[i] == -1; i++) {
|
||||
// do nothing
|
||||
}
|
||||
} else {
|
||||
for (i = 0; (i < val.numberLength) && (val.digits[i] == -1); i++) {
|
||||
// do nothing
|
||||
}
|
||||
if (i == val.numberLength) {
|
||||
resDigits[i] = 1;
|
||||
return new TBigInteger(-val.sign, i + 1, resDigits);
|
||||
}
|
||||
}
|
||||
// Here a carry 1 was generated
|
||||
} else {// (val.sign < 0)
|
||||
// ~val = -val - 1
|
||||
for (i = 0; val.digits[i] == 0; i++) {
|
||||
resDigits[i] = -1;
|
||||
}
|
||||
// Here a borrow -1 was generated
|
||||
}
|
||||
// Now, the carry/borrow can be absorbed
|
||||
resDigits[i] = val.digits[i] + val.sign;
|
||||
// Copying the remaining unchanged digit
|
||||
for (i++; i < val.numberLength; i++) {
|
||||
resDigits[i] = val.digits[i];
|
||||
}
|
||||
return new TBigInteger(-val.sign, i, resDigits);
|
||||
}
|
||||
|
||||
/** @see TBigInteger#and(TBigInteger) */
|
||||
static TBigInteger and(TBigInteger val, TBigInteger that) {
|
||||
if (that.sign == 0 || val.sign == 0) {
|
||||
return TBigInteger.ZERO;
|
||||
}
|
||||
if (that.equals(TBigInteger.MINUS_ONE)){
|
||||
return val;
|
||||
}
|
||||
if (val.equals(TBigInteger.MINUS_ONE)) {
|
||||
return that;
|
||||
}
|
||||
|
||||
if (val.sign > 0) {
|
||||
if (that.sign > 0) {
|
||||
return andPositive(val, that);
|
||||
} else {
|
||||
return andDiffSigns(val, that);
|
||||
}
|
||||
} else {
|
||||
if (that.sign > 0) {
|
||||
return andDiffSigns(that, val);
|
||||
} else if (val.numberLength > that.numberLength) {
|
||||
return andNegative(val, that);
|
||||
} else {
|
||||
return andNegative(that, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @return sign = 1, magnitude = val.magnitude & that.magnitude*/
|
||||
static TBigInteger andPositive(TBigInteger val, TBigInteger that) {
|
||||
// PRE: both arguments are positive
|
||||
int resLength = Math.min(val.numberLength, that.numberLength);
|
||||
int i = Math.max(val.getFirstNonzeroDigit(), that.getFirstNonzeroDigit());
|
||||
|
||||
if (i >= resLength) {
|
||||
return TBigInteger.ZERO;
|
||||
}
|
||||
|
||||
int resDigits[] = new int[resLength];
|
||||
for ( ; i < resLength; i++) {
|
||||
resDigits[i] = val.digits[i] & that.digits[i];
|
||||
}
|
||||
|
||||
TBigInteger result = new TBigInteger(1, resLength, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return sign = positive.magnitude & magnitude = -negative.magnitude */
|
||||
static TBigInteger andDiffSigns(TBigInteger positive, TBigInteger negative) {
|
||||
// PRE: positive is positive and negative is negative
|
||||
int iPos = positive.getFirstNonzeroDigit();
|
||||
int iNeg = negative.getFirstNonzeroDigit();
|
||||
|
||||
// Look if the trailing zeros of the negative will "blank" all
|
||||
// the positive digits
|
||||
if (iNeg >= positive.numberLength) {
|
||||
return TBigInteger.ZERO;
|
||||
}
|
||||
int resLength = positive.numberLength;
|
||||
int resDigits[] = new int[resLength];
|
||||
|
||||
// Must start from max(iPos, iNeg)
|
||||
int i = Math.max(iPos, iNeg);
|
||||
if (i == iNeg) {
|
||||
resDigits[i] = -negative.digits[i] & positive.digits[i];
|
||||
i++;
|
||||
}
|
||||
int limit = Math.min(negative.numberLength, positive.numberLength);
|
||||
for ( ; i < limit; i++) {
|
||||
resDigits[i] = ~negative.digits[i] & positive.digits[i];
|
||||
}
|
||||
// if the negative was shorter must copy the remaining digits
|
||||
// from positive
|
||||
if (i >= negative.numberLength) {
|
||||
for ( ; i < positive.numberLength; i++) {
|
||||
resDigits[i] = positive.digits[i];
|
||||
}
|
||||
} // else positive ended and must "copy" virtual 0's, do nothing then
|
||||
|
||||
TBigInteger result = new TBigInteger(1, resLength, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return sign = -1, magnitude = -(-longer.magnitude & -shorter.magnitude)*/
|
||||
static TBigInteger andNegative(TBigInteger longer, TBigInteger shorter) {
|
||||
// PRE: longer and shorter are negative
|
||||
// PRE: longer has at least as many digits as shorter
|
||||
int iLonger = longer.getFirstNonzeroDigit();
|
||||
int iShorter = shorter.getFirstNonzeroDigit();
|
||||
|
||||
// Does shorter matter?
|
||||
if (iLonger >= shorter.numberLength) {
|
||||
return longer;
|
||||
}
|
||||
|
||||
int resLength;
|
||||
int resDigits[];
|
||||
int i = Math.max(iShorter, iLonger);
|
||||
int digit;
|
||||
if (iShorter > iLonger) {
|
||||
digit = -shorter.digits[i] & ~longer.digits[i];
|
||||
} else if (iShorter < iLonger) {
|
||||
digit = ~shorter.digits[i] & -longer.digits[i];
|
||||
} else {
|
||||
digit = -shorter.digits[i] & -longer.digits[i];
|
||||
}
|
||||
if (digit == 0) {
|
||||
for (i++; i < shorter.numberLength && (digit = ~(longer.digits[i] | shorter.digits[i])) == 0; i++) {
|
||||
// do nothing
|
||||
}
|
||||
if (digit == 0) {
|
||||
// shorter has only the remaining virtual sign bits
|
||||
for ( ; i < longer.numberLength && (digit = ~longer.digits[i]) == 0; i++) {
|
||||
// do nothing
|
||||
}
|
||||
if (digit == 0) {
|
||||
resLength = longer.numberLength + 1;
|
||||
resDigits = new int[resLength];
|
||||
resDigits[resLength - 1] = 1;
|
||||
|
||||
TBigInteger result = new TBigInteger(-1, resLength, resDigits);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
resLength = longer.numberLength;
|
||||
resDigits = new int[resLength];
|
||||
resDigits[i] = -digit;
|
||||
for (i++; i < shorter.numberLength; i++){
|
||||
// resDigits[i] = ~(~longer.digits[i] & ~shorter.digits[i];)
|
||||
resDigits[i] = longer.digits[i] | shorter.digits[i];
|
||||
}
|
||||
// shorter has only the remaining virtual sign bits
|
||||
for( ; i < longer.numberLength; i++){
|
||||
resDigits[i] = longer.digits[i];
|
||||
}
|
||||
|
||||
TBigInteger result = new TBigInteger(-1, resLength, resDigits);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @see TBigInteger#andNot(TBigInteger) */
|
||||
static TBigInteger andNot(TBigInteger val, TBigInteger that) {
|
||||
if (that.sign == 0 ) {
|
||||
return val;
|
||||
}
|
||||
if (val.sign == 0) {
|
||||
return TBigInteger.ZERO;
|
||||
}
|
||||
if (val.equals(TBigInteger.MINUS_ONE)) {
|
||||
return that.not();
|
||||
}
|
||||
if (that.equals(TBigInteger.MINUS_ONE)){
|
||||
return TBigInteger.ZERO;
|
||||
}
|
||||
|
||||
//if val == that, return 0
|
||||
|
||||
if (val.sign > 0) {
|
||||
if (that.sign > 0) {
|
||||
return andNotPositive(val, that);
|
||||
} else {
|
||||
return andNotPositiveNegative(val, that);
|
||||
}
|
||||
} else {
|
||||
if (that.sign > 0) {
|
||||
return andNotNegativePositive(val, that);
|
||||
} else {
|
||||
return andNotNegative(val, that);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @return sign = 1, magnitude = val.magnitude & ~that.magnitude*/
|
||||
static TBigInteger andNotPositive(TBigInteger val, TBigInteger that) {
|
||||
// PRE: both arguments are positive
|
||||
int resDigits[] = new int[val.numberLength];
|
||||
|
||||
int limit = Math.min(val.numberLength, that.numberLength);
|
||||
int i;
|
||||
for (i = val.getFirstNonzeroDigit(); i < limit; i++) {
|
||||
resDigits[i] = val.digits[i] & ~that.digits[i];
|
||||
}
|
||||
for ( ; i < val.numberLength; i++) {
|
||||
resDigits[i] = val.digits[i];
|
||||
}
|
||||
|
||||
TBigInteger result = new TBigInteger(1, val.numberLength, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return sign = 1, magnitude = positive.magnitude & ~(-negative.magnitude)*/
|
||||
static TBigInteger andNotPositiveNegative(TBigInteger positive, TBigInteger negative) {
|
||||
// PRE: positive > 0 && negative < 0
|
||||
int iNeg = negative.getFirstNonzeroDigit();
|
||||
int iPos = positive.getFirstNonzeroDigit();
|
||||
|
||||
if (iNeg >= positive.numberLength) {
|
||||
return positive;
|
||||
}
|
||||
|
||||
int resLength = Math.min(positive.numberLength, negative.numberLength);
|
||||
int resDigits[] = new int[resLength];
|
||||
|
||||
// Always start from first non zero of positive
|
||||
int i = iPos;
|
||||
for ( ; i < iNeg; i++) {
|
||||
// resDigits[i] = positive.digits[i] & -1 (~0)
|
||||
resDigits[i] = positive.digits[i];
|
||||
}
|
||||
if (i == iNeg) {
|
||||
resDigits[i] = positive.digits[i] & (negative.digits[i] - 1);
|
||||
i++;
|
||||
}
|
||||
for ( ; i < resLength; i++) {
|
||||
// resDigits[i] = positive.digits[i] & ~(~negative.digits[i]);
|
||||
resDigits[i] = positive.digits[i] & negative.digits[i];
|
||||
}
|
||||
|
||||
TBigInteger result = new TBigInteger(1, resLength, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return sign = -1, magnitude = -(-negative.magnitude & ~positive.magnitude)*/
|
||||
static TBigInteger andNotNegativePositive(TBigInteger negative, TBigInteger positive) {
|
||||
// PRE: negative < 0 && positive > 0
|
||||
int resLength;
|
||||
int resDigits[];
|
||||
int limit;
|
||||
int digit;
|
||||
|
||||
int iNeg = negative.getFirstNonzeroDigit();
|
||||
int iPos = positive.getFirstNonzeroDigit();
|
||||
|
||||
if (iNeg >= positive.numberLength) {
|
||||
return negative;
|
||||
}
|
||||
|
||||
resLength = Math.max(negative.numberLength, positive.numberLength);
|
||||
int i = iNeg;
|
||||
if (iPos > iNeg) {
|
||||
resDigits = new int[resLength];
|
||||
limit = Math.min(negative.numberLength, iPos);
|
||||
for ( ; i < limit; i++) {
|
||||
// 1st case: resDigits [i] = -(-negative.digits[i] & (~0))
|
||||
// otherwise: resDigits[i] = ~(~negative.digits[i] & ~0) ;
|
||||
resDigits[i] = negative.digits[i];
|
||||
}
|
||||
if (i == negative.numberLength) {
|
||||
for (i = iPos; i < positive.numberLength; i++) {
|
||||
// resDigits[i] = ~(~positive.digits[i] & -1);
|
||||
resDigits[i] = positive.digits[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
digit = -negative.digits[i] & ~positive.digits[i];
|
||||
if (digit == 0) {
|
||||
limit = Math.min(positive.numberLength, negative.numberLength);
|
||||
for (i++; i < limit && (digit = ~(negative.digits[i] | positive.digits[i])) == 0; i++) {
|
||||
// do nothing
|
||||
}
|
||||
if (digit == 0) {
|
||||
// the shorter has only the remaining virtual sign bits
|
||||
for ( ; i < positive.numberLength && (digit = ~positive.digits[i]) == 0; i++) {
|
||||
// do nothing
|
||||
}
|
||||
for ( ; i < negative.numberLength && (digit = ~negative.digits[i]) == 0; i++) {
|
||||
// do nothing
|
||||
}
|
||||
if (digit == 0) {
|
||||
resLength++;
|
||||
resDigits = new int[resLength];
|
||||
resDigits[resLength - 1] = 1;
|
||||
|
||||
TBigInteger result = new TBigInteger(-1, resLength, resDigits);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
resDigits = new int[resLength];
|
||||
resDigits[i] = -digit;
|
||||
i++;
|
||||
}
|
||||
|
||||
limit = Math.min(positive.numberLength, negative.numberLength);
|
||||
for ( ; i < limit; i++) {
|
||||
//resDigits[i] = ~(~negative.digits[i] & ~positive.digits[i]);
|
||||
resDigits[i] = negative.digits[i] | positive.digits[i];
|
||||
}
|
||||
// Actually one of the next two cycles will be executed
|
||||
for ( ; i < negative.numberLength; i++) {
|
||||
resDigits[i] = negative.digits[i];
|
||||
}
|
||||
for ( ; i < positive.numberLength; i++) {
|
||||
resDigits[i] = positive.digits[i];
|
||||
}
|
||||
|
||||
TBigInteger result = new TBigInteger(-1, resLength, resDigits);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return sign = 1, magnitude = -val.magnitude & ~(-that.magnitude)*/
|
||||
static TBigInteger andNotNegative(TBigInteger val, TBigInteger that) {
|
||||
// PRE: val < 0 && that < 0
|
||||
int iVal = val.getFirstNonzeroDigit();
|
||||
int iThat = that.getFirstNonzeroDigit();
|
||||
|
||||
if (iVal >= that.numberLength) {
|
||||
return TBigInteger.ZERO;
|
||||
}
|
||||
|
||||
int resLength = that.numberLength;
|
||||
int resDigits[] = new int[resLength];
|
||||
int limit;
|
||||
int i = iVal;
|
||||
if (iVal < iThat) {
|
||||
// resDigits[i] = -val.digits[i] & -1;
|
||||
resDigits[i] = -val.digits[i];
|
||||
limit = Math.min(val.numberLength, iThat);
|
||||
for (i++; i < limit; i++) {
|
||||
// resDigits[i] = ~val.digits[i] & -1;
|
||||
resDigits[i] = ~val.digits[i];
|
||||
}
|
||||
if (i == val.numberLength) {
|
||||
for ( ; i < iThat; i++) {
|
||||
// resDigits[i] = -1 & -1;
|
||||
resDigits[i] = -1;
|
||||
}
|
||||
// resDigits[i] = -1 & ~-that.digits[i];
|
||||
resDigits[i] = that.digits[i] - 1;
|
||||
} else {
|
||||
// resDigits[i] = ~val.digits[i] & ~-that.digits[i];
|
||||
resDigits[i] = ~val.digits[i] & (that.digits[i] - 1);
|
||||
}
|
||||
} else if (iThat < iVal ) {
|
||||
// resDigits[i] = -val.digits[i] & ~~that.digits[i];
|
||||
resDigits[i] = -val.digits[i] & that.digits[i];
|
||||
} else {
|
||||
// resDigits[i] = -val.digits[i] & ~-that.digits[i];
|
||||
resDigits[i] = -val.digits[i] & (that.digits[i] - 1);
|
||||
}
|
||||
|
||||
limit = Math.min(val.numberLength, that.numberLength);
|
||||
for (i++; i < limit; i++) {
|
||||
// resDigits[i] = ~val.digits[i] & ~~that.digits[i];
|
||||
resDigits[i] = ~val.digits[i] & that.digits[i];
|
||||
}
|
||||
for ( ; i < that.numberLength; i++) {
|
||||
// resDigits[i] = -1 & ~~that.digits[i];
|
||||
resDigits[i] = that.digits[i];
|
||||
}
|
||||
|
||||
TBigInteger result = new TBigInteger(1, resLength, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @see TBigInteger#or(TBigInteger) */
|
||||
static TBigInteger or(TBigInteger val, TBigInteger that) {
|
||||
if (that.equals(TBigInteger.MINUS_ONE) || val.equals(TBigInteger.MINUS_ONE)) {
|
||||
return TBigInteger.MINUS_ONE;
|
||||
}
|
||||
if (that.sign == 0) {
|
||||
return val;
|
||||
}
|
||||
if (val.sign == 0) {
|
||||
return that;
|
||||
}
|
||||
|
||||
if (val.sign > 0) {
|
||||
if (that.sign > 0) {
|
||||
if (val.numberLength > that.numberLength) {
|
||||
return orPositive(val, that);
|
||||
} else {
|
||||
return orPositive(that, val);
|
||||
}
|
||||
} else {
|
||||
return orDiffSigns(val, that);
|
||||
}
|
||||
} else {
|
||||
if (that.sign > 0) {
|
||||
return orDiffSigns(that, val);
|
||||
} else if (that.getFirstNonzeroDigit() > val.getFirstNonzeroDigit()) {
|
||||
return orNegative(that, val);
|
||||
} else {
|
||||
return orNegative(val, that);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @return sign = 1, magnitude = longer.magnitude | shorter.magnitude*/
|
||||
static TBigInteger orPositive(TBigInteger longer, TBigInteger shorter) {
|
||||
// PRE: longer and shorter are positive;
|
||||
// PRE: longer has at least as many digits as shorter
|
||||
int resLength = longer.numberLength;
|
||||
int resDigits[] = new int[resLength];
|
||||
|
||||
int i = Math.min(longer.getFirstNonzeroDigit(), shorter.getFirstNonzeroDigit());
|
||||
for (i = 0; i < shorter.numberLength; i++) {
|
||||
resDigits[i] = longer.digits[i] | shorter.digits[i];
|
||||
}
|
||||
for ( ; i < resLength; i++) {
|
||||
resDigits[i] = longer.digits[i];
|
||||
}
|
||||
|
||||
TBigInteger result = new TBigInteger(1, resLength, resDigits);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return sign = -1, magnitude = -(-val.magnitude | -that.magnitude) */
|
||||
static TBigInteger orNegative(TBigInteger val, TBigInteger that){
|
||||
// PRE: val and that are negative;
|
||||
// PRE: val has at least as many trailing zeros digits as that
|
||||
int iThat = that.getFirstNonzeroDigit();
|
||||
int iVal = val.getFirstNonzeroDigit();
|
||||
int i;
|
||||
|
||||
if (iVal >= that.numberLength) {
|
||||
return that;
|
||||
}else if (iThat >= val.numberLength) {
|
||||
return val;
|
||||
}
|
||||
|
||||
int resLength = Math.min(val.numberLength, that.numberLength);
|
||||
int resDigits[] = new int[resLength];
|
||||
|
||||
//Looking for the first non-zero digit of the result
|
||||
if (iThat == iVal) {
|
||||
resDigits[iVal] = -(-val.digits[iVal] | -that.digits[iVal]);
|
||||
i = iVal;
|
||||
} else {
|
||||
for (i = iThat; i < iVal; i++) {
|
||||
resDigits[i] = that.digits[i];
|
||||
}
|
||||
resDigits[i] = that.digits[i] & (val.digits[i] - 1);
|
||||
}
|
||||
|
||||
for (i++; i < resLength; i++) {
|
||||
resDigits[i] = val.digits[i] & that.digits[i];
|
||||
}
|
||||
|
||||
TBigInteger result = new TBigInteger(-1, resLength, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return sign = -1, magnitude = -(positive.magnitude | -negative.magnitude) */
|
||||
static TBigInteger orDiffSigns(TBigInteger positive, TBigInteger negative){
|
||||
// Jumping over the least significant zero bits
|
||||
int iNeg = negative.getFirstNonzeroDigit();
|
||||
int iPos = positive.getFirstNonzeroDigit();
|
||||
int i;
|
||||
int limit;
|
||||
|
||||
// Look if the trailing zeros of the positive will "copy" all
|
||||
// the negative digits
|
||||
if (iPos >= negative.numberLength) {
|
||||
return negative;
|
||||
}
|
||||
int resLength = negative.numberLength;
|
||||
int resDigits[] = new int[resLength];
|
||||
|
||||
if (iNeg < iPos ) {
|
||||
// We know for sure that this will
|
||||
// be the first non zero digit in the result
|
||||
for (i = iNeg; i < iPos; i++) {
|
||||
resDigits[i] = negative.digits[i];
|
||||
}
|
||||
} else if (iPos < iNeg) {
|
||||
i = iPos;
|
||||
resDigits[i] = -positive.digits[i];
|
||||
limit = Math.min(positive.numberLength, iNeg);
|
||||
for(i++; i < limit; i++ ) {
|
||||
resDigits[i] = ~positive.digits[i];
|
||||
}
|
||||
if (i != positive.numberLength) {
|
||||
resDigits[i] = ~(-negative.digits[i] | positive.digits[i]);
|
||||
} else{
|
||||
for (; i<iNeg; i++) {
|
||||
resDigits[i] = -1;
|
||||
}
|
||||
// resDigits[i] = ~(-negative.digits[i] | 0);
|
||||
resDigits[i] = negative.digits[i] - 1;
|
||||
}
|
||||
i++;
|
||||
} else {// iNeg == iPos
|
||||
// Applying two complement to negative and to result
|
||||
i = iPos;
|
||||
resDigits[i] = -(-negative.digits[i] | positive.digits[i]);
|
||||
i++;
|
||||
}
|
||||
limit = Math.min(negative.numberLength, positive.numberLength);
|
||||
for (; i < limit; i++) {
|
||||
// Applying two complement to negative and to result
|
||||
// resDigits[i] = ~(~negative.digits[i] | positive.digits[i] );
|
||||
resDigits[i] = negative.digits[i] & ~positive.digits[i];
|
||||
}
|
||||
for( ; i < negative.numberLength; i++) {
|
||||
resDigits[i] = negative.digits[i];
|
||||
}
|
||||
|
||||
TBigInteger result = new TBigInteger(-1, resLength, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @see TBigInteger#xor(TBigInteger) */
|
||||
static TBigInteger xor(TBigInteger val, TBigInteger that) {
|
||||
if (that.sign == 0) {
|
||||
return val;
|
||||
}
|
||||
if (val.sign == 0) {
|
||||
return that;
|
||||
}
|
||||
if (that.equals(TBigInteger.MINUS_ONE)) {
|
||||
return val.not();
|
||||
}
|
||||
if (val.equals(TBigInteger.MINUS_ONE)) {
|
||||
return that.not();
|
||||
}
|
||||
|
||||
if (val.sign > 0) {
|
||||
if (that.sign > 0) {
|
||||
if (val.numberLength > that.numberLength) {
|
||||
return xorPositive(val, that);
|
||||
} else {
|
||||
return xorPositive(that, val);
|
||||
}
|
||||
} else {
|
||||
return xorDiffSigns(val, that);
|
||||
}
|
||||
} else {
|
||||
if (that.sign > 0) {
|
||||
return xorDiffSigns(that, val);
|
||||
} else if (that.getFirstNonzeroDigit() > val.getFirstNonzeroDigit()) {
|
||||
return xorNegative(that, val);
|
||||
} else {
|
||||
return xorNegative(val, that);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @return sign = 0, magnitude = longer.magnitude | shorter.magnitude */
|
||||
static TBigInteger xorPositive(TBigInteger longer, TBigInteger shorter) {
|
||||
// PRE: longer and shorter are positive;
|
||||
// PRE: longer has at least as many digits as shorter
|
||||
int resLength = longer.numberLength;
|
||||
int resDigits[] = new int[resLength];
|
||||
int i = Math.min(longer.getFirstNonzeroDigit(), shorter.getFirstNonzeroDigit());
|
||||
for ( ; i < shorter.numberLength; i++) {
|
||||
resDigits[i] = longer.digits[i] ^ shorter.digits[i];
|
||||
}
|
||||
for( ; i < longer.numberLength; i++ ){
|
||||
resDigits[i] = longer.digits[i];
|
||||
}
|
||||
|
||||
TBigInteger result = new TBigInteger(1, resLength, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return sign = 0, magnitude = -val.magnitude ^ -that.magnitude */
|
||||
static TBigInteger xorNegative(TBigInteger val, TBigInteger that){
|
||||
// PRE: val and that are negative
|
||||
// PRE: val has at least as many trailing zero digits as that
|
||||
int resLength = Math.max(val.numberLength, that.numberLength);
|
||||
int resDigits[] = new int[resLength];
|
||||
int iVal = val.getFirstNonzeroDigit();
|
||||
int iThat = that.getFirstNonzeroDigit();
|
||||
int i = iThat;
|
||||
int limit;
|
||||
|
||||
|
||||
if (iVal == iThat) {
|
||||
resDigits[i] = -val.digits[i] ^ -that.digits[i];
|
||||
} else {
|
||||
resDigits[i] = -that.digits[i];
|
||||
limit = Math.min(that.numberLength, iVal);
|
||||
for (i++; i < limit; i++) {
|
||||
resDigits[i] = ~that.digits[i];
|
||||
}
|
||||
// Remains digits in that?
|
||||
if (i == that.numberLength) {
|
||||
//Jumping over the remaining zero to the first non one
|
||||
for ( ;i < iVal; i++) {
|
||||
//resDigits[i] = 0 ^ -1;
|
||||
resDigits[i] = -1;
|
||||
}
|
||||
//resDigits[i] = -val.digits[i] ^ -1;
|
||||
resDigits[i] = val.digits[i] - 1;
|
||||
} else {
|
||||
resDigits[i] = -val.digits[i] ^ ~that.digits[i];
|
||||
}
|
||||
}
|
||||
|
||||
limit = Math.min(val.numberLength, that.numberLength);
|
||||
//Perform ^ between that al val until that ends
|
||||
for (i++; i < limit; i++) {
|
||||
//resDigits[i] = ~val.digits[i] ^ ~that.digits[i];
|
||||
resDigits[i] = val.digits[i] ^ that.digits[i];
|
||||
}
|
||||
//Perform ^ between val digits and -1 until val ends
|
||||
for ( ; i < val.numberLength; i++) {
|
||||
//resDigits[i] = ~val.digits[i] ^ -1 ;
|
||||
resDigits[i] = val.digits[i] ;
|
||||
}
|
||||
for ( ; i < that.numberLength; i++) {
|
||||
//resDigits[i] = -1 ^ ~that.digits[i] ;
|
||||
resDigits[i] = that.digits[i];
|
||||
}
|
||||
|
||||
TBigInteger result = new TBigInteger(1, resLength, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @return sign = 1, magnitude = -(positive.magnitude ^ -negative.magnitude)*/
|
||||
static TBigInteger xorDiffSigns(TBigInteger positive, TBigInteger negative){
|
||||
int resLength = Math.max(negative.numberLength, positive.numberLength);
|
||||
int resDigits[];
|
||||
int iNeg = negative.getFirstNonzeroDigit();
|
||||
int iPos = positive.getFirstNonzeroDigit();
|
||||
int i;
|
||||
int limit;
|
||||
|
||||
//The first
|
||||
if (iNeg < iPos) {
|
||||
resDigits = new int[resLength];
|
||||
i = iNeg;
|
||||
//resDigits[i] = -(-negative.digits[i]);
|
||||
resDigits[i] = negative.digits[i];
|
||||
limit = Math.min(negative.numberLength, iPos);
|
||||
//Skip the positive digits while they are zeros
|
||||
for (i++; i < limit; i++) {
|
||||
//resDigits[i] = ~(~negative.digits[i]);
|
||||
resDigits[i] = negative.digits[i];
|
||||
}
|
||||
//if the negative has no more elements, must fill the
|
||||
//result with the remaining digits of the positive
|
||||
if (i == negative.numberLength) {
|
||||
for ( ; i < positive.numberLength; i++) {
|
||||
//resDigits[i] = ~(positive.digits[i] ^ -1) -> ~(~positive.digits[i])
|
||||
resDigits[i] = positive.digits[i];
|
||||
}
|
||||
}
|
||||
} else if (iPos < iNeg) {
|
||||
resDigits = new int[resLength];
|
||||
i = iPos;
|
||||
//Applying two complement to the first non-zero digit of the result
|
||||
resDigits[i] = -positive.digits[i];
|
||||
limit = Math.min(positive.numberLength, iNeg);
|
||||
for (i++; i < limit; i++) {
|
||||
//Continue applying two complement the result
|
||||
resDigits[i] = ~positive.digits[i];
|
||||
}
|
||||
//When the first non-zero digit of the negative is reached, must apply
|
||||
//two complement (arithmetic negation) to it, and then operate
|
||||
if (i == iNeg) {
|
||||
resDigits[i] = ~(positive.digits[i] ^ -negative.digits[i]);
|
||||
i++;
|
||||
} else {
|
||||
//if the positive has no more elements must fill the remaining digits with
|
||||
//the negative ones
|
||||
for ( ; i < iNeg; i++) {
|
||||
// resDigits[i] = ~(0 ^ 0)
|
||||
resDigits[i] = -1;
|
||||
}
|
||||
for ( ; i < negative.numberLength; i++) {
|
||||
//resDigits[i] = ~(~negative.digits[i] ^ 0)
|
||||
resDigits[i] = negative.digits[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int digit;
|
||||
//The first non-zero digit of the positive and negative are the same
|
||||
i = iNeg;
|
||||
digit = positive.digits[i] ^ -negative.digits[i];
|
||||
if (digit == 0) {
|
||||
limit = Math.min(positive.numberLength, negative.numberLength);
|
||||
for (i++; i < limit && (digit = positive.digits[i] ^ ~negative.digits[i]) == 0; i++) {
|
||||
// do nothing
|
||||
}
|
||||
if (digit == 0) {
|
||||
// shorter has only the remaining virtual sign bits
|
||||
for ( ; i < positive.numberLength && (digit = ~positive.digits[i]) == 0; i++) {
|
||||
// do nothing
|
||||
}
|
||||
for ( ; i < negative.numberLength && (digit = ~negative.digits[i]) == 0; i++) {
|
||||
// do nothing
|
||||
}
|
||||
if (digit == 0) {
|
||||
resLength = resLength + 1;
|
||||
resDigits = new int[resLength];
|
||||
resDigits[resLength - 1] = 1;
|
||||
|
||||
TBigInteger result = new TBigInteger(-1, resLength, resDigits);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
resDigits = new int[resLength];
|
||||
resDigits[i] = -digit;
|
||||
i++;
|
||||
}
|
||||
|
||||
limit = Math.min(negative.numberLength, positive.numberLength);
|
||||
for ( ; i < limit; i++) {
|
||||
resDigits[i] = ~(~negative.digits[i] ^ positive.digits[i]);
|
||||
}
|
||||
for ( ; i < positive.numberLength; i++) {
|
||||
// resDigits[i] = ~(positive.digits[i] ^ -1)
|
||||
resDigits[i] = positive.digits[i];
|
||||
}
|
||||
for ( ; i < negative.numberLength; i++) {
|
||||
// resDigits[i] = ~(0 ^ ~negative.digits[i])
|
||||
resDigits[i] = negative.digits[i];
|
||||
}
|
||||
|
||||
TBigInteger result = new TBigInteger(-1, resLength, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,290 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Immutable objects describing settings such as rounding mode and digit
|
||||
* precision for the numerical operations provided by class {@link TBigDecimal}.
|
||||
*/
|
||||
public final class TMathContext implements Serializable {
|
||||
|
||||
/**
|
||||
* A {@code MathContext} which corresponds to the IEEE 754r quadruple
|
||||
* decimal precision format: 34 digit precision and
|
||||
* {@link TRoundingMode#HALF_EVEN} rounding.
|
||||
*/
|
||||
public static final TMathContext DECIMAL128 = new TMathContext(34,
|
||||
TRoundingMode.HALF_EVEN);
|
||||
|
||||
/**
|
||||
* A {@code MathContext} which corresponds to the IEEE 754r single decimal
|
||||
* precision format: 7 digit precision and {@link TRoundingMode#HALF_EVEN}
|
||||
* rounding.
|
||||
*/
|
||||
public static final TMathContext DECIMAL32 = new TMathContext(7,
|
||||
TRoundingMode.HALF_EVEN);
|
||||
|
||||
/**
|
||||
* A {@code MathContext} which corresponds to the IEEE 754r double decimal
|
||||
* precision format: 16 digit precision and {@link TRoundingMode#HALF_EVEN}
|
||||
* rounding.
|
||||
*/
|
||||
public static final TMathContext DECIMAL64 = new TMathContext(16,
|
||||
TRoundingMode.HALF_EVEN);
|
||||
|
||||
/**
|
||||
* A {@code MathContext} for unlimited precision with
|
||||
* {@link TRoundingMode#HALF_UP} rounding.
|
||||
*/
|
||||
public static final TMathContext UNLIMITED = new TMathContext(0,
|
||||
TRoundingMode.HALF_UP);
|
||||
|
||||
/** This is the serialVersionUID used by the sun implementation */
|
||||
private static final long serialVersionUID = 5579720004786848255L;
|
||||
|
||||
/**
|
||||
* The number of digits to be used for an operation; results are rounded to
|
||||
* this precision.
|
||||
*/
|
||||
private int precision;
|
||||
|
||||
/**
|
||||
* A {@code RoundingMode} object which specifies the algorithm to be used
|
||||
* for rounding.
|
||||
*/
|
||||
private TRoundingMode roundingMode;
|
||||
|
||||
/**
|
||||
* An array of {@code char} containing: {@code
|
||||
* 'p','r','e','c','i','s','i','o','n','='}. It's used to improve the
|
||||
* methods related to {@code String} conversion.
|
||||
*
|
||||
* @see #MathContext(String)
|
||||
* @see #toString()
|
||||
*/
|
||||
private final static char[] chPrecision = { 'p', 'r', 'e', 'c', 'i', 's',
|
||||
'i', 'o', 'n', '=' };
|
||||
|
||||
/**
|
||||
* An array of {@code char} containing: {@code
|
||||
* 'r','o','u','n','d','i','n','g','M','o','d','e','='}. It's used to
|
||||
* improve the methods related to {@code String} conversion.
|
||||
*
|
||||
* @see #MathContext(String)
|
||||
* @see #toString()
|
||||
*/
|
||||
private final static char[] chRoundingMode = { 'r', 'o', 'u', 'n', 'd',
|
||||
'i', 'n', 'g', 'M', 'o', 'd', 'e', '=' };
|
||||
|
||||
/**
|
||||
* Constructs a new {@code MathContext} with the specified precision and
|
||||
* with the rounding mode {@link TRoundingMode#HALF_UP HALF_UP}. If the
|
||||
* precision passed is zero, then this implies that the computations have to
|
||||
* be performed exact, the rounding mode in this case is irrelevant.
|
||||
*
|
||||
* @param precision
|
||||
* the precision for the new {@code MathContext}.
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code precision < 0}.
|
||||
*/
|
||||
public TMathContext(int precision) {
|
||||
this(precision, TRoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code MathContext} with the specified precision and
|
||||
* with the specified rounding mode. If the precision passed is zero, then
|
||||
* this implies that the computations have to be performed exact, the
|
||||
* rounding mode in this case is irrelevant.
|
||||
*
|
||||
* @param precision
|
||||
* the precision for the new {@code MathContext}.
|
||||
* @param roundingMode
|
||||
* the rounding mode for the new {@code MathContext}.
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code precision < 0}.
|
||||
* @throws NullPointerException
|
||||
* if {@code roundingMode} is {@code null}.
|
||||
*/
|
||||
public TMathContext(int precision, TRoundingMode roundingMode) {
|
||||
if (precision < 0) {
|
||||
throw new IllegalArgumentException("Digits < 0");
|
||||
}
|
||||
if (roundingMode == null) {
|
||||
throw new NullPointerException("null RoundingMode");
|
||||
}
|
||||
this.precision = precision;
|
||||
this.roundingMode = roundingMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code MathContext} from a string. The string has to
|
||||
* specify the precision and the rounding mode to be used and has to follow
|
||||
* the following syntax: "precision=<precision> roundingMode=<roundingMode>"
|
||||
* This is the same form as the one returned by the {@link #toString}
|
||||
* method.
|
||||
*
|
||||
* @param val
|
||||
* a string describing the precision and rounding mode for the
|
||||
* new {@code MathContext}.
|
||||
* @throws IllegalArgumentException
|
||||
* if the string is not in the correct format or if the
|
||||
* precision specified is < 0.
|
||||
*/
|
||||
public TMathContext(String val) {
|
||||
char[] charVal = val.toCharArray();
|
||||
int i; // Index of charVal
|
||||
int j; // Index of chRoundingMode
|
||||
int digit; // It will contain the digit parsed
|
||||
|
||||
if ((charVal.length < 27) || (charVal.length > 45)) {
|
||||
throw new IllegalArgumentException("bad string format");
|
||||
}
|
||||
// Parsing "precision=" String
|
||||
for (i = 0; (i < chPrecision.length) && (charVal[i] == chPrecision[i]); i++) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
if (i < chPrecision.length) {
|
||||
throw new IllegalArgumentException("bad string format");
|
||||
}
|
||||
// Parsing the value for "precision="...
|
||||
digit = Character.digit(charVal[i], 10);
|
||||
if (digit == -1) {
|
||||
throw new IllegalArgumentException("bad string format");
|
||||
}
|
||||
this.precision = this.precision * 10 + digit;
|
||||
i++;
|
||||
|
||||
do {
|
||||
digit = Character.digit(charVal[i], 10);
|
||||
if (digit == -1) {
|
||||
if (charVal[i] == ' ') {
|
||||
// It parsed all the digits
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
// It isn't a valid digit, and isn't a white space
|
||||
throw new IllegalArgumentException("bad string format");
|
||||
}
|
||||
// Accumulating the value parsed
|
||||
this.precision = this.precision * 10 + digit;
|
||||
if (this.precision < 0) {
|
||||
throw new IllegalArgumentException("bad string format");
|
||||
}
|
||||
i++;
|
||||
} while (true);
|
||||
// Parsing "roundingMode="
|
||||
for (j = 0; (j < chRoundingMode.length) && (charVal[i] == chRoundingMode[j]); i++, j++) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
if (j < chRoundingMode.length) {
|
||||
throw new IllegalArgumentException("bad string format");
|
||||
}
|
||||
// Parsing the value for "roundingMode"...
|
||||
this.roundingMode = TRoundingMode.valueOf(String.valueOf(charVal, i, charVal.length - i));
|
||||
}
|
||||
|
||||
/* Public Methods */
|
||||
|
||||
/**
|
||||
* Returns the precision. The precision is the number of digits used for an
|
||||
* operation. Results are rounded to this precision. The precision is
|
||||
* guaranteed to be non negative. If the precision is zero, then the
|
||||
* computations have to be performed exact, results are not rounded in this
|
||||
* case.
|
||||
*
|
||||
* @return the precision.
|
||||
*/
|
||||
public int getPrecision() {
|
||||
return precision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rounding mode. The rounding mode is the strategy to be used
|
||||
* to round results.
|
||||
* <p>
|
||||
* The rounding mode is one of
|
||||
* {@link TRoundingMode#UP},
|
||||
* {@link TRoundingMode#DOWN},
|
||||
* {@link TRoundingMode#CEILING},
|
||||
* {@link TRoundingMode#FLOOR},
|
||||
* {@link TRoundingMode#HALF_UP},
|
||||
* {@link TRoundingMode#HALF_DOWN},
|
||||
* {@link TRoundingMode#HALF_EVEN}, or
|
||||
* {@link TRoundingMode#UNNECESSARY}.
|
||||
*
|
||||
* @return the rounding mode.
|
||||
*/
|
||||
public TRoundingMode getRoundingMode() {
|
||||
return roundingMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if x is a {@code MathContext} with the same precision
|
||||
* setting and the same rounding mode as this {@code MathContext} instance.
|
||||
*
|
||||
* @param x
|
||||
* object to be compared.
|
||||
* @return {@code true} if this {@code MathContext} instance is equal to the
|
||||
* {@code x} argument; {@code false} otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object x) {
|
||||
return ((x instanceof TMathContext)
|
||||
&& (((TMathContext) x).getPrecision() == precision) && (((TMathContext) x)
|
||||
.getRoundingMode() == roundingMode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code for this {@code MathContext} instance.
|
||||
*
|
||||
* @return the hash code for this {@code MathContext}.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
// Make place for the necessary bits to represent 8 rounding modes
|
||||
return ((precision << 3) | roundingMode.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string representation for this {@code MathContext} instance.
|
||||
* The string has the form
|
||||
* {@code
|
||||
* "precision=<precision> roundingMode=<roundingMode>"
|
||||
* } where {@code <precision>} is an integer describing the number
|
||||
* of digits used for operations and {@code <roundingMode>} is the
|
||||
* string representation of the rounding mode.
|
||||
*
|
||||
* @return a string representation for this {@code MathContext} instance
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder(45);
|
||||
|
||||
sb.append(chPrecision);
|
||||
sb.append(precision);
|
||||
sb.append(' ');
|
||||
sb.append(chRoundingMode);
|
||||
sb.append(roundingMode);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,510 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
/**
|
||||
* Static library that provides all multiplication of {@link TBigInteger} methods.
|
||||
*/
|
||||
class TMultiplication {
|
||||
|
||||
/** Just to denote that this class can't be instantiated. */
|
||||
private TMultiplication() {}
|
||||
|
||||
/**
|
||||
* Break point in digits (number of {@code int} elements)
|
||||
* between Karatsuba and Pencil and Paper multiply.
|
||||
*/
|
||||
static final int whenUseKaratsuba = 63; // an heuristic value
|
||||
|
||||
/**
|
||||
* An array with powers of ten that fit in the type {@code int}.
|
||||
* ({@code 10^0,10^1,...,10^9})
|
||||
*/
|
||||
static final int tenPows[] = {
|
||||
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
|
||||
};
|
||||
|
||||
/**
|
||||
* An array with powers of five that fit in the type {@code int}.
|
||||
* ({@code 5^0,5^1,...,5^13})
|
||||
*/
|
||||
static final int fivePows[] = {
|
||||
1, 5, 25, 125, 625, 3125, 15625, 78125, 390625,
|
||||
1953125, 9765625, 48828125, 244140625, 1220703125
|
||||
};
|
||||
|
||||
/**
|
||||
* An array with the first powers of ten in {@code BigInteger} version.
|
||||
* ({@code 10^0,10^1,...,10^31})
|
||||
*/
|
||||
static final TBigInteger[] bigTenPows = new TBigInteger[32];
|
||||
|
||||
/**
|
||||
* An array with the first powers of five in {@code BigInteger} version.
|
||||
* ({@code 5^0,5^1,...,5^31})
|
||||
*/
|
||||
static final TBigInteger bigFivePows[] = new TBigInteger[32];
|
||||
|
||||
|
||||
|
||||
static {
|
||||
int i;
|
||||
long fivePow = 1L;
|
||||
|
||||
for (i = 0; i <= 18; i++) {
|
||||
bigFivePows[i] = TBigInteger.valueOf(fivePow);
|
||||
bigTenPows[i] = TBigInteger.valueOf(fivePow << i);
|
||||
fivePow *= 5;
|
||||
}
|
||||
for (; i < bigTenPows.length; i++) {
|
||||
bigFivePows[i] = bigFivePows[i - 1].multiply(bigFivePows[1]);
|
||||
bigTenPows[i] = bigTenPows[i - 1].multiply(TBigInteger.TEN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a multiplication of two BigInteger and hides the algorithm used.
|
||||
* @see TBigInteger#multiply(TBigInteger)
|
||||
*/
|
||||
static TBigInteger multiply(TBigInteger x, TBigInteger y) {
|
||||
return karatsuba(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the multiplication with the Karatsuba's algorithm.
|
||||
* <b>Karatsuba's algorithm:</b>
|
||||
*<tt>
|
||||
* u = u<sub>1</sub> * B + u<sub>0</sub><br>
|
||||
* v = v<sub>1</sub> * B + v<sub>0</sub><br>
|
||||
*
|
||||
*
|
||||
* u*v = (u<sub>1</sub> * v<sub>1</sub>) * B<sub>2</sub> + ((u<sub>1</sub> - u<sub>0</sub>) * (v<sub>0</sub> - v<sub>1</sub>) + u<sub>1</sub> * v<sub>1</sub> +
|
||||
* u<sub>0</sub> * v<sub>0</sub> ) * B + u<sub>0</sub> * v<sub>0</sub><br>
|
||||
*</tt>
|
||||
* @param op1 first factor of the product
|
||||
* @param op2 second factor of the product
|
||||
* @return {@code op1 * op2}
|
||||
* @see #multiply(TBigInteger, TBigInteger)
|
||||
*/
|
||||
static TBigInteger karatsuba(TBigInteger op1, TBigInteger op2) {
|
||||
TBigInteger temp;
|
||||
if (op2.numberLength > op1.numberLength) {
|
||||
temp = op1;
|
||||
op1 = op2;
|
||||
op2 = temp;
|
||||
}
|
||||
if (op2.numberLength < whenUseKaratsuba) {
|
||||
return multiplyPAP(op1, op2);
|
||||
}
|
||||
/* Karatsuba: u = u1*B + u0
|
||||
* v = v1*B + v0
|
||||
* u*v = (u1*v1)*B^2 + ((u1-u0)*(v0-v1) + u1*v1 + u0*v0)*B + u0*v0
|
||||
*/
|
||||
// ndiv2 = (op1.numberLength / 2) * 32
|
||||
int ndiv2 = (op1.numberLength & 0xFFFFFFFE) << 4;
|
||||
TBigInteger upperOp1 = op1.shiftRight(ndiv2);
|
||||
TBigInteger upperOp2 = op2.shiftRight(ndiv2);
|
||||
TBigInteger lowerOp1 = op1.subtract(upperOp1.shiftLeft(ndiv2));
|
||||
TBigInteger lowerOp2 = op2.subtract(upperOp2.shiftLeft(ndiv2));
|
||||
|
||||
TBigInteger upper = karatsuba(upperOp1, upperOp2);
|
||||
TBigInteger lower = karatsuba(lowerOp1, lowerOp2);
|
||||
TBigInteger middle = karatsuba( upperOp1.subtract(lowerOp1),
|
||||
lowerOp2.subtract(upperOp2));
|
||||
middle = middle.add(upper).add(lower);
|
||||
middle = middle.shiftLeft(ndiv2);
|
||||
upper = upper.shiftLeft(ndiv2 << 1);
|
||||
|
||||
return upper.add(middle).add(lower);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies two BigIntegers.
|
||||
* Implements traditional scholar algorithm described by Knuth.
|
||||
*
|
||||
* <br><tt>
|
||||
* <table border="0">
|
||||
* <tbody>
|
||||
*
|
||||
*
|
||||
* <tr>
|
||||
* <td align="center">A=</td>
|
||||
* <td>a<sub>3</sub></td>
|
||||
* <td>a<sub>2</sub></td>
|
||||
* <td>a<sub>1</sub></td>
|
||||
* <td>a<sub>0</sub></td>
|
||||
* <td></td>
|
||||
* <td></td>
|
||||
* </tr>
|
||||
*
|
||||
*<tr>
|
||||
* <td align="center">B=</td>
|
||||
* <td></td>
|
||||
* <td>b<sub>2</sub></td>
|
||||
* <td>b<sub>1</sub></td>
|
||||
* <td>b<sub>1</sub></td>
|
||||
* <td></td>
|
||||
* <td></td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td></td>
|
||||
* <td></td>
|
||||
* <td></td>
|
||||
* <td>b<sub>0</sub>*a<sub>3</sub></td>
|
||||
* <td>b<sub>0</sub>*a<sub>2</sub></td>
|
||||
* <td>b<sub>0</sub>*a<sub>1</sub></td>
|
||||
* <td>b<sub>0</sub>*a<sub>0</sub></td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td></td>
|
||||
* <td></td>
|
||||
* <td>b<sub>1</sub>*a<sub>3</sub></td>
|
||||
* <td>b<sub>1</sub>*a<sub>2</sub></td>
|
||||
* <td>b<sub>1</sub>*a1</td>
|
||||
* <td>b<sub>1</sub>*a0</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td>+</td>
|
||||
* <td>b<sub>2</sub>*a<sub>3</sub></td>
|
||||
* <td>b<sub>2</sub>*a<sub>2</sub></td>
|
||||
* <td>b<sub>2</sub>*a<sub>1</sub></td>
|
||||
* <td>b<sub>2</sub>*a<sub>0</sub></td>
|
||||
* </tr>
|
||||
*
|
||||
*<tr>
|
||||
* <td></td>
|
||||
*<td>______</td>
|
||||
* <td>______</td>
|
||||
* <td>______</td>
|
||||
* <td>______</td>
|
||||
* <td>______</td>
|
||||
* <td>______</td>
|
||||
*</tr>
|
||||
*
|
||||
* <tr>
|
||||
*
|
||||
* <td align="center">A*B=R=</td>
|
||||
* <td align="center">r<sub>5</sub></td>
|
||||
* <td align="center">r<sub>4</sub></td>
|
||||
* <td align="center">r<sub>3</sub></td>
|
||||
* <td align="center">r<sub>2</sub></td>
|
||||
* <td align="center">r<sub>1</sub></td>
|
||||
* <td align="center">r<sub>0</sub></td>
|
||||
* <td></td>
|
||||
* </tr>
|
||||
*
|
||||
* </tbody>
|
||||
* </table>
|
||||
*
|
||||
*</tt>
|
||||
*
|
||||
* @param op1 first factor of the multiplication {@code op1 >= 0}
|
||||
* @param op2 second factor of the multiplication {@code op2 >= 0}
|
||||
* @return a {@code BigInteger} of value {@code op1 * op2}
|
||||
*/
|
||||
static TBigInteger multiplyPAP(TBigInteger a, TBigInteger b) {
|
||||
// PRE: a >= b
|
||||
int aLen = a.numberLength;
|
||||
int bLen = b.numberLength;
|
||||
int resLength = aLen + bLen;
|
||||
int resSign = (a.sign != b.sign) ? -1 : 1;
|
||||
// A special case when both numbers don't exceed int
|
||||
if (resLength == 2) {
|
||||
long val = unsignedMultAddAdd(a.digits[0], b.digits[0], 0, 0);
|
||||
int valueLo = (int)val;
|
||||
int valueHi = (int)(val >>> 32);
|
||||
return ((valueHi == 0)
|
||||
? new TBigInteger(resSign, valueLo)
|
||||
: new TBigInteger(resSign, 2, new int[]{valueLo, valueHi}));
|
||||
}
|
||||
int[] aDigits = a.digits;
|
||||
int[] bDigits = b.digits;
|
||||
int resDigits[] = new int[resLength];
|
||||
// Common case
|
||||
multArraysPAP(aDigits, aLen, bDigits, bLen, resDigits);
|
||||
TBigInteger result = new TBigInteger(resSign, resLength, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
|
||||
static void multArraysPAP(int[] aDigits, int aLen, int[] bDigits, int bLen, int[] resDigits) {
|
||||
if(aLen == 0 || bLen == 0) return;
|
||||
|
||||
if(aLen == 1) {
|
||||
resDigits[bLen] = multiplyByInt(resDigits, bDigits, bLen, aDigits[0]);
|
||||
} else if(bLen == 1) {
|
||||
resDigits[aLen] = multiplyByInt(resDigits, aDigits, aLen, bDigits[0]);
|
||||
} else {
|
||||
multPAP(aDigits, bDigits, resDigits, aLen, bLen);
|
||||
}
|
||||
}
|
||||
|
||||
static void multPAP(int a[], int b[], int t[], int aLen, int bLen) {
|
||||
if(a == b && aLen == bLen) {
|
||||
square(a, aLen, t);
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < aLen; i++){
|
||||
long carry = 0;
|
||||
int aI = a[i];
|
||||
for (int j = 0; j < bLen; j++){
|
||||
carry = unsignedMultAddAdd(aI, b[j], t[i+j], (int)carry);
|
||||
t[i+j] = (int) carry;
|
||||
carry >>>= 32;
|
||||
}
|
||||
t[i+bLen] = (int) carry;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies an array of integers by an integer value
|
||||
* and saves the result in {@code res}.
|
||||
* @param a the array of integers
|
||||
* @param aSize the number of elements of intArray to be multiplied
|
||||
* @param factor the multiplier
|
||||
* @return the top digit of production
|
||||
*/
|
||||
private static int multiplyByInt(int res[], int a[], final int aSize, final int factor) {
|
||||
long carry = 0;
|
||||
for (int i = 0; i < aSize; i++) {
|
||||
carry = unsignedMultAddAdd(a[i], factor, (int)carry, 0);
|
||||
res[i] = (int)carry;
|
||||
carry >>>= 32;
|
||||
}
|
||||
return (int)carry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Multiplies an array of integers by an integer value.
|
||||
* @param a the array of integers
|
||||
* @param aSize the number of elements of intArray to be multiplied
|
||||
* @param factor the multiplier
|
||||
* @return the top digit of production
|
||||
*/
|
||||
static int multiplyByInt(int a[], final int aSize, final int factor) {
|
||||
return multiplyByInt(a, a, aSize, factor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies a number by a positive integer.
|
||||
* @param val an arbitrary {@code BigInteger}
|
||||
* @param factor a positive {@code int} number
|
||||
* @return {@code val * factor}
|
||||
*/
|
||||
static TBigInteger multiplyByPositiveInt(TBigInteger val, int factor) {
|
||||
int resSign = val.sign;
|
||||
if (resSign == 0) {
|
||||
return TBigInteger.ZERO;
|
||||
}
|
||||
int aNumberLength = val.numberLength;
|
||||
int[] aDigits = val.digits;
|
||||
|
||||
if (aNumberLength == 1) {
|
||||
long res = unsignedMultAddAdd(aDigits[0], factor, 0, 0);
|
||||
int resLo = (int)res;
|
||||
int resHi = (int)(res >>> 32);
|
||||
return ((resHi == 0)
|
||||
? new TBigInteger(resSign, resLo)
|
||||
: new TBigInteger(resSign, 2, new int[]{resLo, resHi}));
|
||||
}
|
||||
// Common case
|
||||
int resLength = aNumberLength + 1;
|
||||
int resDigits[] = new int[resLength];
|
||||
|
||||
resDigits[aNumberLength] = multiplyByInt(resDigits, aDigits, aNumberLength, factor);
|
||||
TBigInteger result = new TBigInteger(resSign, resLength, resDigits);
|
||||
result.cutOffLeadingZeroes();
|
||||
return result;
|
||||
}
|
||||
|
||||
static TBigInteger pow(TBigInteger base, int exponent) {
|
||||
// PRE: exp > 0
|
||||
TBigInteger res = TBigInteger.ONE;
|
||||
TBigInteger acc = base;
|
||||
|
||||
for (; exponent > 1; exponent >>= 1) {
|
||||
if ((exponent & 1) != 0) {
|
||||
// if odd, multiply one more time by acc
|
||||
res = res.multiply(acc);
|
||||
}
|
||||
// acc = base^(2^i)
|
||||
//a limit where karatsuba performs a faster square than the square algorithm
|
||||
if ( acc.numberLength == 1 ){
|
||||
acc = acc.multiply(acc); // square
|
||||
}
|
||||
else{
|
||||
acc = new TBigInteger(1, square(acc.digits, acc.numberLength, new int [acc.numberLength<<1]));
|
||||
}
|
||||
}
|
||||
// exponent == 1, multiply one more time
|
||||
res = res.multiply(acc);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a<sup>2</sup>
|
||||
* @param a The number to square.
|
||||
* @param aLen The length of the number to square.
|
||||
*/
|
||||
static int[] square(int[] a, int aLen, int[] res) {
|
||||
long carry;
|
||||
|
||||
for(int i = 0; i < aLen; i++){
|
||||
carry = 0;
|
||||
for (int j = i+1; j < aLen; j++){
|
||||
carry = unsignedMultAddAdd(a[i], a[j], res[i+j], (int)carry);
|
||||
res[i+j] = (int) carry;
|
||||
carry >>>= 32;
|
||||
}
|
||||
res[i+aLen] = (int) carry;
|
||||
}
|
||||
|
||||
TBitLevel.shiftLeftOneBit(res, res, aLen << 1);
|
||||
|
||||
carry = 0;
|
||||
for(int i = 0, index = 0; i < aLen; i++, index++){
|
||||
carry = unsignedMultAddAdd(a[i], a[i], res[index],(int)carry);
|
||||
res[index] = (int) carry;
|
||||
carry >>>= 32;
|
||||
index++;
|
||||
carry += res[index] & 0xFFFFFFFFL;
|
||||
res[index] = (int)carry;
|
||||
carry >>>= 32;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies a number by a power of ten.
|
||||
* This method is used in {@code BigDecimal} class.
|
||||
* @param val the number to be multiplied
|
||||
* @param exp a positive {@code long} exponent
|
||||
* @return {@code val * 10<sup>exp</sup>}
|
||||
*/
|
||||
static TBigInteger multiplyByTenPow(TBigInteger val, long exp) {
|
||||
// PRE: exp >= 0
|
||||
return ((exp < tenPows.length)
|
||||
? multiplyByPositiveInt(val, tenPows[(int)exp])
|
||||
: val.multiply(powerOf10(exp)));
|
||||
}
|
||||
|
||||
/**
|
||||
* It calculates a power of ten, which exponent could be out of 32-bit range.
|
||||
* Note that internally this method will be used in the worst case with
|
||||
* an exponent equals to: {@code Integer.MAX_VALUE - Integer.MIN_VALUE}.
|
||||
* @param exp the exponent of power of ten, it must be positive.
|
||||
* @return a {@code BigInteger} with value {@code 10<sup>exp</sup>}.
|
||||
*/
|
||||
static TBigInteger powerOf10(long exp) {
|
||||
// PRE: exp >= 0
|
||||
int intExp = (int)exp;
|
||||
// "SMALL POWERS"
|
||||
if (exp < bigTenPows.length) {
|
||||
// The largest power that fit in 'long' type
|
||||
return bigTenPows[intExp];
|
||||
} else if (exp <= 50) {
|
||||
// To calculate: 10^exp
|
||||
return TBigInteger.TEN.pow(intExp);
|
||||
} else if (exp <= 1000) {
|
||||
// To calculate: 5^exp * 2^exp
|
||||
return bigFivePows[1].pow(intExp).shiftLeft(intExp);
|
||||
}
|
||||
// "LARGE POWERS"
|
||||
/*
|
||||
* To check if there is free memory to allocate a BigInteger of the
|
||||
* estimated size, measured in bytes: 1 + [exp / log10(2)]
|
||||
*/
|
||||
long byteArraySize = 1 + (long)(exp / 2.4082399653118496);
|
||||
|
||||
if (byteArraySize > 1000000) {
|
||||
throw new ArithmeticException("power of ten too big");
|
||||
}
|
||||
if (exp <= Integer.MAX_VALUE) {
|
||||
// To calculate: 5^exp * 2^exp
|
||||
return bigFivePows[1].pow(intExp).shiftLeft(intExp);
|
||||
}
|
||||
/*
|
||||
* "HUGE POWERS"
|
||||
*
|
||||
* This branch probably won't be executed since the power of ten is too
|
||||
* big.
|
||||
*/
|
||||
// To calculate: 5^exp
|
||||
TBigInteger powerOfFive = bigFivePows[1].pow(Integer.MAX_VALUE);
|
||||
TBigInteger res = powerOfFive;
|
||||
long longExp = exp - Integer.MAX_VALUE;
|
||||
|
||||
intExp = (int)(exp % Integer.MAX_VALUE);
|
||||
while (longExp > Integer.MAX_VALUE) {
|
||||
res = res.multiply(powerOfFive);
|
||||
longExp -= Integer.MAX_VALUE;
|
||||
}
|
||||
res = res.multiply(bigFivePows[1].pow(intExp));
|
||||
// To calculate: 5^exp << exp
|
||||
res = res.shiftLeft(Integer.MAX_VALUE);
|
||||
longExp = exp - Integer.MAX_VALUE;
|
||||
while (longExp > Integer.MAX_VALUE) {
|
||||
res = res.shiftLeft(Integer.MAX_VALUE);
|
||||
longExp -= Integer.MAX_VALUE;
|
||||
}
|
||||
res = res.shiftLeft(intExp);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies a number by a power of five.
|
||||
* This method is used in {@code BigDecimal} class.
|
||||
* @param val the number to be multiplied
|
||||
* @param exp a positive {@code int} exponent
|
||||
* @return {@code val * 5<sup>exp</sup>}
|
||||
*/
|
||||
static TBigInteger multiplyByFivePow(TBigInteger val, int exp) {
|
||||
// PRE: exp >= 0
|
||||
if (exp < fivePows.length) {
|
||||
return multiplyByPositiveInt(val, fivePows[exp]);
|
||||
} else if (exp < bigFivePows.length) {
|
||||
return val.multiply(bigFivePows[exp]);
|
||||
} else {// Large powers of five
|
||||
return val.multiply(bigFivePows[1].pow(exp));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the value unsigned ((uint)a*(uint)b + (uint)c + (uint)d). This
|
||||
* method could improve the readability and performance of the code.
|
||||
*
|
||||
* @param a
|
||||
* parameter 1
|
||||
* @param b
|
||||
* parameter 2
|
||||
* @param c
|
||||
* parameter 3
|
||||
* @param d
|
||||
* parameter 4
|
||||
* @return value of expression
|
||||
*/
|
||||
static long unsignedMultAddAdd(int a, int b, int c, int d) {
|
||||
return (a & 0xFFFFFFFFL) * (b & 0xFFFFFFFFL) + (c & 0xFFFFFFFFL) + (d & 0xFFFFFFFFL);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,279 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Provides primality probabilistic methods.
|
||||
*/
|
||||
class TPrimality {
|
||||
|
||||
/** Just to denote that this class can't be instantiated. */
|
||||
private TPrimality() {}
|
||||
|
||||
/** All prime numbers with bit length lesser than 10 bits. */
|
||||
private static final int primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
|
||||
31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
|
||||
103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167,
|
||||
173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239,
|
||||
241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313,
|
||||
317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397,
|
||||
401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467,
|
||||
479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569,
|
||||
571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643,
|
||||
647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
|
||||
739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823,
|
||||
827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
|
||||
919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009,
|
||||
1013, 1019, 1021 };
|
||||
|
||||
/** All {@code BigInteger} prime numbers with bit length lesser than 8 bits. */
|
||||
private static final TBigInteger BIprimes[] = new TBigInteger[primes.length];
|
||||
|
||||
/**
|
||||
* It encodes how many iterations of Miller-Rabin test are need to get an
|
||||
* error bound not greater than {@code 2<sup>(-100)</sup>}. For example:
|
||||
* for a {@code 1000}-bit number we need {@code 4} iterations, since
|
||||
* {@code BITS[3] < 1000 <= BITS[4]}.
|
||||
*/
|
||||
private static final int[] BITS = { 0, 0, 1854, 1233, 927, 747, 627, 543,
|
||||
480, 431, 393, 361, 335, 314, 295, 279, 265, 253, 242, 232, 223,
|
||||
216, 181, 169, 158, 150, 145, 140, 136, 132, 127, 123, 119, 114,
|
||||
110, 105, 101, 96, 92, 87, 83, 78, 73, 69, 64, 59, 54, 49, 44, 38,
|
||||
32, 26, 1 };
|
||||
|
||||
/**
|
||||
* It encodes how many i-bit primes there are in the table for
|
||||
* {@code i=2,...,10}. For example {@code offsetPrimes[6]} says that from
|
||||
* index {@code 11} exists {@code 7} consecutive {@code 6}-bit prime
|
||||
* numbers in the array.
|
||||
*/
|
||||
private static final int[][] offsetPrimes = { null, null, { 0, 2 },
|
||||
{ 2, 2 }, { 4, 2 }, { 6, 5 }, { 11, 7 }, { 18, 13 }, { 31, 23 },
|
||||
{ 54, 43 }, { 97, 75 } };
|
||||
|
||||
static {// To initialize the dual table of BigInteger primes
|
||||
for (int i = 0; i < primes.length; i++) {
|
||||
BIprimes[i] = TBigInteger.valueOf(primes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It uses the sieve of Eratosthenes to discard several composite numbers in
|
||||
* some appropriate range (at the moment {@code [this, this + 1024]}). After
|
||||
* this process it applies the Miller-Rabin test to the numbers that were
|
||||
* not discarded in the sieve.
|
||||
*
|
||||
* @see TBigInteger#nextProbablePrime()
|
||||
* @see #millerRabin(TBigInteger, int)
|
||||
*/
|
||||
static TBigInteger nextProbablePrime(TBigInteger n) {
|
||||
// PRE: n >= 0
|
||||
int i, j;
|
||||
int certainty;
|
||||
int gapSize = 1024; // for searching of the next probable prime number
|
||||
int modules[] = new int[primes.length];
|
||||
boolean isDivisible[] = new boolean[gapSize];
|
||||
TBigInteger startPoint;
|
||||
TBigInteger probPrime;
|
||||
// If n < "last prime of table" searches next prime in the table
|
||||
if ((n.numberLength == 1) && (n.digits[0] >= 0)
|
||||
&& (n.digits[0] < primes[primes.length - 1])) {
|
||||
for (i = 0; n.digits[0] >= primes[i]; i++) {
|
||||
// do nothing
|
||||
}
|
||||
return BIprimes[i];
|
||||
}
|
||||
/*
|
||||
* Creates a "N" enough big to hold the next probable prime Note that: N <
|
||||
* "next prime" < 2*N
|
||||
*/
|
||||
startPoint = new TBigInteger(1, n.numberLength,
|
||||
new int[n.numberLength + 1]);
|
||||
System.arraycopy(n.digits, 0, startPoint.digits, 0, n.numberLength);
|
||||
// To fix N to the "next odd number"
|
||||
if (n.testBit(0)) {
|
||||
TElementary.inplaceAdd(startPoint, 2);
|
||||
} else {
|
||||
startPoint.digits[0] |= 1;
|
||||
}
|
||||
// To set the improved certainly of Miller-Rabin
|
||||
j = startPoint.bitLength();
|
||||
for (certainty = 2; j < BITS[certainty]; certainty++) {
|
||||
// do nothing
|
||||
}
|
||||
// To calculate modules: N mod p1, N mod p2, ... for first primes.
|
||||
for (i = 0; i < primes.length; i++) {
|
||||
modules[i] = TDivision.remainder(startPoint, primes[i]) - gapSize;
|
||||
}
|
||||
while (true) {
|
||||
// At this point, all numbers in the gap are initialized as
|
||||
// probably primes
|
||||
Arrays.fill(isDivisible, false);
|
||||
// To discard multiples of first primes
|
||||
for (i = 0; i < primes.length; i++) {
|
||||
modules[i] = (modules[i] + gapSize) % primes[i];
|
||||
j = (modules[i] == 0) ? 0 : (primes[i] - modules[i]);
|
||||
for (; j < gapSize; j += primes[i]) {
|
||||
isDivisible[j] = true;
|
||||
}
|
||||
}
|
||||
// To execute Miller-Rabin for non-divisible numbers by all first
|
||||
// primes
|
||||
for (j = 0; j < gapSize; j++) {
|
||||
if (!isDivisible[j]) {
|
||||
probPrime = startPoint.copy();
|
||||
TElementary.inplaceAdd(probPrime, j);
|
||||
|
||||
if (millerRabin(probPrime, certainty)) {
|
||||
return probPrime;
|
||||
}
|
||||
}
|
||||
}
|
||||
TElementary.inplaceAdd(startPoint, gapSize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A random number is generated until a probable prime number is found.
|
||||
*
|
||||
* @see TBigInteger#BigInteger(int,int,Random)
|
||||
* @see TBigInteger#probablePrime(int,Random)
|
||||
* @see #isProbablePrime(TBigInteger, int)
|
||||
*/
|
||||
static TBigInteger consBigInteger(int bitLength, int certainty, Random rnd) {
|
||||
// PRE: bitLength >= 2;
|
||||
// For small numbers get a random prime from the prime table
|
||||
if (bitLength <= 10) {
|
||||
int rp[] = offsetPrimes[bitLength];
|
||||
return BIprimes[rp[0] + rnd.nextInt(rp[1])];
|
||||
}
|
||||
int shiftCount = (-bitLength) & 31;
|
||||
int last = (bitLength + 31) >> 5;
|
||||
TBigInteger n = new TBigInteger(1, last, new int[last]);
|
||||
|
||||
last--;
|
||||
do {// To fill the array with random integers
|
||||
for (int i = 0; i < n.numberLength; i++) {
|
||||
n.digits[i] = rnd.nextInt();
|
||||
}
|
||||
// To fix to the correct bitLength
|
||||
n.digits[last] |= 0x80000000;
|
||||
n.digits[last] >>>= shiftCount;
|
||||
// To create an odd number
|
||||
n.digits[0] |= 1;
|
||||
} while (!isProbablePrime(n, certainty));
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see TBigInteger#isProbablePrime(int)
|
||||
* @see #millerRabin(TBigInteger, int)
|
||||
* @ar.org.fitc.ref Optimizations: "A. Menezes - Handbook of applied
|
||||
* Cryptography, Chapter 4".
|
||||
*/
|
||||
static boolean isProbablePrime(TBigInteger n, int certainty) {
|
||||
// PRE: n >= 0;
|
||||
if ((certainty <= 0) || ((n.numberLength == 1) && (n.digits[0] == 2))) {
|
||||
return true;
|
||||
}
|
||||
// To discard all even numbers
|
||||
if (!n.testBit(0)) {
|
||||
return false;
|
||||
}
|
||||
// To check if 'n' exists in the table (it fit in 10 bits)
|
||||
if ((n.numberLength == 1) && ((n.digits[0] & 0XFFFFFC00) == 0)) {
|
||||
return (Arrays.binarySearch(primes, n.digits[0]) >= 0);
|
||||
}
|
||||
// To check if 'n' is divisible by some prime of the table
|
||||
for (int i = 1; i < primes.length; i++) {
|
||||
if (TDivision.remainderArrayByInt(n.digits, n.numberLength,
|
||||
primes[i]) == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// To set the number of iterations necessary for Miller-Rabin test
|
||||
int i;
|
||||
int bitLength = n.bitLength();
|
||||
|
||||
for (i = 2; bitLength < BITS[i]; i++) {
|
||||
// do nothing
|
||||
}
|
||||
certainty = Math.min(i, 1 + ((certainty - 1) >> 1));
|
||||
|
||||
return millerRabin(n, certainty);
|
||||
}
|
||||
|
||||
/**
|
||||
* The Miller-Rabin primality test.
|
||||
*
|
||||
* @param n the input number to be tested.
|
||||
* @param t the number of trials.
|
||||
* @return {@code false} if the number is definitely compose, otherwise
|
||||
* {@code true} with probability {@code 1 - 4<sup>(-t)</sup>}.
|
||||
* @ar.org.fitc.ref "D. Knuth, The Art of Computer Programming Vo.2, Section
|
||||
* 4.5.4., Algorithm P"
|
||||
*/
|
||||
private static boolean millerRabin(TBigInteger n, int t) {
|
||||
// PRE: n >= 0, t >= 0
|
||||
TBigInteger x; // x := UNIFORM{2...n-1}
|
||||
TBigInteger y; // y := x^(q * 2^j) mod n
|
||||
TBigInteger n_minus_1 = n.subtract(TBigInteger.ONE); // n-1
|
||||
int bitLength = n_minus_1.bitLength(); // ~ log2(n-1)
|
||||
// (q,k) such that: n-1 = q * 2^k and q is odd
|
||||
int k = n_minus_1.getLowestSetBit();
|
||||
TBigInteger q = n_minus_1.shiftRight(k);
|
||||
Random rnd = new Random();
|
||||
|
||||
for (int i = 0; i < t; i++) {
|
||||
// To generate a witness 'x', first it use the primes of table
|
||||
if (i < primes.length) {
|
||||
x = BIprimes[i];
|
||||
} else {/*
|
||||
* It generates random witness only if it's necesssary. Note
|
||||
* that all methods would call Miller-Rabin with t <= 50 so
|
||||
* this part is only to do more robust the algorithm
|
||||
*/
|
||||
do {
|
||||
x = new TBigInteger(bitLength, rnd);
|
||||
} while ((x.compareTo(n) >= TBigInteger.EQUALS) || (x.sign == 0)
|
||||
|| x.isOne());
|
||||
}
|
||||
y = x.modPow(q, n);
|
||||
if (y.isOne() || y.equals(n_minus_1)) {
|
||||
continue;
|
||||
}
|
||||
for (int j = 1; j < k; j++) {
|
||||
if (y.equals(n_minus_1)) {
|
||||
continue;
|
||||
}
|
||||
y = y.multiply(y).mod(n);
|
||||
if (y.isOne()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!y.equals(n_minus_1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
/**
|
||||
* Specifies the rounding behavior for operations whose results cannot be
|
||||
* represented exactly.
|
||||
*/
|
||||
public enum TRoundingMode {
|
||||
|
||||
/**
|
||||
* Rounding mode where positive values are rounded towards positive infinity
|
||||
* and negative values towards negative infinity.
|
||||
* <br>
|
||||
* Rule: {@code x.round().abs() >= x.abs()}
|
||||
*/
|
||||
UP(TBigDecimal.ROUND_UP),
|
||||
|
||||
/**
|
||||
* Rounding mode where the values are rounded towards zero.
|
||||
* <br>
|
||||
* Rule: {@code x.round().abs() <= x.abs()}
|
||||
*/
|
||||
DOWN(TBigDecimal.ROUND_DOWN),
|
||||
|
||||
/**
|
||||
* Rounding mode to round towards positive infinity. For positive values
|
||||
* this rounding mode behaves as {@link #UP}, for negative values as
|
||||
* {@link #DOWN}.
|
||||
* <br>
|
||||
* Rule: {@code x.round() >= x}
|
||||
*/
|
||||
CEILING(TBigDecimal.ROUND_CEILING),
|
||||
|
||||
/**
|
||||
* Rounding mode to round towards negative infinity. For positive values
|
||||
* this rounding mode behaves as {@link #DOWN}, for negative values as
|
||||
* {@link #UP}.
|
||||
* <br>
|
||||
* Rule: {@code x.round() <= x}
|
||||
*/
|
||||
FLOOR(TBigDecimal.ROUND_FLOOR),
|
||||
|
||||
/**
|
||||
* Rounding mode where values are rounded towards the nearest neighbor. Ties
|
||||
* are broken by rounding up.
|
||||
*/
|
||||
HALF_UP(TBigDecimal.ROUND_HALF_UP),
|
||||
|
||||
/**
|
||||
* Rounding mode where values are rounded towards the nearest neighbor. Ties
|
||||
* are broken by rounding down.
|
||||
*/
|
||||
HALF_DOWN(TBigDecimal.ROUND_HALF_DOWN),
|
||||
|
||||
/**
|
||||
* Rounding mode where values are rounded towards the nearest neighbor. Ties
|
||||
* are broken by rounding to the even neighbor.
|
||||
*/
|
||||
HALF_EVEN(TBigDecimal.ROUND_HALF_EVEN),
|
||||
|
||||
/**
|
||||
* Rounding mode where the rounding operations throws an ArithmeticException
|
||||
* for the case that rounding is necessary, i.e. for the case that the value
|
||||
* cannot be represented exactly.
|
||||
*/
|
||||
UNNECESSARY(TBigDecimal.ROUND_UNNECESSARY);
|
||||
|
||||
/** The old constant of <code>BigDecimal</code>. */
|
||||
@SuppressWarnings("unused")
|
||||
private final int bigDecimalRM;
|
||||
|
||||
/** It sets the old constant. */
|
||||
TRoundingMode(int rm) {
|
||||
bigDecimalRM = rm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts rounding mode constants from class {@code BigDecimal} into
|
||||
* {@code RoundingMode} values.
|
||||
*
|
||||
* @param mode
|
||||
* rounding mode constant as defined in class {@code BigDecimal}
|
||||
* @return corresponding rounding mode object
|
||||
*/
|
||||
public static TRoundingMode valueOf(int mode) {
|
||||
switch (mode) {
|
||||
case TBigDecimal.ROUND_CEILING:
|
||||
return CEILING;
|
||||
case TBigDecimal.ROUND_DOWN:
|
||||
return DOWN;
|
||||
case TBigDecimal.ROUND_FLOOR:
|
||||
return FLOOR;
|
||||
case TBigDecimal.ROUND_HALF_DOWN:
|
||||
return HALF_DOWN;
|
||||
case TBigDecimal.ROUND_HALF_EVEN:
|
||||
return HALF_EVEN;
|
||||
case TBigDecimal.ROUND_HALF_UP:
|
||||
return HALF_UP;
|
||||
case TBigDecimal.ROUND_UNNECESSARY:
|
||||
return UNNECESSARY;
|
||||
case TBigDecimal.ROUND_UP:
|
||||
return UP;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid rounding mode");
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,549 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigDecimal
|
||||
* Methods: abs, compareTo, equals, hashCode,
|
||||
* max, min, negate, signum
|
||||
*/
|
||||
public class BigDecimalCompareTest {
|
||||
/**
|
||||
* Abs() of a negative BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testAbsNeg() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
String result = "123809648392384754573567356745735635678902957849027687.87678287";
|
||||
assertEquals("incorrect value", result, aNumber.abs().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Abs() of a positive BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testAbsPos() {
|
||||
String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
String result = "123809648392384754573567356745735635678902957849027687.87678287";
|
||||
assertEquals("incorrect value", result, aNumber.abs().toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Abs(MathContext) of a negative BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testAbsMathContextNeg() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
int precision = 15;
|
||||
RoundingMode rm = RoundingMode.HALF_DOWN;
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
String result = "1.23809648392385E+53";
|
||||
int resScale = -39;
|
||||
BigDecimal res = aNumber.abs(mc);
|
||||
assertEquals("incorrect value", result, res.toString());
|
||||
assertEquals("incorrect scale", resScale, res.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* Abs(MathContext) of a positive BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testAbsMathContextPos() {
|
||||
String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
int precision = 41;
|
||||
RoundingMode rm = RoundingMode.HALF_EVEN;
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
String result = "1.2380964839238475457356735674573563567890E+53";
|
||||
int resScale = -13;
|
||||
BigDecimal res = aNumber.abs(mc);
|
||||
assertEquals("incorrect value", result, res.toString());
|
||||
assertEquals("incorrect scale", resScale, res.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare to a number of an equal scale
|
||||
*/
|
||||
@Test
|
||||
public void testCompareEqualScale1() {
|
||||
String a = "12380964839238475457356735674573563567890295784902768787678287";
|
||||
int aScale = 18;
|
||||
String b = "4573563567890295784902768787678287";
|
||||
int bScale = 18;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
int result = 1;
|
||||
assertEquals("incorrect result", result, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare to a number of an equal scale
|
||||
*/
|
||||
@Test
|
||||
public void testCompareEqualScale2() {
|
||||
String a = "12380964839238475457356735674573563567890295784902768787678287";
|
||||
int aScale = 18;
|
||||
String b = "4573563923487289357829759278282992758247567890295784902768787678287";
|
||||
int bScale = 18;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
int result = -1;
|
||||
assertEquals("incorrect result", result, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare to a number of an greater scale
|
||||
*/
|
||||
@Test
|
||||
public void testCompareGreaterScale1() {
|
||||
String a = "12380964839238475457356735674573563567890295784902768787678287";
|
||||
int aScale = 28;
|
||||
String b = "4573563567890295784902768787678287";
|
||||
int bScale = 18;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
int result = 1;
|
||||
assertEquals("incorrect result", result, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare to a number of an greater scale
|
||||
*/
|
||||
@Test
|
||||
public void testCompareGreaterScale2() {
|
||||
String a = "12380964839238475457356735674573563567890295784902768787678287";
|
||||
int aScale = 48;
|
||||
String b = "4573563567890295784902768787678287";
|
||||
int bScale = 2;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
int result = -1;
|
||||
assertEquals("incorrect result", result, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare to a number of an less scale
|
||||
*/
|
||||
@Test
|
||||
public void testCompareLessScale1() {
|
||||
String a = "12380964839238475457356735674573563567890295784902768787678287";
|
||||
int aScale = 18;
|
||||
String b = "4573563567890295784902768787678287";
|
||||
int bScale = 28;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
int result = 1;
|
||||
assertEquals("incorrect result", result, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare to a number of an less scale
|
||||
*/
|
||||
@Test
|
||||
public void testCompareLessScale2() {
|
||||
String a = "12380964839238475457356735674573";
|
||||
int aScale = 36;
|
||||
String b = "45735635948573894578349572001798379183767890295784902768787678287";
|
||||
int bScale = 48;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
int result = -1;
|
||||
assertEquals("incorrect result", result, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Equals() for unequal BigDecimals
|
||||
*/
|
||||
@Test
|
||||
public void testEqualsUnequal1() {
|
||||
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = -24;
|
||||
String b = "7472334223847623782375469293018787918347987234564568";
|
||||
int bScale = 13;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
assertFalse(aNumber.equals(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Equals() for unequal BigDecimals
|
||||
*/
|
||||
@Test
|
||||
public void testEqualsUnequal2() {
|
||||
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = -24;
|
||||
String b = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int bScale = 13;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
assertFalse(aNumber.equals(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Equals() for unequal BigDecimals
|
||||
*/
|
||||
@Test
|
||||
public void testEqualsUnequal3() {
|
||||
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = -24;
|
||||
String b = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
assertFalse(aNumber.equals(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* equals() for equal BigDecimals
|
||||
*/
|
||||
@Test
|
||||
public void testEqualsEqual() {
|
||||
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = -24;
|
||||
String b = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int bScale = -24;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
assertEquals(aNumber, bNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* equals() for equal BigDecimals
|
||||
*/
|
||||
@Test
|
||||
public void testEqualsNull() {
|
||||
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = -24;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
assertFalse(aNumber.equals(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* hashCode() for equal BigDecimals
|
||||
*/
|
||||
@Test
|
||||
public void testHashCodeEqual() {
|
||||
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = -24;
|
||||
String b = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int bScale = -24;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
assertEquals("incorrect value", aNumber.hashCode(), bNumber.hashCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* hashCode() for unequal BigDecimals
|
||||
*/
|
||||
@Test
|
||||
public void testHashCodeUnequal() {
|
||||
String a = "8478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 41;
|
||||
String b = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int bScale = -24;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
assertTrue("incorrect value", aNumber.hashCode() != bNumber.hashCode());
|
||||
}
|
||||
|
||||
/**
|
||||
* max() for equal BigDecimals
|
||||
*/
|
||||
@Test
|
||||
public void testMaxEqual() {
|
||||
String a = "8478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 41;
|
||||
String b = "8478231212478987482988429808779810457634781384756794987";
|
||||
int bScale = 41;
|
||||
String c = "8478231212478987482988429808779810457634781384756794987";
|
||||
int cScale = 41;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
BigDecimal cNumber = new BigDecimal(new BigInteger(c), cScale);
|
||||
assertEquals("incorrect value", cNumber, aNumber.max(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* max() for unequal BigDecimals
|
||||
*/
|
||||
@Test
|
||||
public void testMaxUnequal1() {
|
||||
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 24;
|
||||
String b = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int bScale = 41;
|
||||
String c = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int cScale = 24;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
BigDecimal cNumber = new BigDecimal(new BigInteger(c), cScale);
|
||||
assertEquals("incorrect value", cNumber, aNumber.max(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* max() for unequal BigDecimals
|
||||
*/
|
||||
@Test
|
||||
public void testMaxUnequal2() {
|
||||
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 41;
|
||||
String b = "94488478231212478987482988429808779810457634781384756794987";
|
||||
int bScale = 41;
|
||||
String c = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int cScale = 41;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
BigDecimal cNumber = new BigDecimal(new BigInteger(c), cScale);
|
||||
assertEquals("incorrect value", cNumber, aNumber.max(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* min() for equal BigDecimals
|
||||
*/
|
||||
@Test
|
||||
public void testMinEqual() {
|
||||
String a = "8478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 41;
|
||||
String b = "8478231212478987482988429808779810457634781384756794987";
|
||||
int bScale = 41;
|
||||
String c = "8478231212478987482988429808779810457634781384756794987";
|
||||
int cScale = 41;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
BigDecimal cNumber = new BigDecimal(new BigInteger(c), cScale);
|
||||
assertEquals("incorrect value", cNumber, aNumber.min(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* min() for unequal BigDecimals
|
||||
*/
|
||||
@Test
|
||||
public void testMinUnequal1() {
|
||||
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 24;
|
||||
String b = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int bScale = 41;
|
||||
String c = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int cScale = 41;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
BigDecimal cNumber = new BigDecimal(new BigInteger(c), cScale);
|
||||
assertEquals("incorrect value", cNumber, aNumber.min(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* min() for unequal BigDecimals
|
||||
*/
|
||||
@Test
|
||||
public void testMinUnequal2() {
|
||||
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 41;
|
||||
String b = "94488478231212478987482988429808779810457634781384756794987";
|
||||
int bScale = 41;
|
||||
String c = "94488478231212478987482988429808779810457634781384756794987";
|
||||
int cScale = 41;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = new BigDecimal(new BigInteger(b), bScale);
|
||||
BigDecimal cNumber = new BigDecimal(new BigInteger(c), cScale);
|
||||
assertEquals("incorrect value", cNumber, aNumber.min(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* plus() for a positive BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testPlusPositive() {
|
||||
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 41;
|
||||
String c = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int cScale = 41;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal cNumber = new BigDecimal(new BigInteger(c), cScale);
|
||||
assertEquals("incorrect value", cNumber, aNumber.plus());
|
||||
}
|
||||
|
||||
/**
|
||||
* plus(MathContext) for a positive BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testPlusMathContextPositive() {
|
||||
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 41;
|
||||
int precision = 37;
|
||||
RoundingMode rm = RoundingMode.FLOOR;
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
String c = "929487820944884782312124789.8748298842";
|
||||
int cScale = 10;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal res = aNumber.plus(mc);
|
||||
assertEquals("incorrect value", c, res.toString());
|
||||
assertEquals("incorrect scale", cScale, res.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* plus() for a negative BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testPlusNegative() {
|
||||
String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 41;
|
||||
String c = "-92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int cScale = 41;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal cNumber = new BigDecimal(new BigInteger(c), cScale);
|
||||
assertEquals("incorrect value", cNumber, aNumber.plus());
|
||||
}
|
||||
|
||||
/**
|
||||
* plus(MathContext) for a negative BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testPlusMathContextNegative() {
|
||||
String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 49;
|
||||
int precision = 46;
|
||||
RoundingMode rm = RoundingMode.CEILING;
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
String c = "-9294878209448847823.121247898748298842980877981";
|
||||
int cScale = 27;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal res = aNumber.plus(mc);
|
||||
assertEquals("incorrect value", c, res.toString());
|
||||
assertEquals("incorrect scale", cScale, res.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* negate() for a positive BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testNegatePositive() {
|
||||
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 41;
|
||||
String c = "-92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int cScale = 41;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal cNumber = new BigDecimal(new BigInteger(c), cScale);
|
||||
assertEquals("incorrect value", cNumber, aNumber.negate());
|
||||
}
|
||||
|
||||
/**
|
||||
* negate(MathContext) for a positive BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testNegateMathContextPositive() {
|
||||
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 41;
|
||||
int precision = 37;
|
||||
RoundingMode rm = RoundingMode.FLOOR;
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
String c = "-929487820944884782312124789.874829884";
|
||||
int cScale = 10;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal res = aNumber.negate(mc);
|
||||
String resString = res.toString();
|
||||
assertEquals("incorrect value", c, resString.substring(0, resString.length() - 1));
|
||||
assertEquals("incorrect scale", cScale, res.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* negate() for a negative BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testNegateNegative() {
|
||||
String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 41;
|
||||
String c = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int cScale = 41;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal cNumber = new BigDecimal(new BigInteger(c), cScale);
|
||||
assertEquals("incorrect value", cNumber, aNumber.negate());
|
||||
}
|
||||
|
||||
/**
|
||||
* negate(MathContext) for a negative BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testNegateMathContextNegative() {
|
||||
String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 49;
|
||||
int precision = 46;
|
||||
RoundingMode rm = RoundingMode.CEILING;
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
String c = "9294878209448847823.12124789874829884298087798";
|
||||
int cScale = 27;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal res = aNumber.negate(mc);
|
||||
String resString = res.toString();
|
||||
assertEquals("incorrect value", c, resString.substring(0, resString.length() - 1));
|
||||
assertEquals("incorrect scale", cScale, res.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* signum() for a positive BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testSignumPositive() {
|
||||
String a = "92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 41;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
assertEquals("incorrect value", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* signum() for a negative BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testSignumNegative() {
|
||||
String a = "-92948782094488478231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 41;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
assertEquals("incorrect value", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* signum() for zero
|
||||
*/
|
||||
@Test
|
||||
public void testSignumZero() {
|
||||
String a = "0";
|
||||
int aScale = 41;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
assertEquals("incorrect value", 0, aNumber.signum());
|
||||
}
|
||||
|
||||
/*
|
||||
* Regression test for HARMONY-6406
|
||||
*/
|
||||
@Test
|
||||
public void testApproxPrecision() {
|
||||
BigDecimal testInstance = BigDecimal.TEN.multiply(new BigDecimal("0.1"));
|
||||
int result = testInstance.compareTo(new BigDecimal("1.00"));
|
||||
assertEquals(0, result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,740 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigDecimal
|
||||
* Methods: constructors and fields
|
||||
*/
|
||||
public class BigDecimalConstructorsTest {
|
||||
/**
|
||||
* check ONE
|
||||
*/
|
||||
@Test
|
||||
public void testFieldONE() {
|
||||
String oneS = "1";
|
||||
double oneD = 1.0;
|
||||
assertEquals("incorrect string value", oneS, BigDecimal.ONE.toString());
|
||||
assertEquals("incorrect double value", oneD, BigDecimal.ONE.doubleValue(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* check TEN
|
||||
*/
|
||||
@Test
|
||||
public void testFieldTEN() {
|
||||
String oneS = "10";
|
||||
double oneD = 10.0;
|
||||
assertEquals("incorrect string value", oneS, BigDecimal.TEN.toString());
|
||||
assertEquals("incorrect double value", oneD, BigDecimal.TEN.doubleValue(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* check ZERO
|
||||
*/
|
||||
@Test
|
||||
public void testFieldZERO() {
|
||||
String oneS = "0";
|
||||
double oneD = 0.0;
|
||||
assertEquals("incorrect string value", oneS, BigDecimal.ZERO.toString());
|
||||
assertEquals("incorrect double value", oneD, BigDecimal.ZERO.doubleValue(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(BigInteger value)
|
||||
*/
|
||||
@Test
|
||||
public void testConstrBI() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
BigInteger bA = new BigInteger(a);
|
||||
BigDecimal aNumber = new BigDecimal(bA);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", 0, aNumber.scale());
|
||||
|
||||
try {
|
||||
new BigDecimal((BigInteger) null);
|
||||
fail("No NullPointerException");
|
||||
} catch (NullPointerException e) {
|
||||
//expected
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(BigInteger value, int scale)
|
||||
*/
|
||||
@Test
|
||||
public void testConstrBIScale() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
BigInteger bA = new BigInteger(a);
|
||||
int aScale = 10;
|
||||
BigDecimal aNumber = new BigDecimal(bA, aScale);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(BigInteger value, MathContext)
|
||||
*/
|
||||
@Test
|
||||
public void testConstrBigIntegerMathContext() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
BigInteger bA = new BigInteger(a);
|
||||
int precision = 46;
|
||||
RoundingMode rm = RoundingMode.CEILING;
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
String res = "1231212478987482988429808779810457634781384757";
|
||||
int resScale = -6;
|
||||
BigDecimal result = new BigDecimal(bA, mc);
|
||||
assertEquals("incorrect value", res, result.unscaledValue().toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(BigInteger value, int scale, MathContext)
|
||||
*/
|
||||
@Test
|
||||
public void testConstrBigIntegerScaleMathContext() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
BigInteger bA = new BigInteger(a);
|
||||
int aScale = 10;
|
||||
int precision = 46;
|
||||
RoundingMode rm = RoundingMode.CEILING;
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
String res = "1231212478987482988429808779810457634781384757";
|
||||
int resScale = 4;
|
||||
BigDecimal result = new BigDecimal(bA, aScale, mc);
|
||||
assertEquals("incorrect value", res, result.unscaledValue().toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(char[] value);
|
||||
*/
|
||||
@Test
|
||||
public void testConstrChar() {
|
||||
char value[] = {'-', '1', '2', '3', '8', '0', '.', '4', '7', '3', '8', 'E', '-', '4', '2', '3'};
|
||||
BigDecimal result = new BigDecimal(value);
|
||||
String res = "-1.23804738E-419";
|
||||
int resScale = 427;
|
||||
assertEquals("incorrect value", res, result.toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
|
||||
try {
|
||||
// Regression for HARMONY-783
|
||||
new BigDecimal(new char[] {});
|
||||
fail("NumberFormatException has not been thrown");
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(char[] value, int offset, int len);
|
||||
*/
|
||||
@Test
|
||||
public void testConstrCharIntInt() {
|
||||
char value[] = {'-', '1', '2', '3', '8', '0', '.', '4', '7', '3', '8', 'E', '-', '4', '2', '3'};
|
||||
int offset = 3;
|
||||
int len = 12;
|
||||
BigDecimal result = new BigDecimal(value, offset, len);
|
||||
String res = "3.804738E-40";
|
||||
int resScale = 46;
|
||||
assertEquals("incorrect value", res, result.toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
|
||||
try {
|
||||
// Regression for HARMONY-783
|
||||
new BigDecimal(new char[] {}, 0, 0);
|
||||
fail("NumberFormatException has not been thrown");
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(char[] value, int offset, int len, MathContext mc);
|
||||
*/
|
||||
@Test
|
||||
public void testConstrCharIntIntMathContext() {
|
||||
char value[] = {'-', '1', '2', '3', '8', '0', '.', '4', '7', '3', '8', 'E', '-', '4', '2', '3'};
|
||||
int offset = 3;
|
||||
int len = 12;
|
||||
int precision = 4;
|
||||
RoundingMode rm = RoundingMode.CEILING;
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
BigDecimal result = new BigDecimal(value, offset, len, mc);
|
||||
String res = "3.805E-40";
|
||||
int resScale = 43;
|
||||
assertEquals("incorrect value", res, result.toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
|
||||
try {
|
||||
// Regression for HARMONY-783
|
||||
new BigDecimal(new char[] {}, 0, 0, MathContext.DECIMAL32);
|
||||
fail("NumberFormatException has not been thrown");
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(char[] value, int offset, int len, MathContext mc);
|
||||
*/
|
||||
@Test
|
||||
public void testConstrCharIntIntMathContextException1() {
|
||||
char value[] = {'-', '1', '2', '3', '8', '0', '.', '4', '7', '3', '8', 'E', '-', '4', '2', '3'};
|
||||
int offset = 3;
|
||||
int len = 120;
|
||||
int precision = 4;
|
||||
RoundingMode rm = RoundingMode.CEILING;
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
try {
|
||||
new BigDecimal(value, offset, len, mc);
|
||||
fail("NumberFormatException has not been thrown");
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(char[] value, int offset, int len, MathContext mc);
|
||||
*/
|
||||
@Test
|
||||
public void testConstrCharIntIntMathContextException2() {
|
||||
char value[] = {'-', '1', '2', '3', '8', '0', ',', '4', '7', '3', '8', 'E', '-', '4', '2', '3'};
|
||||
int offset = 3;
|
||||
int len = 120;
|
||||
int precision = 4;
|
||||
RoundingMode rm = RoundingMode.CEILING;
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
try {
|
||||
new BigDecimal(value, offset, len, mc);
|
||||
fail("NumberFormatException has not been thrown");
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(char[] value, MathContext mc);
|
||||
*/
|
||||
@Test
|
||||
public void testConstrCharMathContext() {
|
||||
try {
|
||||
// Regression for HARMONY-783
|
||||
new BigDecimal(new char[] {}, MathContext.DECIMAL32);
|
||||
fail("NumberFormatException has not been thrown");
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(double value) when value is NaN
|
||||
*/
|
||||
@Test
|
||||
public void testConstrDoubleNaN() {
|
||||
double a = Double.NaN;
|
||||
try {
|
||||
new BigDecimal(a);
|
||||
fail("NumberFormatException has not been caught");
|
||||
} catch (NumberFormatException e) {
|
||||
assertEquals("Improper exception message", "Infinite or NaN", e
|
||||
.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(double value) when value is positive infinity
|
||||
*/
|
||||
@Test
|
||||
public void testConstrDoublePosInfinity() {
|
||||
double a = Double.POSITIVE_INFINITY;
|
||||
try {
|
||||
new BigDecimal(a);
|
||||
fail("NumberFormatException has not been caught");
|
||||
} catch (NumberFormatException e) {
|
||||
assertEquals("Improper exception message", "Infinite or NaN",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(double value) when value is positive infinity
|
||||
*/
|
||||
@Test
|
||||
public void testConstrDoubleNegInfinity() {
|
||||
double a = Double.NEGATIVE_INFINITY;
|
||||
try {
|
||||
new BigDecimal(a);
|
||||
fail("NumberFormatException has not been caught");
|
||||
} catch (NumberFormatException e) {
|
||||
assertEquals("Improper exception message", "Infinite or NaN",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(double value)
|
||||
*/
|
||||
@Test
|
||||
public void testConstrDouble() {
|
||||
double a = 732546982374982347892379283571094797.287346782359284756;
|
||||
int aScale = 0;
|
||||
BigInteger bA = new BigInteger("732546982374982285073458350476230656");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(double, MathContext)
|
||||
*/
|
||||
@Test
|
||||
public void testConstrDoubleMathContext() {
|
||||
double a = 732546982374982347892379283571094797.287346782359284756;
|
||||
int precision = 21;
|
||||
RoundingMode rm = RoundingMode.CEILING;
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
String res = "732546982374982285074";
|
||||
int resScale = -15;
|
||||
BigDecimal result = new BigDecimal(a, mc);
|
||||
assertEquals("incorrect value", res, result.unscaledValue().toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(0.1)
|
||||
*/
|
||||
@Test
|
||||
public void testConstrDouble01() {
|
||||
double a = 1.E-1;
|
||||
int aScale = 55;
|
||||
BigInteger bA = new BigInteger("1000000000000000055511151231257827021181583404541015625");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(0.555)
|
||||
*/
|
||||
@Test
|
||||
public void testConstrDouble02() {
|
||||
double a = 0.555;
|
||||
int aScale = 53;
|
||||
BigInteger bA = new BigInteger("55500000000000004884981308350688777863979339599609375");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(-0.1)
|
||||
*/
|
||||
@Test
|
||||
public void testConstrDoubleMinus01() {
|
||||
double a = -1.E-1;
|
||||
int aScale = 55;
|
||||
BigInteger bA = new BigInteger("-1000000000000000055511151231257827021181583404541015625");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(int value)
|
||||
*/
|
||||
@Test
|
||||
public void testConstrInt() {
|
||||
int a = 732546982;
|
||||
String res = "732546982";
|
||||
int resScale = 0;
|
||||
BigDecimal result = new BigDecimal(a);
|
||||
assertEquals("incorrect value", res, result.unscaledValue().toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(int, MathContext)
|
||||
*/
|
||||
@Test
|
||||
public void testConstrIntMathContext() {
|
||||
int a = 732546982;
|
||||
int precision = 21;
|
||||
RoundingMode rm = RoundingMode.CEILING;
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
String res = "732546982";
|
||||
int resScale = 0;
|
||||
BigDecimal result = new BigDecimal(a, mc);
|
||||
assertEquals("incorrect value", res, result.unscaledValue().toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(long value)
|
||||
*/
|
||||
@Test
|
||||
public void testConstrLong() {
|
||||
long a = 4576578677732546982L;
|
||||
String res = "4576578677732546982";
|
||||
int resScale = 0;
|
||||
BigDecimal result = new BigDecimal(a);
|
||||
assertEquals("incorrect value", res, result.unscaledValue().toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(long, MathContext)
|
||||
*/
|
||||
@Test
|
||||
public void testConstrLongMathContext() {
|
||||
long a = 4576578677732546982L;
|
||||
int precision = 5;
|
||||
RoundingMode rm = RoundingMode.CEILING;
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
String res = "45766";
|
||||
int resScale = -14;
|
||||
BigDecimal result = new BigDecimal(a, mc);
|
||||
assertEquals("incorrect value", res, result.unscaledValue().toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(double value) when value is denormalized
|
||||
*/
|
||||
@Test
|
||||
public void testConstrDoubleDenormalized() {
|
||||
double a = 2.274341322658976E-309;
|
||||
int aScale = 1073;
|
||||
BigInteger bA = new BigInteger("227434132265897633950269241702666687639731047124115603942986140264569528085692462493371029187342478828091760934014851133733918639492582043963243759464684978401240614084312038547315281016804838374623558434472007664427140169018817050565150914041833284370702366055678057809362286455237716100382057360123091641959140448783514464639706721250400288267372238950016114583259228262046633530468551311769574111763316146065958042194569102063373243372766692713192728878701004405568459288708477607744497502929764155046100964958011009313090462293046650352146796805866786767887226278836423536035611825593567576424943331337401071583562754098901412372708947790843318760718495117047155597276492717187936854356663665005157041552436478744491526494952982062613955349661409854888916015625");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value)
|
||||
* when value is not a valid representation of BigDecimal.
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringException() {
|
||||
String a = "-238768.787678287a+10";
|
||||
try {
|
||||
new BigDecimal(a);
|
||||
fail("NumberFormatException has not been caught");
|
||||
} catch (NumberFormatException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value) when exponent is empty.
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringExceptionEmptyExponent1() {
|
||||
String a = "-238768.787678287e";
|
||||
try {
|
||||
new BigDecimal(a);
|
||||
fail("NumberFormatException has not been caught");
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value) when exponent is empty.
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringExceptionEmptyExponent2() {
|
||||
String a = "-238768.787678287e-";
|
||||
try {
|
||||
new BigDecimal(a);
|
||||
fail("NumberFormatException has not been caught");
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value) when exponent is greater than
|
||||
* Integer.MAX_VALUE.
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringExceptionExponentGreaterIntegerMax() {
|
||||
String a = "-238768.787678287e214748364767876";
|
||||
try {
|
||||
new BigDecimal(a);
|
||||
fail("NumberFormatException has not been caught");
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value) when exponent is less than
|
||||
* Integer.MIN_VALUE.
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringExceptionExponentLessIntegerMin() {
|
||||
String a = "-238768.787678287e-214748364767876";
|
||||
try {
|
||||
new BigDecimal(a);
|
||||
fail("NumberFormatException has not been caught");
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value)
|
||||
* when exponent is Integer.MAX_VALUE.
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringExponentIntegerMax() {
|
||||
String a = "-238768.787678287e2147483647";
|
||||
int aScale = -2147483638;
|
||||
BigInteger bA = new BigInteger("-238768787678287");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value)
|
||||
* when exponent is Integer.MIN_VALUE.
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringExponentIntegerMin() {
|
||||
String a = ".238768e-2147483648";
|
||||
try {
|
||||
new BigDecimal(a);
|
||||
fail("NumberFormatException expected");
|
||||
} catch (NumberFormatException e) {
|
||||
assertEquals("Improper exception message","Scale out of range.",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value); value does not contain exponent
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringWithoutExpPos1() {
|
||||
String a = "732546982374982347892379283571094797.287346782359284756";
|
||||
int aScale = 18;
|
||||
BigInteger bA = new BigInteger("732546982374982347892379283571094797287346782359284756");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value); value does not contain exponent
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringWithoutExpPos2() {
|
||||
String a = "+732546982374982347892379283571094797.287346782359284756";
|
||||
int aScale = 18;
|
||||
BigInteger bA = new BigInteger("732546982374982347892379283571094797287346782359284756");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value); value does not contain exponent
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringWithoutExpNeg() {
|
||||
String a = "-732546982374982347892379283571094797.287346782359284756";
|
||||
int aScale = 18;
|
||||
BigInteger bA = new BigInteger("-732546982374982347892379283571094797287346782359284756");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value); value does not contain exponent
|
||||
* and decimal point
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringWithoutExpWithoutPoint() {
|
||||
String a = "-732546982374982347892379283571094797287346782359284756";
|
||||
int aScale = 0;
|
||||
BigInteger bA = new BigInteger("-732546982374982347892379283571094797287346782359284756");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value); value contains exponent
|
||||
* and does not contain decimal point
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringWithExponentWithoutPoint1() {
|
||||
String a = "-238768787678287e214";
|
||||
int aScale = -214;
|
||||
BigInteger bA = new BigInteger("-238768787678287");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value); value contains exponent
|
||||
* and does not contain decimal point
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringWithExponentWithoutPoint2() {
|
||||
String a = "-238768787678287e-214";
|
||||
int aScale = 214;
|
||||
BigInteger bA = new BigInteger("-238768787678287");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value); value contains exponent
|
||||
* and does not contain decimal point
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringWithExponentWithoutPoint3() {
|
||||
String a = "238768787678287e-214";
|
||||
int aScale = 214;
|
||||
BigInteger bA = new BigInteger("238768787678287");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value); value contains exponent
|
||||
* and does not contain decimal point
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringWithExponentWithoutPoint4() {
|
||||
String a = "238768787678287e+214";
|
||||
int aScale = -214;
|
||||
BigInteger bA = new BigInteger("238768787678287");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value); value contains exponent
|
||||
* and does not contain decimal point
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringWithExponentWithoutPoint5() {
|
||||
String a = "238768787678287E214";
|
||||
int aScale = -214;
|
||||
BigInteger bA = new BigInteger("238768787678287");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value);
|
||||
* value contains both exponent and decimal point
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringWithExponentWithPoint1() {
|
||||
String a = "23985439837984782435652424523876878.7678287e+214";
|
||||
int aScale = -207;
|
||||
BigInteger bA = new BigInteger("239854398379847824356524245238768787678287");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value);
|
||||
* value contains both exponent and decimal point
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringWithExponentWithPoint2() {
|
||||
String a = "238096483923847545735673567457356356789029578490276878.7678287e-214";
|
||||
int aScale = 221;
|
||||
BigInteger bA = new BigInteger("2380964839238475457356735674573563567890295784902768787678287");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value);
|
||||
* value contains both exponent and decimal point
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringWithExponentWithPoint3() {
|
||||
String a = "2380964839238475457356735674573563567890.295784902768787678287E+21";
|
||||
int aScale = 0;
|
||||
BigInteger bA = new BigInteger("2380964839238475457356735674573563567890295784902768787678287");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value);
|
||||
* value contains both exponent and decimal point
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringWithExponentWithPoint4() {
|
||||
String a = "23809648392384754573567356745735635678.90295784902768787678287E+21";
|
||||
int aScale = 2;
|
||||
BigInteger bA = new BigInteger("2380964839238475457356735674573563567890295784902768787678287");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value);
|
||||
* value contains both exponent and decimal point
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringWithExponentWithPoint5() {
|
||||
String a = "238096483923847545735673567457356356789029.5784902768787678287E+21";
|
||||
int aScale = -2;
|
||||
BigInteger bA = new BigInteger("2380964839238475457356735674573563567890295784902768787678287");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
assertEquals("incorrect value", bA, aNumber.unscaledValue());
|
||||
assertEquals("incorrect scale", aScale, aNumber.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* new BigDecimal(String value, MathContext)
|
||||
*/
|
||||
@Test
|
||||
public void testConstrStringMathContext() {
|
||||
String a = "-238768787678287e214";
|
||||
int precision = 5;
|
||||
RoundingMode rm = RoundingMode.CEILING;
|
||||
MathContext mc = new MathContext(precision, rm);
|
||||
String res = "-23876";
|
||||
int resScale = -224;
|
||||
BigDecimal result = new BigDecimal(a, mc);
|
||||
assertEquals("incorrect value", res, result.unscaledValue().toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,619 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigDecimal
|
||||
* Methods: doubleValue, floatValue, intValue, longValue,
|
||||
* valueOf, toString, toBigInteger
|
||||
*/
|
||||
public class BigDecimalConvertTest {
|
||||
/**
|
||||
* Double value of a negative BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValueNeg() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
double result = -1.2380964839238476E53;
|
||||
assertEquals("incorrect value", result, aNumber.doubleValue(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Double value of a positive BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValuePos() {
|
||||
String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
double result = 1.2380964839238476E53;
|
||||
assertEquals("incorrect value", result, aNumber.doubleValue(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Double value of a large positive BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValuePosInfinity() {
|
||||
String a = "123809648392384754573567356745735.63567890295784902768787678287E+400";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
double result = Double.POSITIVE_INFINITY;
|
||||
assertEquals("incorrect value", result, aNumber.doubleValue(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Double value of a large negative BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValueNegInfinity() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E+400";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
double result = Double.NEGATIVE_INFINITY;
|
||||
assertEquals("incorrect value", result, aNumber.doubleValue(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Double value of a small negative BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValueMinusZero() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E-400";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
long minusZero = -9223372036854775808L;
|
||||
double result = aNumber.doubleValue();
|
||||
assertTrue("incorrect value", Double.doubleToLongBits(result) == minusZero);
|
||||
}
|
||||
|
||||
/**
|
||||
* Double value of a small positive BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValuePlusZero() {
|
||||
String a = "123809648392384754573567356745735.63567890295784902768787678287E-400";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
long zero = 0;
|
||||
double result = aNumber.doubleValue();
|
||||
assertTrue("incorrect value", Double.doubleToLongBits(result) == zero);
|
||||
}
|
||||
|
||||
/**
|
||||
* Float value of a negative BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueNeg() {
|
||||
String a = "-1238096483923847.6356789029578E+21";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
float result = -1.2380965E36F;
|
||||
assertTrue("incorrect value", aNumber.floatValue() == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Float value of a positive BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValuePos() {
|
||||
String a = "1238096483923847.6356789029578E+21";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
float result = 1.2380965E36F;
|
||||
assertTrue("incorrect value", aNumber.floatValue() == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Float value of a large positive BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValuePosInfinity() {
|
||||
String a = "123809648373567356745735.6356789787678287E+200";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
float result = Float.POSITIVE_INFINITY;
|
||||
assertTrue("incorrect value", aNumber.floatValue() == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Float value of a large negative BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueNegInfinity() {
|
||||
String a = "-123809648392384755735.63567887678287E+200";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
float result = Float.NEGATIVE_INFINITY;
|
||||
assertTrue("incorrect value", aNumber.floatValue() == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Float value of a small negative BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueMinusZero() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E-400";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
int minusZero = -2147483648;
|
||||
float result = aNumber.floatValue();
|
||||
assertTrue("incorrect value", Float.floatToIntBits(result) == minusZero);
|
||||
}
|
||||
|
||||
/**
|
||||
* Float value of a small positive BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValuePlusZero() {
|
||||
String a = "123809648392384754573567356745735.63567890295784902768787678287E-400";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
int zero = 0;
|
||||
float result = aNumber.floatValue();
|
||||
assertTrue("incorrect value", Float.floatToIntBits(result) == zero);
|
||||
}
|
||||
|
||||
/**
|
||||
* Integer value of a negative BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testIntValueNeg() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
int result = 218520473;
|
||||
assertTrue("incorrect value", aNumber.intValue() == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Integer value of a positive BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testIntValuePos() {
|
||||
String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
int result = -218520473;
|
||||
assertTrue("incorrect value", aNumber.intValue() == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Long value of a negative BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testLongValueNeg() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
long result = -1246043477766677607L;
|
||||
assertTrue("incorrect value", aNumber.longValue() == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Long value of a positive BigDecimal
|
||||
*/
|
||||
@Test
|
||||
public void testLongValuePos() {
|
||||
String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
long result = 1246043477766677607L;
|
||||
assertTrue("incorrect value", aNumber.longValue() == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* scaleByPowerOfTen(int n)
|
||||
*/
|
||||
@Test
|
||||
public void testScaleByPowerOfTen1() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 13;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal result = aNumber.scaleByPowerOfTen(10);
|
||||
String res = "1231212478987482988429808779810457634781384756794.987";
|
||||
int resScale = 3;
|
||||
assertEquals("incorrect value", res, result.toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* scaleByPowerOfTen(int n)
|
||||
*/
|
||||
@Test
|
||||
public void testScaleByPowerOfTen2() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
int aScale = -13;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal result = aNumber.scaleByPowerOfTen(10);
|
||||
String res = "1.231212478987482988429808779810457634781384756794987E+74";
|
||||
int resScale = -23;
|
||||
assertEquals("incorrect value", res, result.toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive BigDecimal to BigInteger
|
||||
*/
|
||||
@Test
|
||||
public void testToBigIntegerPos1() {
|
||||
String a = "123809648392384754573567356745735.63567890295784902768787678287E+21";
|
||||
BigInteger bNumber = new BigInteger("123809648392384754573567356745735635678902957849027687");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
BigInteger result = aNumber.toBigInteger();
|
||||
assertTrue("incorrect value", result.equals(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive BigDecimal to BigInteger
|
||||
*/
|
||||
@Test
|
||||
public void testToBigIntegerPos2() {
|
||||
String a = "123809648392384754573567356745735.63567890295784902768787678287E+15";
|
||||
BigInteger bNumber = new BigInteger("123809648392384754573567356745735635678902957849");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
BigInteger result = aNumber.toBigInteger();
|
||||
assertTrue("incorrect value", result.equals(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive BigDecimal to BigInteger
|
||||
*/
|
||||
@Test
|
||||
public void testToBigIntegerPos3() {
|
||||
String a = "123809648392384754573567356745735.63567890295784902768787678287E+45";
|
||||
BigInteger bNumber = new BigInteger("123809648392384754573567356745735635678902957849027687876782870000000000000000");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
BigInteger result = aNumber.toBigInteger();
|
||||
assertTrue("incorrect value", result.equals(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative BigDecimal to BigInteger
|
||||
*/
|
||||
@Test
|
||||
public void testToBigIntegerNeg1() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E+21";
|
||||
BigInteger bNumber = new BigInteger("-123809648392384754573567356745735635678902957849027687");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
BigInteger result = aNumber.toBigInteger();
|
||||
assertTrue("incorrect value", result.equals(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative BigDecimal to BigInteger
|
||||
*/
|
||||
@Test
|
||||
public void testToBigIntegerNeg2() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E+15";
|
||||
BigInteger bNumber = new BigInteger("-123809648392384754573567356745735635678902957849");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
BigInteger result = aNumber.toBigInteger();
|
||||
assertTrue("incorrect value", result.equals(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative BigDecimal to BigInteger
|
||||
*/
|
||||
@Test
|
||||
public void testToBigIntegerNeg3() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E+45";
|
||||
BigInteger bNumber = new BigInteger("-123809648392384754573567356745735635678902957849027687876782870000000000000000");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
BigInteger result = aNumber.toBigInteger();
|
||||
assertTrue("incorrect value", result.equals(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a small BigDecimal to BigInteger
|
||||
*/
|
||||
@Test
|
||||
public void testToBigIntegerZero() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E-500";
|
||||
BigInteger bNumber = new BigInteger("0");
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
BigInteger result = aNumber.toBigInteger();
|
||||
assertTrue("incorrect value", result.equals(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* toBigIntegerExact()
|
||||
*/
|
||||
@Test
|
||||
public void testToBigIntegerExact1() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E+45";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
String res = "-123809648392384754573567356745735635678902957849027687876782870000000000000000";
|
||||
BigInteger result = aNumber.toBigIntegerExact();
|
||||
assertEquals("incorrect value", res, result.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* toBigIntegerExact()
|
||||
*/
|
||||
@Test
|
||||
public void testToBigIntegerExactException() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E-10";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
try {
|
||||
aNumber.toBigIntegerExact();
|
||||
fail("java.lang.ArithmeticException has not been thrown");
|
||||
} catch (java.lang.ArithmeticException e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive BigDecimal to an engineering string representation
|
||||
*/
|
||||
@Test
|
||||
public void testToEngineeringStringPos() {
|
||||
String a = "123809648392384754573567356745735.63567890295784902768787678287E-501";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
String result = "123.80964839238475457356735674573563567890295784902768787678287E-471";
|
||||
assertEquals("incorrect value", result, aNumber.toEngineeringString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative BigDecimal to an engineering string representation
|
||||
*/
|
||||
@Test
|
||||
public void testToEngineeringStringNeg() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E-501";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
String result = "-123.80964839238475457356735674573563567890295784902768787678287E-471";
|
||||
assertEquals("incorrect value", result, aNumber.toEngineeringString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative BigDecimal to an engineering string representation
|
||||
*/
|
||||
@Test
|
||||
public void testToEngineeringStringZeroPosExponent() {
|
||||
String a = "0.0E+16";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
String result = "0E+15";
|
||||
assertEquals("incorrect value", result, aNumber.toEngineeringString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative BigDecimal to an engineering string representation
|
||||
*/
|
||||
@Test
|
||||
public void testToEngineeringStringZeroNegExponent() {
|
||||
String a = "0.0E-16";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
String result = "0.00E-15";
|
||||
assertEquals("incorrect value", result, aNumber.toEngineeringString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative BigDecimal with a negative exponent to a plain string
|
||||
* representation; scale == 0.
|
||||
*/
|
||||
@Test
|
||||
public void testToPlainStringNegNegExp() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E-100";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
String result = "-0.000000000000000000000000000000000000000000000000000000000000000000012380964839238475457356735674573563567890295784902768787678287";
|
||||
assertTrue("incorrect value", aNumber.toPlainString().equals(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative BigDecimal with a positive exponent
|
||||
* to a plain string representation;
|
||||
* scale == 0.
|
||||
*/
|
||||
@Test
|
||||
public void testToPlainStringNegPosExp() {
|
||||
String a = "-123809648392384754573567356745735.63567890295784902768787678287E100";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
String result = "-1238096483923847545735673567457356356789029578490276878767828700000000000000000000000000000000000000000000000000000000000000000000000";
|
||||
assertTrue("incorrect value", aNumber.toPlainString().equals(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive BigDecimal with a negative exponent
|
||||
* to a plain string representation;
|
||||
* scale == 0.
|
||||
*/
|
||||
@Test
|
||||
public void testToPlainStringPosNegExp() {
|
||||
String a = "123809648392384754573567356745735.63567890295784902768787678287E-100";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
String result = "0.000000000000000000000000000000000000000000000000000000000000000000012380964839238475457356735674573563567890295784902768787678287";
|
||||
assertTrue("incorrect value", aNumber.toPlainString().equals(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative BigDecimal with a negative exponent
|
||||
* to a plain string representation;
|
||||
* scale == 0.
|
||||
*/
|
||||
@Test
|
||||
public void testToPlainStringPosPosExp() {
|
||||
String a = "123809648392384754573567356745735.63567890295784902768787678287E+100";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
String result = "1238096483923847545735673567457356356789029578490276878767828700000000000000000000000000000000000000000000000000000000000000000000000";
|
||||
assertTrue("incorrect value", aNumber.toPlainString().equals(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a BigDecimal to a string representation;
|
||||
* scale == 0.
|
||||
*/
|
||||
@Test
|
||||
public void testToStringZeroScale() {
|
||||
String a = "-123809648392384754573567356745735635678902957849027687876782870";
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a));
|
||||
String result = "-123809648392384754573567356745735635678902957849027687876782870";
|
||||
assertTrue("incorrect value", aNumber.toString().equals(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive BigDecimal to a string representation
|
||||
*/
|
||||
@Test
|
||||
public void testToStringPos() {
|
||||
String a = "123809648392384754573567356745735.63567890295784902768787678287E-500";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
String result = "1.2380964839238475457356735674573563567890295784902768787678287E-468";
|
||||
assertTrue("incorrect value", aNumber.toString().equals(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative BigDecimal to a string representation
|
||||
*/
|
||||
@Test
|
||||
public void testToStringNeg() {
|
||||
String a = "-123.4564563673567380964839238475457356735674573563567890295784902768787678287E-5";
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
String result = "-0.001234564563673567380964839238475457356735674573563567890295784902768787678287";
|
||||
assertTrue("incorrect value", aNumber.toString().equals(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a BigDecimal from a positive long value; scale == 0
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfPosZeroScale() {
|
||||
long a = 98374823947823578L;
|
||||
BigDecimal aNumber = BigDecimal.valueOf(a);
|
||||
String result = "98374823947823578";
|
||||
assertTrue("incorrect value", aNumber.toString().equals(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a BigDecimal from a negative long value; scale is 0
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfNegZeroScale() {
|
||||
long a = -98374823947823578L;
|
||||
BigDecimal aNumber = BigDecimal.valueOf(a);
|
||||
String result = "-98374823947823578";
|
||||
assertTrue("incorrect value", aNumber.toString().equals(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a BigDecimal from a negative long value; scale is positive
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfNegScalePos() {
|
||||
long a = -98374823947823578L;
|
||||
int scale = 12;
|
||||
BigDecimal aNumber = BigDecimal.valueOf(a, scale);
|
||||
String result = "-98374.823947823578";
|
||||
assertTrue("incorrect value", aNumber.toString().equals(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a BigDecimal from a negative long value; scale is negative
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfNegScaleNeg() {
|
||||
long a = -98374823947823578L;
|
||||
int scale = -12;
|
||||
BigDecimal aNumber = BigDecimal.valueOf(a, scale);
|
||||
String result = "-9.8374823947823578E+28";
|
||||
assertTrue("incorrect value", aNumber.toString().equals(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a BigDecimal from a negative long value; scale is positive
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfPosScalePos() {
|
||||
long a = 98374823947823578L;
|
||||
int scale = 12;
|
||||
BigDecimal aNumber = BigDecimal.valueOf(a, scale);
|
||||
String result = "98374.823947823578";
|
||||
assertTrue("incorrect value", aNumber.toString().equals(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a BigDecimal from a negative long value; scale is negative
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfPosScaleNeg() {
|
||||
long a = 98374823947823578L;
|
||||
int scale = -12;
|
||||
BigDecimal aNumber = BigDecimal.valueOf(a, scale);
|
||||
String result = "9.8374823947823578E+28";
|
||||
assertTrue("incorrect value", aNumber.toString().equals(result));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a BigDecimal from a negative double value
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfDoubleNeg() {
|
||||
double a = -65678765876567576.98788767;
|
||||
BigDecimal result = BigDecimal.valueOf(a);
|
||||
String res = "-65678765876567576";
|
||||
int resScale = 0;
|
||||
assertEquals("incorrect value", res, result.toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a BigDecimal from a positive double value
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfDoublePos1() {
|
||||
double a = 65678765876567576.98788767;
|
||||
BigDecimal result = BigDecimal.valueOf(a);
|
||||
String res = "65678765876567576";
|
||||
int resScale = 0;
|
||||
assertEquals("incorrect value", res, result.toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a BigDecimal from a positive double value
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfDoublePos2() {
|
||||
double a = 12321237576.98788767;
|
||||
BigDecimal result = BigDecimal.valueOf(a);
|
||||
String res = "12321237576.987888";
|
||||
int resScale = 6;
|
||||
assertEquals("incorrect value", res, result.toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a BigDecimal from a positive double value
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfDoublePos3() {
|
||||
double a = 12321237576.9878838;
|
||||
BigDecimal result = BigDecimal.valueOf(a);
|
||||
String res = "12321237576.987885";
|
||||
int resScale = 6;
|
||||
assertEquals("incorrect value", res, result.toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* valueOf(Double.NaN)
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfDoubleNaN() {
|
||||
double a = Double.NaN;
|
||||
try {
|
||||
BigDecimal.valueOf(a);
|
||||
fail("NumberFormatException has not been thrown for Double.NaN");
|
||||
} catch (NumberFormatException e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,374 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.*;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigDecimal
|
||||
* Methods: movePointLeft, movePointRight, scale, setScale, unscaledValue *
|
||||
*/
|
||||
public class BigDecimalScaleOperationsTest {
|
||||
/**
|
||||
* Check the default scale
|
||||
*/
|
||||
@Test
|
||||
public void testScaleDefault() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
int cScale = 0;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a));
|
||||
assertTrue("incorrect scale", aNumber.scale() == cScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a negative scale
|
||||
*/
|
||||
@Test
|
||||
public void testScaleNeg() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
int aScale = -10;
|
||||
int cScale = -10;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
assertTrue("incorrect scale", aNumber.scale() == cScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a positive scale
|
||||
*/
|
||||
@Test
|
||||
public void testScalePos() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 10;
|
||||
int cScale = 10;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
assertTrue("incorrect scale", aNumber.scale() == cScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the zero scale
|
||||
*/
|
||||
@Test
|
||||
public void testScaleZero() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 0;
|
||||
int cScale = 0;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
assertTrue("incorrect scale", aNumber.scale() == cScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the unscaled value
|
||||
*/
|
||||
@Test
|
||||
public void testUnscaledValue() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 100;
|
||||
BigInteger bNumber = new BigInteger(a);
|
||||
BigDecimal aNumber = new BigDecimal(bNumber, aScale);
|
||||
assertTrue("incorrect unscaled value", aNumber.unscaledValue().equals(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a greater new scale
|
||||
*/
|
||||
@Test
|
||||
public void testSetScaleGreater() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 18;
|
||||
int newScale = 28;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = aNumber.setScale(newScale);
|
||||
assertTrue("incorrect scale", bNumber.scale() == newScale);
|
||||
assertEquals("incorrect value", 0, bNumber.compareTo(aNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a less new scale; this.scale == 8; newScale == 5.
|
||||
*/
|
||||
@Test
|
||||
public void testSetScaleLess() {
|
||||
String a = "2.345726458768760000E+10";
|
||||
int newScale = 5;
|
||||
BigDecimal aNumber = new BigDecimal(a);
|
||||
BigDecimal bNumber = aNumber.setScale(newScale);
|
||||
assertTrue("incorrect scale", bNumber.scale() == newScale);
|
||||
assertEquals("incorrect value", 0, bNumber.compareTo(aNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify an exception when setting a new scale
|
||||
*/
|
||||
@Test
|
||||
public void testSetScaleException() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 28;
|
||||
int newScale = 18;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
try {
|
||||
aNumber.setScale(newScale);
|
||||
fail("ArithmeticException has not been caught");
|
||||
} catch (ArithmeticException e) {
|
||||
assertEquals("Improper exception message", "Rounding necessary", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the same new scale
|
||||
*/
|
||||
@Test
|
||||
public void testSetScaleSame() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 18;
|
||||
int newScale = 18;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = aNumber.setScale(newScale);
|
||||
assertTrue("incorrect scale", bNumber.scale() == newScale);
|
||||
assertTrue("incorrect value", bNumber.equals(aNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new scale
|
||||
*/
|
||||
@Test
|
||||
public void testSetScaleRoundUp() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
String b = "123121247898748298842980877981045763478139";
|
||||
int aScale = 28;
|
||||
int newScale = 18;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_UP);
|
||||
assertTrue("incorrect scale", bNumber.scale() == newScale);
|
||||
assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new scale
|
||||
*/
|
||||
@Test
|
||||
public void testSetScaleRoundDown() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
String b = "123121247898748298842980877981045763478138";
|
||||
int aScale = 28;
|
||||
int newScale = 18;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_DOWN);
|
||||
assertTrue("incorrect scale", bNumber.scale() == newScale);
|
||||
assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new scale
|
||||
*/
|
||||
@Test
|
||||
public void testSetScaleRoundCeiling() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
String b = "123121247898748298842980877981045763478139";
|
||||
int aScale = 28;
|
||||
int newScale = 18;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_CEILING);
|
||||
assertTrue("incorrect scale", bNumber.scale() == newScale);
|
||||
assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new scale
|
||||
*/
|
||||
@Test
|
||||
public void testSetScaleRoundFloor() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
String b = "123121247898748298842980877981045763478138";
|
||||
int aScale = 28;
|
||||
int newScale = 18;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_FLOOR);
|
||||
assertTrue("incorrect scale", bNumber.scale() == newScale);
|
||||
assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new scale
|
||||
*/
|
||||
@Test
|
||||
public void testSetScaleRoundHalfUp() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
String b = "123121247898748298842980877981045763478138";
|
||||
int aScale = 28;
|
||||
int newScale = 18;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_HALF_UP);
|
||||
assertTrue("incorrect scale", bNumber.scale() == newScale);
|
||||
assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new scale
|
||||
*/
|
||||
@Test
|
||||
public void testSetScaleRoundHalfDown() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
String b = "123121247898748298842980877981045763478138";
|
||||
int aScale = 28;
|
||||
int newScale = 18;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_HALF_DOWN);
|
||||
assertTrue("incorrect scale", bNumber.scale() == newScale);
|
||||
assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new scale
|
||||
*/
|
||||
@Test
|
||||
public void testSetScaleRoundHalfEven() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
String b = "123121247898748298842980877981045763478138";
|
||||
int aScale = 28;
|
||||
int newScale = 18;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_HALF_EVEN);
|
||||
assertTrue("incorrect scale", bNumber.scale() == newScale);
|
||||
assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* SetScale(int, RoundingMode)
|
||||
*/
|
||||
@Test
|
||||
public void testSetScaleIntRoundingMode() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 28;
|
||||
int newScale = 18;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal result = aNumber.setScale(newScale, RoundingMode.HALF_EVEN);
|
||||
String res = "123121247898748298842980.877981045763478138";
|
||||
int resScale = 18;
|
||||
assertEquals("incorrect value", res, result.toString());
|
||||
assertEquals("incorrect scale", resScale, result.scale());
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the decimal point to the left; the shift value is positive
|
||||
*/
|
||||
@Test
|
||||
public void testMovePointLeftPos() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 28;
|
||||
int shift = 18;
|
||||
int resScale = 46;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = aNumber.movePointLeft(shift);
|
||||
assertTrue("incorrect scale", bNumber.scale() == resScale);
|
||||
assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(a));
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the decimal point to the left; the shift value is positive
|
||||
*/
|
||||
@Test
|
||||
public void testMovePointLeftNeg() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 28;
|
||||
int shift = -18;
|
||||
int resScale = 10;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = aNumber.movePointLeft(shift);
|
||||
assertTrue("incorrect scale", bNumber.scale() == resScale);
|
||||
assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(a));
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the decimal point to the right; the shift value is positive
|
||||
*/
|
||||
@Test
|
||||
public void testMovePointRightPosGreater() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 28;
|
||||
int shift = 18;
|
||||
int resScale = 10;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = aNumber.movePointRight(shift);
|
||||
assertTrue("incorrect scale", bNumber.scale() == resScale);
|
||||
assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(a));
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the decimal point to the right; the shift value is positive
|
||||
*/
|
||||
@Test
|
||||
public void testMovePointRightPosLess() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
String b = "123121247898748298842980877981045763478138475679498700";
|
||||
int aScale = 28;
|
||||
int shift = 30;
|
||||
int resScale = 0;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = aNumber.movePointRight(shift);
|
||||
assertTrue("incorrect scale", bNumber.scale() == resScale);
|
||||
assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the decimal point to the right; the shift value is positive
|
||||
*/
|
||||
@Test
|
||||
public void testMovePointRightNeg() {
|
||||
String a = "1231212478987482988429808779810457634781384756794987";
|
||||
int aScale = 28;
|
||||
int shift = -18;
|
||||
int resScale = 46;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
BigDecimal bNumber = aNumber.movePointRight(shift);
|
||||
assertTrue("incorrect scale", bNumber.scale() == resScale);
|
||||
assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(a));
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the decimal point to the right when the scale overflows
|
||||
*/
|
||||
@Test
|
||||
public void testMovePointRightException() {
|
||||
String a = "12312124789874829887348723648726347429808779810457634781384756794987";
|
||||
int aScale = Integer.MAX_VALUE; //2147483647
|
||||
int shift = -18;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
try {
|
||||
aNumber.movePointRight(shift);
|
||||
fail("ArithmeticException has not been caught");
|
||||
} catch (ArithmeticException e) {
|
||||
assertEquals("Improper exception message", "Underflow", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* precision()
|
||||
*/
|
||||
@Test
|
||||
public void testPrecision() {
|
||||
String a = "12312124789874829887348723648726347429808779810457634781384756794987";
|
||||
int aScale = 14;
|
||||
BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
|
||||
int prec = aNumber.precision();
|
||||
assertEquals(68, prec);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,519 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigInteger
|
||||
* Method: add
|
||||
*/
|
||||
public class BigIntegerAddTest {
|
||||
/**
|
||||
* Add two positive numbers of the same length
|
||||
*/
|
||||
@Test
|
||||
public void testCase1() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {11, 22, 33, 44, 55, 66, 77, 11, 22, 33};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two negative numbers of the same length
|
||||
*/
|
||||
@Test
|
||||
public void testCase2() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-12, -23, -34, -45, -56, -67, -78, -12, -23, -33};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two numbers of the same length.
|
||||
* The first one is positive and the second is negative.
|
||||
* The first one is greater in absolute value.
|
||||
*/
|
||||
@Test
|
||||
public void testCase3() {
|
||||
byte aBytes[] = {3, 4, 5, 6, 7, 8, 9};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
byte rBytes[] = {2, 2, 2, 2, 2, 2, 2};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two numbers of the same length.
|
||||
* The first one is negative and the second is positive.
|
||||
* The first one is greater in absolute value.
|
||||
*/
|
||||
@Test
|
||||
public void testCase4() {
|
||||
byte aBytes[] = {3, 4, 5, 6, 7, 8, 9};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
byte rBytes[] = {-3, -3, -3, -3, -3, -3, -2};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two numbers of the same length.
|
||||
* The first is positive and the second is negative.
|
||||
* The first is less in absolute value.
|
||||
*/
|
||||
@Test
|
||||
public void testCase5() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {3, 4, 5, 6, 7, 8, 9};
|
||||
byte rBytes[] = {-3, -3, -3, -3, -3, -3, -2};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two numbers of the same length.
|
||||
* The first one is negative and the second is positive.
|
||||
* The first one is less in absolute value.
|
||||
*/
|
||||
@Test
|
||||
public void testCase6() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {3, 4, 5, 6, 7, 8, 9};
|
||||
byte rBytes[] = {2, 2, 2, 2, 2, 2, 2};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two positive numbers of different length.
|
||||
* The first is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase7() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {1, 2, 3, 4, 15, 26, 37, 41, 52, 63, 74, 15, 26, 37};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two positive numbers of different length.
|
||||
* The second is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase8() {
|
||||
byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
byte rBytes[] = {1, 2, 3, 4, 15, 26, 37, 41, 52, 63, 74, 15, 26, 37};
|
||||
BigInteger aNumber = new BigInteger(aBytes);
|
||||
BigInteger bNumber = new BigInteger(bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two negative numbers of different length.
|
||||
* The first is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase9() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-2, -3, -4, -5, -16, -27, -38, -42, -53, -64, -75, -16, -27, -37};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two negative numbers of different length.
|
||||
* The second is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase10() {
|
||||
byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-2, -3, -4, -5, -16, -27, -38, -42, -53, -64, -75, -16, -27, -37};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two numbers of different length and sign.
|
||||
* The first is positive.
|
||||
* The first is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase11() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {1, 2, 3, 3, -6, -15, -24, -40, -49, -58, -67, -6, -15, -23};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two numbers of different length and sign.
|
||||
* The first is positive.
|
||||
* The second is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase12() {
|
||||
byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two numbers of different length and sign.
|
||||
* The first is negative.
|
||||
* The first is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase13() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two numbers of different length and sign.
|
||||
* The first is negative.
|
||||
* The second is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase14() {
|
||||
byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {1, 2, 3, 3, -6, -15, -24, -40, -49, -58, -67, -6, -15, -23};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two equal numbers of different signs
|
||||
*/
|
||||
@Test
|
||||
public void testCase15() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
byte rBytes[] = {0};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add zero to a number
|
||||
*/
|
||||
@Test
|
||||
public void testCase16() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {0};
|
||||
byte rBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a number to zero
|
||||
*/
|
||||
@Test
|
||||
public void testCase17() {
|
||||
byte aBytes[] = {0};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
byte rBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add zero to zero
|
||||
*/
|
||||
@Test
|
||||
public void testCase18() {
|
||||
byte aBytes[] = {0};
|
||||
byte bBytes[] = {0};
|
||||
byte rBytes[] = {0};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add ZERO to a number
|
||||
*/
|
||||
@Test
|
||||
public void testCase19() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
byte rBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
int aSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = BigInteger.ZERO;
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a number to zero
|
||||
*/
|
||||
@Test
|
||||
public void testCase20() {
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
byte rBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
int bSign = 1;
|
||||
BigInteger aNumber = BigInteger.ZERO;
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add ZERO to ZERO
|
||||
*/
|
||||
@Test
|
||||
public void testCase21() {
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = BigInteger.ZERO;
|
||||
BigInteger bNumber = BigInteger.ZERO;
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add ONE to ONE
|
||||
*/
|
||||
@Test
|
||||
public void testCase22() {
|
||||
byte rBytes[] = {2};
|
||||
BigInteger aNumber = BigInteger.ONE;
|
||||
BigInteger bNumber = BigInteger.ONE;
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add two numbers so that carry is 1
|
||||
*/
|
||||
@Test
|
||||
public void testCase23() {
|
||||
byte aBytes[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
|
||||
byte bBytes[] = {-1, -1, -1, -1, -1, -1, -1, -1};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {1, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -2};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.add(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,454 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigInteger
|
||||
* Method: and
|
||||
*/
|
||||
public class BigIntegerAndTest {
|
||||
/**
|
||||
* And for zero and a positive number
|
||||
*/
|
||||
@Test
|
||||
public void testZeroPos() {
|
||||
byte aBytes[] = {0};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = 0;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for zero and a negative number
|
||||
*/
|
||||
@Test
|
||||
public void testZeroNeg() {
|
||||
byte aBytes[] = {0};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = 0;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for a positive number and zero
|
||||
*/
|
||||
@Test
|
||||
public void testPosZero() {
|
||||
byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
byte bBytes[] = {0};
|
||||
int aSign = 1;
|
||||
int bSign = 0;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for a negative number and zero
|
||||
*/
|
||||
@Test
|
||||
public void testNegPos() {
|
||||
byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
byte bBytes[] = {0};
|
||||
int aSign = -1;
|
||||
int bSign = 0;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for zero and zero
|
||||
*/
|
||||
@Test
|
||||
public void testZeroZero() {
|
||||
byte aBytes[] = {0};
|
||||
byte bBytes[] = {0};
|
||||
int aSign = 0;
|
||||
int bSign = 0;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for zero and one
|
||||
*/
|
||||
@Test
|
||||
public void testZeroOne() {
|
||||
BigInteger aNumber = BigInteger.ZERO;
|
||||
BigInteger bNumber = BigInteger.ONE;
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
assertTrue(result.equals(BigInteger.ZERO));
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for one and one
|
||||
*/
|
||||
@Test
|
||||
public void testOneOne() {
|
||||
BigInteger aNumber = BigInteger.ONE;
|
||||
BigInteger bNumber = BigInteger.ONE;
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
assertTrue(result.equals(BigInteger.ONE));
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for two positive numbers of the same length
|
||||
*/
|
||||
@Test
|
||||
public void testPosPosSameLength() {
|
||||
byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0, -128, 56, 100, 4, 4, 17, 37, 16, 1, 64, 1, 10, 3};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for two positive numbers; the first is longer
|
||||
*/
|
||||
@Test
|
||||
public void testPosPosFirstLonger() {
|
||||
byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0, -2, -76, 88, 44, 1, 2, 17, 35, 16, 9, 2, 5, 6, 21};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for two positive numbers; the first is shorter
|
||||
*/
|
||||
@Test
|
||||
public void testPosPosFirstShorter() {
|
||||
byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0, -2, -76, 88, 44, 1, 2, 17, 35, 16, 9, 2, 5, 6, 21};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for two negative numbers of the same length
|
||||
*/
|
||||
@Test
|
||||
public void testNegNegSameLength() {
|
||||
byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-1, 1, 2, 3, 3, 0, 65, -96, -48, -124, -60, 12, -40, -31, 97};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for two negative numbers; the first is longer
|
||||
*/
|
||||
@Test
|
||||
public void testNegNegFirstLonger() {
|
||||
byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-1, 127, -10, -57, -101, 1, 2, 2, 2, -96, -16, 8, -40, -59, 68, -88, -88, 16, 73};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for two negative numbers; the first is shorter
|
||||
*/
|
||||
@Test
|
||||
public void testNegNegFirstShorter() {
|
||||
byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-1, 127, -10, -57, -101, 1, 2, 2, 2, -96, -16, 8, -40, -59, 68, -88, -88, 16, 73};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for two numbers of different signs and the same length
|
||||
*/
|
||||
@Test
|
||||
public void testPosNegSameLength() {
|
||||
byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {0, -6, -80, 72, 8, 75, 2, -79, 34, 16, -119};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for two numbers of different signs and the same length
|
||||
*/
|
||||
@Test
|
||||
public void testNegPosSameLength() {
|
||||
byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0, -2, 125, -60, -104, 1, 10, 6, 2, 32, 56, 2, 4, 4, 21};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for a negative and a positive numbers; the first is longer
|
||||
*/
|
||||
@Test
|
||||
public void testNegPosFirstLonger() {
|
||||
byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {73, -92, -48, 4, 12, 6, 4, 32, 48, 64, 0, 8, 3};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for a negative and a positive numbers; the first is shorter
|
||||
*/
|
||||
@Test
|
||||
public void testNegPosFirstShorter() {
|
||||
byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0, -128, 9, 56, 100, 0, 0, 1, 1, 90, 1, -32, 0, 10, -126, 21, 82, -31, -95};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for a positive and a negative numbers; the first is longer
|
||||
*/
|
||||
@Test
|
||||
public void testPosNegFirstLonger() {
|
||||
byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {0, -128, 9, 56, 100, 0, 0, 1, 1, 90, 1, -32, 0, 10, -126, 21, 82, -31, -95};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* And for a positive and a negative numbers; the first is shorter
|
||||
*/
|
||||
@Test
|
||||
public void testPosNegFirstShorter() {
|
||||
byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {73, -92, -48, 4, 12, 6, 4, 32, 48, 64, 0, 8, 3};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for a special case
|
||||
*/
|
||||
@Test
|
||||
public void testSpecialCase1() {
|
||||
byte aBytes[] = {-1, -1, -1, -1};
|
||||
byte bBytes[] = {5, -4, -3, -2};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-1, 0, 0, 0, 0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for a special case
|
||||
*/
|
||||
@Test
|
||||
public void testSpecialCase2() {
|
||||
byte aBytes[] = {-51};
|
||||
byte bBytes[] = {-52, -51, -50, -49, -48};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0, -52, -51, -50, -49, 16};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.and(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,567 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigInteger
|
||||
* Methods: abs, compareTo, equals, max, min, negate, signum
|
||||
*/
|
||||
public class BigIntegerCompareTest {
|
||||
/**
|
||||
* abs() for a positive number
|
||||
*/
|
||||
@Test
|
||||
public void testAbsPositive() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger result = aNumber.abs();
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* abs() for a negative number
|
||||
*/
|
||||
@Test
|
||||
public void testAbsNegative() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
int aSign = -1;
|
||||
byte rBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger result = aNumber.abs();
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* compareTo(BigInteger a).
|
||||
* Compare two positive numbers.
|
||||
* The first is greater.
|
||||
*/
|
||||
@Test
|
||||
public void testCompareToPosPos1() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
assertEquals(1, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* compareTo(BigInteger a).
|
||||
* Compare two positive numbers.
|
||||
* The first is less.
|
||||
*/
|
||||
@Test
|
||||
public void testCompareToPosPos2() {
|
||||
byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
assertEquals(-1, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* compareTo(BigInteger a).
|
||||
* Compare two equal positive numbers.
|
||||
*/
|
||||
@Test
|
||||
public void testCompareToEqualPos() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
assertEquals(0, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* compareTo(BigInteger a).
|
||||
* Compare two negative numbers.
|
||||
* The first is greater in absolute value.
|
||||
*/
|
||||
@Test
|
||||
public void testCompareToNegNeg1() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
assertEquals(-1, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* compareTo(BigInteger a).
|
||||
* Compare two negative numbers.
|
||||
* The first is less in absolute value.
|
||||
*/
|
||||
@Test
|
||||
public void testCompareNegNeg2() {
|
||||
byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
assertEquals(1, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* compareTo(BigInteger a).
|
||||
* Compare two equal negative numbers.
|
||||
*/
|
||||
@Test
|
||||
public void testCompareToEqualNeg() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
assertEquals(0, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* compareTo(BigInteger a).
|
||||
* Compare two numbers of different signs.
|
||||
* The first is positive.
|
||||
*/
|
||||
@Test
|
||||
public void testCompareToDiffSigns1() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
assertEquals(1, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* compareTo(BigInteger a).
|
||||
* Compare two numbers of different signs.
|
||||
* The first is negative.
|
||||
*/
|
||||
@Test
|
||||
public void testCompareToDiffSigns2() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
assertEquals(-1, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* compareTo(BigInteger a).
|
||||
* Compare a positive number to ZERO.
|
||||
*/
|
||||
@Test
|
||||
public void testCompareToPosZero() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = BigInteger.ZERO;
|
||||
assertEquals(1, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* compareTo(BigInteger a).
|
||||
* Compare ZERO to a positive number.
|
||||
*/
|
||||
@Test
|
||||
public void testCompareToZeroPos() {
|
||||
byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int bSign = 1;
|
||||
BigInteger aNumber = BigInteger.ZERO;
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
assertEquals(-1, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* compareTo(BigInteger a).
|
||||
* Compare a negative number to ZERO.
|
||||
*/
|
||||
@Test
|
||||
public void testCompareToNegZero() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = -1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = BigInteger.ZERO;
|
||||
assertEquals(-1, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* compareTo(BigInteger a).
|
||||
* Compare ZERO to a negative number.
|
||||
*/
|
||||
@Test
|
||||
public void testCompareToZeroNeg() {
|
||||
byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int bSign = -1;
|
||||
BigInteger aNumber = BigInteger.ZERO;
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
assertEquals(1, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* compareTo(BigInteger a).
|
||||
* Compare ZERO to ZERO.
|
||||
*/
|
||||
@Test
|
||||
public void testCompareToZeroZero() {
|
||||
BigInteger aNumber = BigInteger.ZERO;
|
||||
BigInteger bNumber = BigInteger.ZERO;
|
||||
assertEquals(0, aNumber.compareTo(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* equals(Object obj).
|
||||
* obj is not a BigInteger
|
||||
*/
|
||||
@Test
|
||||
public void testEqualsObject() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
Object obj = new Object();
|
||||
assertFalse(aNumber.equals(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* equals(null).
|
||||
*/
|
||||
@Test
|
||||
public void testEqualsNull() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
assertFalse(aNumber.equals(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* equals(Object obj).
|
||||
* obj is a BigInteger.
|
||||
* numbers are equal.
|
||||
*/
|
||||
@Test
|
||||
public void testEqualsBigIntegerTrue() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
Object bNumber = new BigInteger(bSign, bBytes);
|
||||
assertTrue(aNumber.equals(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* equals(Object obj).
|
||||
* obj is a BigInteger.
|
||||
* numbers are not equal.
|
||||
*/
|
||||
@Test
|
||||
public void testEqualsBigIntegerFalse() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte bBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
Object bNumber = new BigInteger(bSign, bBytes);
|
||||
assertFalse(aNumber.equals(bNumber));
|
||||
}
|
||||
|
||||
/**
|
||||
* max(BigInteger val).
|
||||
* the first is greater.
|
||||
*/
|
||||
@Test
|
||||
public void testMaxGreater() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte bBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.max(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertTrue("incorrect sign", result.signum() == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* max(BigInteger val).
|
||||
* the first is less.
|
||||
*/
|
||||
@Test
|
||||
public void testMaxLess() {
|
||||
byte aBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.max(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertTrue("incorrect sign", result.signum() == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* max(BigInteger val).
|
||||
* numbers are equal.
|
||||
*/
|
||||
@Test
|
||||
public void testMaxEqual() {
|
||||
byte aBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte bBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.max(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* max(BigInteger val).
|
||||
* max of negative and ZERO.
|
||||
*/
|
||||
@Test
|
||||
public void testMaxNegZero() {
|
||||
byte aBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = -1;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = BigInteger.ZERO;
|
||||
BigInteger result = aNumber.max(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertTrue("incorrect sign", result.signum() == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* min(BigInteger val).
|
||||
* the first is greater.
|
||||
*/
|
||||
@Test
|
||||
public void testMinGreater() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte bBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.min(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* min(BigInteger val).
|
||||
* the first is less.
|
||||
*/
|
||||
@Test
|
||||
public void testMinLess() {
|
||||
byte aBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte bBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.min(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* min(BigInteger val).
|
||||
* numbers are equal.
|
||||
*/
|
||||
@Test
|
||||
public void testMinEqual() {
|
||||
byte aBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte bBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.min(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertTrue("incorrect sign", result.signum() == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* max(BigInteger val).
|
||||
* min of positive and ZERO.
|
||||
*/
|
||||
@Test
|
||||
public void testMinPosZero() {
|
||||
byte aBytes[] = {45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = BigInteger.ZERO;
|
||||
BigInteger result = aNumber.min(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertTrue("incorrect sign", result.signum() == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* negate() a positive number.
|
||||
*/
|
||||
@Test
|
||||
public void testNegatePositive() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {-13, -57, -101, 1, 75, -90, -46, -92, -4, 14, -36, -27, -4, -91};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger result = aNumber.negate();
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertTrue("incorrect sign", result.signum() == -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* negate() a negative number.
|
||||
*/
|
||||
@Test
|
||||
public void testNegateNegative() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = -1;
|
||||
byte rBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger result = aNumber.negate();
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertTrue("incorrect sign", result.signum() == 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* negate() ZERO.
|
||||
*/
|
||||
@Test
|
||||
public void testNegateZero() {
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = BigInteger.ZERO;
|
||||
BigInteger result = aNumber.negate();
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* signum() of a positive number.
|
||||
*/
|
||||
@Test
|
||||
public void testSignumPositive() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* signum() of a negative number.
|
||||
*/
|
||||
@Test
|
||||
public void testSignumNegative() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
int aSign = -1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* signum() of ZERO.
|
||||
*/
|
||||
@Test
|
||||
public void testSignumZero() {
|
||||
BigInteger aNumber = BigInteger.ZERO;
|
||||
assertEquals("incorrect sign", 0, aNumber.signum());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,819 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Random;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigInteger
|
||||
* Constructors: BigInteger(byte[] a), BigInteger(int sign, byte[] a),
|
||||
* BigInteger(String val, int radix)
|
||||
*/
|
||||
public class BigIntegerConstructorsTest {
|
||||
/**
|
||||
* Create a number from an array of bytes.
|
||||
* Verify an exception thrown if an array is zero bytes long
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorBytesException() {
|
||||
byte aBytes[] = {};
|
||||
try {
|
||||
new BigInteger(aBytes);
|
||||
fail("NumberFormatException has not been caught");
|
||||
} catch (NumberFormatException e) {
|
||||
assertEquals("Improper exception message", "Zero length BigInteger", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from an array of bytes.
|
||||
* The number fits in an array of integers.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorBytesPositive1() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte rBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
BigInteger aNumber = new BigInteger(aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from an array of bytes.
|
||||
* The number fits in an integer.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorBytesPositive2() {
|
||||
byte aBytes[] = {12, 56, 100};
|
||||
byte rBytes[] = {12, 56, 100};
|
||||
BigInteger aNumber = new BigInteger(aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from an array of bytes.
|
||||
* The number of bytes is 4.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorBytesPositive3() {
|
||||
byte aBytes[] = {127, 56, 100, -1};
|
||||
byte rBytes[] = {127, 56, 100, -1};
|
||||
BigInteger aNumber = new BigInteger(aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from an array of bytes.
|
||||
* The number of bytes is multiple of 4.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorBytesPositive() {
|
||||
byte aBytes[] = {127, 56, 100, -1, 14, 75, -24, -100};
|
||||
byte rBytes[] = {127, 56, 100, -1, 14, 75, -24, -100};
|
||||
BigInteger aNumber = new BigInteger(aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a negative number from an array of bytes.
|
||||
* The number fits in an array of integers.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorBytesNegative1() {
|
||||
byte aBytes[] = {-12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
byte rBytes[] = {-12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, 3, 91};
|
||||
BigInteger aNumber = new BigInteger(aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a negative number from an array of bytes.
|
||||
* The number fits in an integer.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorBytesNegative2() {
|
||||
byte aBytes[] = {-12, 56, 100};
|
||||
byte rBytes[] = {-12, 56, 100};
|
||||
BigInteger aNumber = new BigInteger(aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a negative number from an array of bytes.
|
||||
* The number of bytes is 4.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorBytesNegative3() {
|
||||
byte aBytes[] = {-128, -12, 56, 100};
|
||||
byte rBytes[] = {-128, -12, 56, 100};
|
||||
BigInteger aNumber = new BigInteger(aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a negative number from an array of bytes.
|
||||
* The number of bytes is multiple of 4.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorBytesNegative4() {
|
||||
byte aBytes[] = {-128, -12, 56, 100, -13, 56, 93, -78};
|
||||
byte rBytes[] = {-128, -12, 56, 100, -13, 56, 93, -78};
|
||||
BigInteger aNumber = new BigInteger(aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a zero number from an array of zero bytes.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorBytesZero() {
|
||||
byte aBytes[] = {0, 0, 0, -0, +0, 0, -0};
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a number from a sign and an array of bytes.
|
||||
* Verify an exception thrown if a sign has improper value.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesException1() {
|
||||
byte aBytes[] = {123, 45, -3, -76};
|
||||
int aSign = 3;
|
||||
try {
|
||||
new BigInteger(aSign, aBytes);
|
||||
fail("NumberFormatException has not been caught");
|
||||
} catch (NumberFormatException e) {
|
||||
assertEquals("Improper exception message", "Invalid signum value", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a number from a sign and an array of bytes.
|
||||
* Verify an exception thrown if the array contains non-zero bytes while the sign is 0.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesException2() {
|
||||
byte aBytes[] = {123, 45, -3, -76};
|
||||
int aSign = 0;
|
||||
try {
|
||||
new BigInteger(aSign, aBytes);
|
||||
fail("NumberFormatException has not been caught");
|
||||
} catch (NumberFormatException e) {
|
||||
assertEquals("Improper exception message", "signum-magnitude mismatch", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from a sign and an array of bytes.
|
||||
* The number fits in an array of integers.
|
||||
* The most significant byte is positive.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesPositive1() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from a sign and an array of bytes.
|
||||
* The number fits in an array of integers.
|
||||
* The most significant byte is negative.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesPositive2() {
|
||||
byte aBytes[] = {-12, 56, 100, -2, -76, 89, 45, 91, 3, -15};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {0, -12, 56, 100, -2, -76, 89, 45, 91, 3, -15};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from a sign and an array of bytes.
|
||||
* The number fits in an integer.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesPositive3() {
|
||||
byte aBytes[] = {-12, 56, 100};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {0, -12, 56, 100};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from a sign and an array of bytes.
|
||||
* The number of bytes is 4.
|
||||
* The most significant byte is positive.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesPositive4() {
|
||||
byte aBytes[] = {127, 56, 100, -2};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {127, 56, 100, -2};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from a sign and an array of bytes.
|
||||
* The number of bytes is 4.
|
||||
* The most significant byte is negative.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesPositive5() {
|
||||
byte aBytes[] = {-127, 56, 100, -2};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {0, -127, 56, 100, -2};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from a sign and an array of bytes.
|
||||
* The number of bytes is multiple of 4.
|
||||
* The most significant byte is positive.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesPositive6() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 23, -101};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 23, -101};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from a sign and an array of bytes.
|
||||
* The number of bytes is multiple of 4.
|
||||
* The most significant byte is negative.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesPositive7() {
|
||||
byte aBytes[] = {-12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 23, -101};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {0, -12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 23, -101};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a negative number from a sign and an array of bytes.
|
||||
* The number fits in an array of integers.
|
||||
* The most significant byte is positive.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesNegative1() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15};
|
||||
int aSign = -1;
|
||||
byte rBytes[] = {-13, -57, -101, 1, 75, -90, -46, -92, -4, 15};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a negative number from a sign and an array of bytes.
|
||||
* The number fits in an array of integers.
|
||||
* The most significant byte is negative.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesNegative2() {
|
||||
byte aBytes[] = {-12, 56, 100, -2, -76, 89, 45, 91, 3, -15};
|
||||
int aSign = -1;
|
||||
byte rBytes[] = {-1, 11, -57, -101, 1, 75, -90, -46, -92, -4, 15};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a negative number from a sign and an array of bytes.
|
||||
* The number fits in an integer.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesNegative3() {
|
||||
byte aBytes[] = {-12, 56, 100};
|
||||
int aSign = -1;
|
||||
byte rBytes[] = {-1, 11, -57, -100};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a negative number from a sign and an array of bytes.
|
||||
* The number of bytes is 4.
|
||||
* The most significant byte is positive.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesNegative4() {
|
||||
byte aBytes[] = {127, 56, 100, -2};
|
||||
int aSign = -1;
|
||||
byte rBytes[] = {-128, -57, -101, 2};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a negative number from a sign and an array of bytes.
|
||||
* The number of bytes is 4.
|
||||
* The most significant byte is negative.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesNegative5() {
|
||||
byte aBytes[] = {-127, 56, 100, -2};
|
||||
int aSign = -1;
|
||||
byte rBytes[] = {-1, 126, -57, -101, 2};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a negative number from a sign and an array of bytes.
|
||||
* The number of bytes is multiple of 4.
|
||||
* The most significant byte is positive.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesNegative6() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 23, -101};
|
||||
int aSign = -1;
|
||||
byte rBytes[] = {-13, -57, -101, 1, 75, -90, -46, -92, -4, 14, -24, 101};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a negative number from a sign and an array of bytes.
|
||||
* The number of bytes is multiple of 4.
|
||||
* The most significant byte is negative.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesNegative7() {
|
||||
byte aBytes[] = {-12, 56, 100, -2, -76, 89, 45, 91, 3, -15, 23, -101};
|
||||
int aSign = -1;
|
||||
byte rBytes[] = {-1, 11, -57, -101, 1, 75, -90, -46, -92, -4, 14, -24, 101};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a zero number from a sign and an array of zero bytes.
|
||||
* The sign is -1.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesZero1() {
|
||||
byte aBytes[] = {-0, 0, +0, 0, 0, 00, 000};
|
||||
int aSign = -1;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a zero number from a sign and an array of zero bytes.
|
||||
* The sign is 0.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesZero2() {
|
||||
byte aBytes[] = {-0, 0, +0, 0, 0, 00, 000};
|
||||
int aSign = 0;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a zero number from a sign and an array of zero bytes.
|
||||
* The sign is 1.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesZero3() {
|
||||
byte aBytes[] = {-0, 0, +0, 0, 0, 00, 000};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a zero number from a sign and an array of zero length.
|
||||
* The sign is -1.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesZeroNull1() {
|
||||
byte aBytes[] = {};
|
||||
int aSign = -1;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a zero number from a sign and an array of zero length.
|
||||
* The sign is 0.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesZeroNull2() {
|
||||
byte aBytes[] = {};
|
||||
int aSign = 0;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a zero number from a sign and an array of zero length.
|
||||
* The sign is 1.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorSignBytesZeroNull3() {
|
||||
byte aBytes[] = {};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a number from a string value and radix.
|
||||
* Verify an exception thrown if a radix is out of range
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorStringException1() {
|
||||
String value = "9234853876401";
|
||||
int radix = 45;
|
||||
try {
|
||||
new BigInteger(value, radix);
|
||||
fail("NumberFormatException has not been caught");
|
||||
} catch (NumberFormatException e) {
|
||||
assertEquals("Improper exception message", "Radix out of range", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a number from a string value and radix.
|
||||
* Verify an exception thrown if the string starts with a space.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorStringException2() {
|
||||
String value = " 9234853876401";
|
||||
int radix = 10;
|
||||
try {
|
||||
new BigInteger(value, radix);
|
||||
fail("NumberFormatException has not been caught");
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a number from a string value and radix.
|
||||
* Verify an exception thrown if the string contains improper characters.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorStringException3() {
|
||||
String value = "92348$*#78987";
|
||||
int radix = 34;
|
||||
try {
|
||||
new BigInteger(value, radix);
|
||||
fail("NumberFormatException has not been caught");
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a number from a string value and radix.
|
||||
* Verify an exception thrown if some digits are greater than radix.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorStringException4() {
|
||||
String value = "98zv765hdsaiy";
|
||||
int radix = 20;
|
||||
try {
|
||||
new BigInteger(value, radix);
|
||||
fail("NumberFormatException has not been caught");
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from a string value and radix 2.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorStringRadix2() {
|
||||
String value = "10101010101010101";
|
||||
int radix = 2;
|
||||
byte rBytes[] = {1, 85, 85};
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from a string value and radix 8.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorStringRadix8() {
|
||||
String value = "76356237071623450";
|
||||
int radix = 8;
|
||||
byte rBytes[] = {7, -50, -28, -8, -25, 39, 40};
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from a string value and radix 10.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorStringRadix10() {
|
||||
String value = "987328901348934898";
|
||||
int radix = 10;
|
||||
byte rBytes[] = {13, -77, -78, 103, -103, 97, 68, -14};
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from a string value and radix 16.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorStringRadix16() {
|
||||
String value = "fe2340a8b5ce790";
|
||||
int radix = 16;
|
||||
byte rBytes[] = {15, -30, 52, 10, -117, 92, -25, -112};
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a positive number from a string value and radix 36.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorStringRadix36() {
|
||||
String value = "skdjgocvhdjfkl20jndjkf347ejg457";
|
||||
int radix = 36;
|
||||
byte rBytes[] = {0, -12, -116, 112, -105, 12, -36, 66, 108, 66, -20, -37, -15, 108, -7, 52, -99, -109, -8, -45, -5};
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a negative number from a string value and radix 10.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorStringRadix10Negative() {
|
||||
String value = "-234871376037";
|
||||
int radix = 36;
|
||||
byte rBytes[] = {-4, 48, 71, 62, -76, 93, -105, 13};
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a zero number from a string value and radix 36.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorStringRadix10Zero() {
|
||||
String value = "-00000000000000";
|
||||
int radix = 10;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a random number of 75 bits length.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorRandom() {
|
||||
int bitLen = 75;
|
||||
Random rnd = new Random();
|
||||
BigInteger aNumber = new BigInteger(bitLen, rnd);
|
||||
assertTrue("incorrect bitLength", aNumber.bitLength() <= bitLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a prime number of 25 bits length.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorPrime() {
|
||||
int bitLen = 25;
|
||||
Random rnd = new Random();
|
||||
BigInteger aNumber = new BigInteger(bitLen, 80, rnd);
|
||||
assertTrue("incorrect bitLength", aNumber.bitLength() == bitLen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a prime number of 2 bits length.
|
||||
*/
|
||||
@Test
|
||||
public void testConstructorPrime2() {
|
||||
int bitLen = 2;
|
||||
Random rnd = new Random();
|
||||
BigInteger aNumber = new BigInteger(bitLen, 80, rnd);
|
||||
assertTrue("incorrect bitLength", aNumber.bitLength() == bitLen);
|
||||
int num = aNumber.intValue();
|
||||
assertTrue("incorrect value", num == 2 || num == 3);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,851 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigInteger
|
||||
* Methods: intValue, longValue, toByteArray(), valueOf(long val),
|
||||
* floatValue(), doubleValue()
|
||||
*/
|
||||
public class BigIntegerConvertTest {
|
||||
/**
|
||||
* Return the double value of ZERO.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValueZero() {
|
||||
String a = "0";
|
||||
double result = 0.0;
|
||||
double aNumber = new BigInteger(a).doubleValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a double value.
|
||||
* The number's length is less than 64 bits.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValuePositive1() {
|
||||
String a = "27467238945";
|
||||
double result = 2.7467238945E10;
|
||||
double aNumber = new BigInteger(a).doubleValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a double value.
|
||||
* The number's bit length is inside [63, 1024].
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValuePositive2() {
|
||||
String a = "2746723894572364578265426346273456972";
|
||||
double result = 2.7467238945723645E36;
|
||||
double aNumber = new BigInteger(a).doubleValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative number to a double value.
|
||||
* The number's bit length is less than 64 bits.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValueNegative1() {
|
||||
String a = "-27467238945";
|
||||
double result = -2.7467238945E10;
|
||||
double aNumber = new BigInteger(a).doubleValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative number to a double value.
|
||||
* The number's bit length is inside [63, 1024].
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValueNegative2() {
|
||||
String a = "-2746723894572364578265426346273456972";
|
||||
double result = -2.7467238945723645E36;
|
||||
double aNumber = new BigInteger(a).doubleValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a double value.
|
||||
* Rounding is needed.
|
||||
* The rounding bit is 1 and the next bit to the left is 1.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValuePosRounded1() {
|
||||
byte[] a = {-128, 1, 2, 3, 4, 5, 60, 23, 1, -3, -5};
|
||||
int aSign = 1;
|
||||
double result = 1.54747264387948E26;
|
||||
double aNumber = new BigInteger(aSign, a).doubleValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a double value.
|
||||
* Rounding is needed.
|
||||
* The rounding bit is 1 and the next bit to the left is 0
|
||||
* but some of dropped bits are 1s.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValuePosRounded2() {
|
||||
byte[] a = {-128, 1, 2, 3, 4, 5, 36, 23, 1, -3, -5};
|
||||
int aSign = 1;
|
||||
double result = 1.547472643879479E26;
|
||||
double aNumber = new BigInteger(aSign, a).doubleValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
/**
|
||||
* Convert a positive number to a double value.
|
||||
* Rounding is NOT needed.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValuePosNotRounded() {
|
||||
byte[] a = {-128, 1, 2, 3, 4, 5, -128, 23, 1, -3, -5};
|
||||
int aSign = 1;
|
||||
double result = 1.5474726438794828E26;
|
||||
double aNumber = new BigInteger(aSign, a).doubleValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a double value.
|
||||
* Rounding is needed.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValueNegRounded1() {
|
||||
byte[] a = {-128, 1, 2, 3, 4, 5, 60, 23, 1, -3, -5};
|
||||
int aSign = -1;
|
||||
double result = -1.54747264387948E26;
|
||||
double aNumber = new BigInteger(aSign, a).doubleValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a double value.
|
||||
* Rounding is needed.
|
||||
* The rounding bit is 1 and the next bit to the left is 0
|
||||
* but some of dropped bits are 1s.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValueNegRounded2() {
|
||||
byte[] a = {-128, 1, 2, 3, 4, 5, 36, 23, 1, -3, -5};
|
||||
int aSign = -1;
|
||||
double result = -1.547472643879479E26;
|
||||
double aNumber = new BigInteger(aSign, a).doubleValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a double value.
|
||||
* Rounding is NOT needed.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValueNegNotRounded() {
|
||||
byte[] a = {-128, 1, 2, 3, 4, 5, -128, 23, 1, -3, -5};
|
||||
int aSign = -1;
|
||||
double result = -1.5474726438794828E26;
|
||||
double aNumber = new BigInteger(aSign, a).doubleValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a double value.
|
||||
* The exponent is 1023 and the mantissa is all 1s.
|
||||
* The rounding bit is 0.
|
||||
* The result is Double.MAX_VALUE.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValuePosMaxValue() {
|
||||
byte[] a = {0, -1, -1, -1, -1, -1, -1, -8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
};
|
||||
int aSign = 1;
|
||||
double aNumber = new BigInteger(aSign, a).doubleValue();
|
||||
assertTrue(aNumber == Double.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative number to a double value.
|
||||
* The exponent is 1023 and the mantissa is all 1s.
|
||||
* The result is -Double.MAX_VALUE.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValueNegMaxValue() {
|
||||
byte[] a = {0, -1, -1, -1, -1, -1, -1, -8, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
};
|
||||
int aSign = -1;
|
||||
double aNumber = new BigInteger(aSign, a).doubleValue();
|
||||
assertTrue(aNumber == -Double.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a double value.
|
||||
* The exponent is 1023 and the mantissa is all 1s.
|
||||
* The rounding bit is 1.
|
||||
* The result is Double.POSITIVE_INFINITY.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValuePositiveInfinity1() {
|
||||
byte[] a = {-1, -1, -1, -1, -1, -1, -1, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
int aSign = 1;
|
||||
double aNumber = new BigInteger(aSign, a).doubleValue();
|
||||
assertTrue(aNumber == Double.POSITIVE_INFINITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a double value.
|
||||
* The number's bit length is greater than 1024.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValuePositiveInfinity2() {
|
||||
String a = "2746723894572364578265426346273456972283746872364768676747462342342342342342342342323423423423423423426767456345745293762384756238475634563456845634568934568347586346578648576478568456457634875673845678456786587345873645767456834756745763457863485768475678465783456702897830296720476846578634576384567845678346573465786457863";
|
||||
double aNumber = new BigInteger(a).doubleValue();
|
||||
assertTrue(aNumber == Double.POSITIVE_INFINITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative number to a double value.
|
||||
* The number's bit length is greater than 1024.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValueNegativeInfinity1() {
|
||||
String a = "-2746723894572364578265426346273456972283746872364768676747462342342342342342342342323423423423423423426767456345745293762384756238475634563456845634568934568347586346578648576478568456457634875673845678456786587345873645767456834756745763457863485768475678465783456702897830296720476846578634576384567845678346573465786457863";
|
||||
double aNumber = new BigInteger(a).doubleValue();
|
||||
assertTrue(aNumber == Double.NEGATIVE_INFINITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative number to a double value.
|
||||
* The exponent is 1023 and the mantissa is all 0s.
|
||||
* The rounding bit is 0.
|
||||
* The result is Double.NEGATIVE_INFINITY.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValueNegativeInfinity2() {
|
||||
byte[] a = {-1, -1, -1, -1, -1, -1, -1, -8, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
int aSign = -1;
|
||||
double aNumber = new BigInteger(aSign, a).doubleValue();
|
||||
assertTrue(aNumber == Double.NEGATIVE_INFINITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a double value.
|
||||
* The exponent is 1023 and the mantissa is all 0s
|
||||
* but the 54th bit (implicit) is 1.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValuePosMantissaIsZero() {
|
||||
byte[] a = {-128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
int aSign = 1;
|
||||
double result = 8.98846567431158E307;
|
||||
double aNumber = new BigInteger(aSign, a).doubleValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a double value.
|
||||
* The exponent is 1023 and the mantissa is all 0s
|
||||
* but the 54th bit (implicit) is 1.
|
||||
*/
|
||||
@Test
|
||||
public void testDoubleValueNegMantissaIsZero() {
|
||||
byte[] a = {-128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
int aSign = -1;
|
||||
double aNumber = new BigInteger(aSign, a).doubleValue();
|
||||
assertTrue(aNumber == -8.98846567431158E307);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the float value of ZERO.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueZero() {
|
||||
String a = "0";
|
||||
float result = 0.0f;
|
||||
float aNumber = new BigInteger(a).floatValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a float value.
|
||||
* The number's length is less than 32 bits.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValuePositive1() {
|
||||
String a = "27467238";
|
||||
float result = 2.7467238E7f;
|
||||
float aNumber = new BigInteger(a).floatValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a float value.
|
||||
* The number's bit length is inside [32, 127].
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValuePositive2() {
|
||||
String a = "27467238945723645782";
|
||||
float result = 2.7467239E19f;
|
||||
float aNumber = new BigInteger(a).floatValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative number to a float value.
|
||||
* The number's bit length is less than 32 bits.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueNegative1() {
|
||||
String a = "-27467238";
|
||||
float result = -2.7467238E7f;
|
||||
float aNumber = new BigInteger(a).floatValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative number to a doufloatble value.
|
||||
* The number's bit length is inside [63, 1024].
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueNegative2() {
|
||||
String a = "-27467238945723645782";
|
||||
float result = -2.7467239E19f;
|
||||
float aNumber = new BigInteger(a).floatValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a float value.
|
||||
* Rounding is needed.
|
||||
* The rounding bit is 1 and the next bit to the left is 1.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValuePosRounded1() {
|
||||
byte[] a = {-128, 1, -1, -4, 4, 5, 60, 23, 1, -3, -5};
|
||||
int aSign = 1;
|
||||
float result = 1.5475195E26f;
|
||||
float aNumber = new BigInteger(aSign, a).floatValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a float value.
|
||||
* Rounding is needed.
|
||||
* The rounding bit is 1 and the next bit to the left is 0
|
||||
* but some of dropped bits are 1s.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValuePosRounded2() {
|
||||
byte[] a = {-128, 1, 2, -128, 4, 5, 60, 23, 1, -3, -5};
|
||||
int aSign = 1;
|
||||
float result = 1.5474728E26f;
|
||||
float aNumber = new BigInteger(aSign, a).floatValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
/**
|
||||
* Convert a positive number to a float value.
|
||||
* Rounding is NOT needed.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValuePosNotRounded() {
|
||||
byte[] a = {-128, 1, 2, 3, 4, 5, 60, 23, 1, -3, -5};
|
||||
int aSign = 1;
|
||||
float result = 1.5474726E26f;
|
||||
float aNumber = new BigInteger(aSign, a).floatValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a float value.
|
||||
* Rounding is needed.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueNegRounded1() {
|
||||
byte[] a = {-128, 1, -1, -4, 4, 5, 60, 23, 1, -3, -5};
|
||||
int aSign = -1;
|
||||
float result = -1.5475195E26f;
|
||||
float aNumber = new BigInteger(aSign, a).floatValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a float value.
|
||||
* Rounding is needed.
|
||||
* The rounding bit is 1 and the next bit to the left is 0
|
||||
* but some of dropped bits are 1s.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueNegRounded2() {
|
||||
byte[] a = {-128, 1, 2, -128, 4, 5, 60, 23, 1, -3, -5};
|
||||
int aSign = -1;
|
||||
float result = -1.5474728E26f;
|
||||
float aNumber = new BigInteger(aSign, a).floatValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a float value.
|
||||
* Rounding is NOT needed.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueNegNotRounded() {
|
||||
byte[] a = {-128, 1, 2, 3, 4, 5, 60, 23, 1, -3, -5};
|
||||
int aSign = -1;
|
||||
float result = -1.5474726E26f;
|
||||
float aNumber = new BigInteger(aSign, a).floatValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a float value.
|
||||
* The exponent is 1023 and the mantissa is all 1s.
|
||||
* The rounding bit is 0.
|
||||
* The result is Float.MAX_VALUE.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValuePosMaxValue() {
|
||||
byte[] a = {0, -1, -1, -1, 0, -1, -1, -8, -1, -1, -1, -1, -1, -1, -1, -1, -1};
|
||||
int aSign = 1;
|
||||
float aNumber = new BigInteger(aSign, a).floatValue();
|
||||
assertTrue(aNumber == Float.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative number to a float value.
|
||||
* The exponent is 1023 and the mantissa is all 1s.
|
||||
* The rounding bit is 0.
|
||||
* The result is -Float.MAX_VALUE.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueNegMaxValue() {
|
||||
byte[] a = {0, -1, -1, -1, 0, -1, -1, -8, -1, -1, -1, -1, -1, -1, -1, -1, -1};
|
||||
int aSign = -1;
|
||||
float aNumber = new BigInteger(aSign, a).floatValue();
|
||||
assertTrue(aNumber == -Float.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a float value.
|
||||
* The exponent is 1023 and the mantissa is all 1s.
|
||||
* The rounding bit is 1.
|
||||
* The result is Float.POSITIVE_INFINITY.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValuePositiveInfinity1() {
|
||||
byte[] a = {0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
|
||||
int aSign = 1;
|
||||
float aNumber = new BigInteger(aSign, a).floatValue();
|
||||
assertTrue(aNumber == Float.POSITIVE_INFINITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a float value.
|
||||
* The number's bit length is greater than 127.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValuePositiveInfinity2() {
|
||||
String a = "2746723894572364578265426346273456972283746872364768676747462342342342342342342342323423423423423423426767456345745293762384756238475634563456845634568934568347586346578648576478568456457634875673845678456786587345873645767456834756745763457863485768475678465783456702897830296720476846578634576384567845678346573465786457863";
|
||||
float aNumber = new BigInteger(a).floatValue();
|
||||
assertTrue(aNumber == Float.POSITIVE_INFINITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative number to a float value.
|
||||
* The number's bit length is greater than 127.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueNegativeInfinity1() {
|
||||
String a = "-2746723894572364578265426346273456972283746872364768676747462342342342342342342342323423423423423423426767456345745293762384756238475634563456845634568934568347586346578648576478568456457634875673845678456786587345873645767456834756745763457863485768475678465783456702897830296720476846578634576384567845678346573465786457863";
|
||||
float aNumber = new BigInteger(a).floatValue();
|
||||
assertTrue(aNumber == Float.NEGATIVE_INFINITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative number to a float value.
|
||||
* The exponent is 1023 and the mantissa is all 0s.
|
||||
* The rounding bit is 0.
|
||||
* The result is Float.NEGATIVE_INFINITY.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueNegativeInfinity2() {
|
||||
byte[] a = {0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
|
||||
int aSign = -1;
|
||||
float aNumber = new BigInteger(aSign, a).floatValue();
|
||||
assertTrue(aNumber == Float.NEGATIVE_INFINITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a float value.
|
||||
* The exponent is 1023 and the mantissa is all 0s
|
||||
* but the 54th bit (implicit) is 1.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValuePosMantissaIsZero() {
|
||||
byte[] a = {-128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int aSign = 1;
|
||||
float result = 1.7014118E38f;
|
||||
float aNumber = new BigInteger(aSign, a).floatValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive number to a double value.
|
||||
* The exponent is 1023 and the mantissa is all 0s
|
||||
* but the 54th bit (implicit) is 1.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueNegMantissaIsZero() {
|
||||
byte[] a = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int aSign = -1;
|
||||
float aNumber = new BigInteger(aSign, a).floatValue();
|
||||
assertTrue(aNumber == Float.NEGATIVE_INFINITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative number to a float value.
|
||||
* The number's bit length is less than 32 bits.
|
||||
*/
|
||||
@Test
|
||||
public void testFloatValueBug2482() {
|
||||
String a = "2147483649";
|
||||
float result = 2.14748365E9f;
|
||||
float aNumber = new BigInteger(a).floatValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive BigInteger to an integer value.
|
||||
* The low digit is positive
|
||||
*/
|
||||
@Test
|
||||
public void testIntValuePositive1() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3};
|
||||
int resInt = 1496144643;
|
||||
int aNumber = new BigInteger(aBytes).intValue();
|
||||
assertTrue(aNumber == resInt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive BigInteger to an integer value.
|
||||
* The low digit is positive
|
||||
*/
|
||||
@Test
|
||||
public void testIntValuePositive2() {
|
||||
byte aBytes[] = {12, 56, 100};
|
||||
int resInt = 800868;
|
||||
int aNumber = new BigInteger(aBytes).intValue();
|
||||
assertTrue(aNumber == resInt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a positive BigInteger to an integer value.
|
||||
* The low digit is negative.
|
||||
*/
|
||||
@Test
|
||||
public void testIntValuePositive3() {
|
||||
byte aBytes[] = {56, 13, 78, -12, -5, 56, 100};
|
||||
int sign = 1;
|
||||
int resInt = -184862620;
|
||||
int aNumber = new BigInteger(sign, aBytes).intValue();
|
||||
assertTrue(aNumber == resInt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative BigInteger to an integer value.
|
||||
* The low digit is negative.
|
||||
*/
|
||||
@Test
|
||||
public void testIntValueNegative1() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, -128, 45, 91, 3};
|
||||
int sign = -1;
|
||||
int resInt = 2144511229;
|
||||
int aNumber = new BigInteger(sign, aBytes).intValue();
|
||||
assertTrue(aNumber == resInt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative BigInteger to an integer value.
|
||||
* The low digit is negative.
|
||||
*/
|
||||
@Test
|
||||
public void testIntValueNegative2() {
|
||||
byte aBytes[] = {-12, 56, 100};
|
||||
int result = -771996;
|
||||
int aNumber = new BigInteger(aBytes).intValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a negative BigInteger to an integer value.
|
||||
* The low digit is positive.
|
||||
*/
|
||||
@Test
|
||||
public void testIntValueNegative3() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 127, 45, 91, 3};
|
||||
int sign = -1;
|
||||
int resInt = -2133678851;
|
||||
int aNumber = new BigInteger(sign, aBytes).intValue();
|
||||
assertTrue(aNumber == resInt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a BigInteger to a positive long value
|
||||
* The BigInteger is longer than int.
|
||||
*/
|
||||
@Test
|
||||
public void testLongValuePositive1() {
|
||||
byte aBytes[] = {12, 56, 100, -2, -76, 89, 45, 91, 3, 120, -34, -12, 45, 98};
|
||||
long result = 3268209772258930018L;
|
||||
long aNumber = new BigInteger(aBytes).longValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a number to a positive long value
|
||||
* The number fits in a long.
|
||||
*/
|
||||
@Test
|
||||
public void testLongValuePositive2() {
|
||||
byte aBytes[] = {12, 56, 100, 18, -105, 34, -18, 45};
|
||||
long result = 880563758158769709L;
|
||||
long aNumber = new BigInteger(aBytes).longValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a number to a negative long value
|
||||
* The BigInteger is longer than int.
|
||||
*/
|
||||
@Test
|
||||
public void testLongValueNegative1() {
|
||||
byte aBytes[] = {12, -1, 100, -2, -76, -128, 45, 91, 3};
|
||||
long result = -43630045168837885L;
|
||||
long aNumber = new BigInteger(aBytes).longValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a number to a negative long value
|
||||
* The number fits in a long.
|
||||
*/
|
||||
@Test
|
||||
public void testLongValueNegative2() {
|
||||
byte aBytes[] = {-12, 56, 100, 45, -101, 45, 98};
|
||||
long result = -3315696807498398L;
|
||||
long aNumber = new BigInteger(aBytes).longValue();
|
||||
assertTrue(aNumber == result);
|
||||
}
|
||||
|
||||
/**
|
||||
* valueOf (long val): convert Integer.MAX_VALUE to a BigInteger.
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfIntegerMax() {
|
||||
long longVal = Integer.MAX_VALUE;
|
||||
BigInteger aNumber = BigInteger.valueOf(longVal);
|
||||
byte rBytes[] = {127, -1, -1, -1};
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* valueOf (long val): convert Integer.MIN_VALUE to a BigInteger.
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfIntegerMin() {
|
||||
long longVal = Integer.MIN_VALUE;
|
||||
BigInteger aNumber = BigInteger.valueOf(longVal);
|
||||
byte rBytes[] = {-128, 0, 0, 0};
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* valueOf (long val): convert Long.MAX_VALUE to a BigInteger.
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfLongMax() {
|
||||
long longVal = Long.MAX_VALUE;
|
||||
BigInteger aNumber = BigInteger.valueOf(longVal);
|
||||
byte rBytes[] = {127, -1, -1, -1, -1, -1, -1, -1};
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* valueOf (long val): convert Long.MIN_VALUE to a BigInteger.
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfLongMin() {
|
||||
long longVal = Long.MIN_VALUE;
|
||||
BigInteger aNumber = BigInteger.valueOf(longVal);
|
||||
byte rBytes[] = {-128, 0, 0, 0, 0, 0, 0, 0};
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* valueOf (long val): convert a positive long value to a BigInteger.
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfLongPositive1() {
|
||||
long longVal = 268209772258930018L;
|
||||
BigInteger aNumber = BigInteger.valueOf(longVal);
|
||||
byte rBytes[] = {3, -72, -33, 93, -24, -56, 45, 98};
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* valueOf (long val): convert a positive long value to a BigInteger.
|
||||
* The long value fits in integer.
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfLongPositive2() {
|
||||
long longVal = 58930018L;
|
||||
BigInteger aNumber = BigInteger.valueOf(longVal);
|
||||
byte rBytes[] = {3, -125, 51, 98};
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* valueOf (long val): convert a negative long value to a BigInteger.
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfLongNegative1() {
|
||||
long longVal = -268209772258930018L;
|
||||
BigInteger aNumber = BigInteger.valueOf(longVal);
|
||||
byte rBytes[] = {-4, 71, 32, -94, 23, 55, -46, -98};
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* valueOf (long val): convert a negative long value to a BigInteger.
|
||||
* The long value fits in integer.
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfLongNegative2() {
|
||||
long longVal = -58930018L;
|
||||
BigInteger aNumber = BigInteger.valueOf(longVal);
|
||||
byte rBytes[] = {-4, 124, -52, -98};
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, aNumber.signum());
|
||||
}
|
||||
/**
|
||||
* valueOf (long val): convert a zero long value to a BigInteger.
|
||||
*/
|
||||
@Test
|
||||
public void testValueOfLongZero() {
|
||||
long longVal = 0L;
|
||||
BigInteger aNumber = BigInteger.valueOf(longVal);
|
||||
byte rBytes[] = {0};
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = aNumber.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, aNumber.signum());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,703 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigInteger
|
||||
* Methods: divide, remainder, mod, and divideAndRemainder
|
||||
*/
|
||||
public class BigIntegerDivideTest {
|
||||
/**
|
||||
* Divide by zero
|
||||
*/
|
||||
@Test
|
||||
public void testCase1() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {0};
|
||||
int aSign = 1;
|
||||
int bSign = 0;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
try {
|
||||
aNumber.divide(bNumber);
|
||||
fail("ArithmeticException has not been caught");
|
||||
} catch (ArithmeticException e) {
|
||||
assertEquals("Improper exception message", "BigInteger divide by zero", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide by ZERO
|
||||
*/
|
||||
@Test
|
||||
public void testCase2() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
int aSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = BigInteger.ZERO;
|
||||
try {
|
||||
aNumber.divide(bNumber);
|
||||
fail("ArithmeticException has not been caught");
|
||||
} catch (ArithmeticException e) {
|
||||
assertEquals("Improper exception message", "BigInteger divide by zero", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide two equal positive numbers
|
||||
*/
|
||||
@Test
|
||||
public void testCase3() {
|
||||
byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127};
|
||||
byte bBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {1};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide two equal in absolute value numbers of different signs.
|
||||
*/
|
||||
@Test
|
||||
public void testCase4() {
|
||||
byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127};
|
||||
byte bBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-1};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide two numbers of different length and different signs.
|
||||
* The second is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase5() {
|
||||
byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127};
|
||||
byte bBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 1, 2, 3, 4, 5};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide two positive numbers of the same length.
|
||||
* The second is greater.
|
||||
*/
|
||||
@Test
|
||||
public void testCase6() {
|
||||
byte aBytes[] = {1, 100, 56, 7, 98, -1, 39, -128, 127};
|
||||
byte bBytes[] = {15, 100, 56, 7, 98, -1, 39, -128, 127};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide two positive numbers.
|
||||
*/
|
||||
@Test
|
||||
public void testCase7() {
|
||||
byte aBytes[] = {1, 100, 56, 7, 98, -1, 39, -128, 127, 5, 6, 7, 8, 9};
|
||||
byte bBytes[] = {15, 48, -29, 7, 98, -1, 39, -128};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {23, 115, 11, 78, 35, -11};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide a positive number by a negative one.
|
||||
*/
|
||||
@Test
|
||||
public void testCase8() {
|
||||
byte aBytes[] = {1, 100, 56, 7, 98, -1, 39, -128, 127, 5, 6, 7, 8, 9};
|
||||
byte bBytes[] = {15, 48, -29, 7, 98, -1, 39, -128};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-24, -116, -12, -79, -36, 11};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide a negative number by a positive one.
|
||||
*/
|
||||
@Test
|
||||
public void testCase9() {
|
||||
byte aBytes[] = {1, 100, 56, 7, 98, -1, 39, -128, 127, 5, 6, 7, 8, 9};
|
||||
byte bBytes[] = {15, 48, -29, 7, 98, -1, 39, -128};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-24, -116, -12, -79, -36, 11};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide two negative numbers.
|
||||
*/
|
||||
@Test
|
||||
public void testCase10() {
|
||||
byte aBytes[] = {1, 100, 56, 7, 98, -1, 39, -128, 127, 5, 6, 7, 8, 9};
|
||||
byte bBytes[] = {15, 48, -29, 7, 98, -1, 39, -128};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {23, 115, 11, 78, 35, -11};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide zero by a negative number.
|
||||
*/
|
||||
@Test
|
||||
public void testCase11() {
|
||||
byte aBytes[] = {0};
|
||||
byte bBytes[] = {15, 48, -29, 7, 98, -1, 39, -128};
|
||||
int aSign = 0;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide ZERO by a negative number.
|
||||
*/
|
||||
@Test
|
||||
public void testCase12() {
|
||||
byte bBytes[] = {15, 48, -29, 7, 98, -1, 39, -128};
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = BigInteger.ZERO;
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide a positive number by ONE.
|
||||
*/
|
||||
@Test
|
||||
public void testCase13() {
|
||||
byte aBytes[] = {15, 48, -29, 7, 98, -1, 39, -128};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {15, 48, -29, 7, 98, -1, 39, -128};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = BigInteger.ONE;
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide ONE by ONE.
|
||||
*/
|
||||
@Test
|
||||
public void testCase14() {
|
||||
byte rBytes[] = {1};
|
||||
BigInteger aNumber = BigInteger.ONE;
|
||||
BigInteger bNumber = BigInteger.ONE;
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the case when borrow != 0 in the private divide method.
|
||||
*/
|
||||
@Test
|
||||
public void testDivisionKnuth1() {
|
||||
byte aBytes[] = {-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {-3, -3, -3, -3};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0, -5, -12, -33, -96, -36, -105, -56, 92, 15, 48, -109};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the case when the divisor is already normalized.
|
||||
*/
|
||||
@Test
|
||||
public void testDivisionKnuthIsNormalized() {
|
||||
byte aBytes[] = {-9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5};
|
||||
byte bBytes[] = {-1, -1, -1, -1, -1, -1, -1, -1};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {0, -9, -8, -7, -6, -5, -4, -3};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies the case when the first digits of the dividend
|
||||
* and divisor equal.
|
||||
*/
|
||||
@Test
|
||||
public void testDivisionKnuthFirstDigitsEqual() {
|
||||
byte aBytes[] = {2, -3, -4, -5, -1, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5};
|
||||
byte bBytes[] = {2, -3, -4, -5, -1, -1, -1, -1};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {0, -1, -1, -1, -1, -2, -88, -60, 41};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide the number of one digit by the number of one digit
|
||||
*/
|
||||
@Test
|
||||
public void testDivisionKnuthOneDigitByOneDigit() {
|
||||
byte aBytes[] = {113, -83, 123, -5};
|
||||
byte bBytes[] = {2, -3, -4, -5};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-37};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide the number of multi digits by the number of one digit
|
||||
*/
|
||||
@Test
|
||||
public void testDivisionKnuthMultiDigitsByOneDigit() {
|
||||
byte aBytes[] = {113, -83, 123, -5, 18, -34, 67, 39, -29};
|
||||
byte bBytes[] = {2, -3, -4, -5};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-38, 2, 7, 30, 109, -43};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.divide(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remainder of division by zero
|
||||
*/
|
||||
@Test
|
||||
public void testCase15() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {0};
|
||||
int aSign = 1;
|
||||
int bSign = 0;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
try {
|
||||
aNumber.remainder(bNumber);
|
||||
fail("ArithmeticException has not been caught");
|
||||
} catch (ArithmeticException e) {
|
||||
assertEquals("Improper exception message", "BigInteger divide by zero", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remainder of division of equal numbers
|
||||
*/
|
||||
@Test
|
||||
public void testCase16() {
|
||||
byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127};
|
||||
byte bBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.remainder(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remainder of division of two positive numbers
|
||||
*/
|
||||
@Test
|
||||
public void testCase17() {
|
||||
byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75};
|
||||
byte bBytes[] = {27, -15, 65, 39, 100};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {12, -21, 73, 56, 27};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.remainder(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remainder of division of two negative numbers
|
||||
*/
|
||||
@Test
|
||||
public void testCase18() {
|
||||
byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75};
|
||||
byte bBytes[] = {27, -15, 65, 39, 100};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-13, 20, -74, -57, -27};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.remainder(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remainder of division of two numbers of different signs.
|
||||
* The first is positive.
|
||||
*/
|
||||
@Test
|
||||
public void testCase19() {
|
||||
byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75};
|
||||
byte bBytes[] = {27, -15, 65, 39, 100};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {12, -21, 73, 56, 27};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.remainder(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remainder of division of two numbers of different signs.
|
||||
* The first is negative.
|
||||
*/
|
||||
@Test
|
||||
public void testCase20() {
|
||||
byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75};
|
||||
byte bBytes[] = {27, -15, 65, 39, 100};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-13, 20, -74, -57, -27};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.remainder(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the step D6 from the Knuth algorithm
|
||||
*/
|
||||
@Test
|
||||
public void testRemainderKnuth1() {
|
||||
byte aBytes[] = {-9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1};
|
||||
byte bBytes[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {1, 2, 3, 4, 5, 6, 7, 7, 18, -89};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.remainder(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide the number of one digit by the number of one digit
|
||||
*/
|
||||
@Test
|
||||
public void testRemainderKnuthOneDigitByOneDigit() {
|
||||
byte aBytes[] = {113, -83, 123, -5};
|
||||
byte bBytes[] = {2, -3, -4, -50};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {2, -9, -14, 53};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.remainder(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide the number of multi digits by the number of one digit
|
||||
*/
|
||||
@Test
|
||||
public void testRemainderKnuthMultiDigitsByOneDigit() {
|
||||
byte aBytes[] = {113, -83, 123, -5, 18, -34, 67, 39, -29};
|
||||
byte bBytes[] = {2, -3, -4, -50};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {2, -37, -60, 59};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.remainder(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* divideAndRemainder of two numbers of different signs.
|
||||
* The first is negative.
|
||||
*/
|
||||
@Test
|
||||
public void testCase21() {
|
||||
byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75};
|
||||
byte bBytes[] = {27, -15, 65, 39, 100};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[][] = {
|
||||
{-5, 94, -115, -74, -85, 84},
|
||||
{-13, 20, -74, -57, -27}
|
||||
};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result[] = aNumber.divideAndRemainder(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result[0].toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
if (resBytes[i] != rBytes[0][i]) {
|
||||
fail("Incorrect quotation");
|
||||
}
|
||||
}
|
||||
assertEquals(-1, result[0].signum());
|
||||
resBytes = result[1].toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
if (resBytes[i] != rBytes[1][i]) {
|
||||
fail("Incorrect remainder");
|
||||
}
|
||||
assertEquals(-1, result[1].signum());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* mod when modulus is negative
|
||||
*/
|
||||
@Test
|
||||
public void testCase22() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {1, 30, 40, 56, -1, 45};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
try {
|
||||
aNumber.mod(bNumber);
|
||||
fail("ArithmeticException has not been caught");
|
||||
} catch (ArithmeticException e) {
|
||||
assertEquals("Improper exception message", "BigInteger: modulus not positive", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* mod when a divisor is positive
|
||||
*/
|
||||
@Test
|
||||
public void testCase23() {
|
||||
byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75};
|
||||
byte bBytes[] = {27, -15, 65, 39, 100};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {12, -21, 73, 56, 27};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.mod(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* mod when a divisor is negative
|
||||
*/
|
||||
@Test
|
||||
public void testCase24() {
|
||||
byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75};
|
||||
byte bBytes[] = {27, -15, 65, 39, 100};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {15, 5, -9, -17, 73};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.mod(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigInteger
|
||||
* Method: hashCode()
|
||||
*/
|
||||
public class BigIntegerHashCodeTest {
|
||||
/**
|
||||
* Test hash codes for the same object
|
||||
*/
|
||||
@Test
|
||||
public void testSameObject() {
|
||||
String value1 = "12378246728727834290276457386374882976782849";
|
||||
String value2 = "-5634562095872038262928728727834290276457386374882976782849";
|
||||
BigInteger aNumber1 = new BigInteger(value1);
|
||||
BigInteger aNumber2 = new BigInteger(value2);
|
||||
int code1 = aNumber1.hashCode();
|
||||
aNumber1.add(aNumber2).shiftLeft(125);
|
||||
aNumber1.subtract(aNumber2).shiftRight(125);
|
||||
aNumber1.multiply(aNumber2).toByteArray();
|
||||
aNumber1.divide(aNumber2).bitLength();
|
||||
aNumber1.gcd(aNumber2).pow(7);
|
||||
int code2 = aNumber1.hashCode();
|
||||
assertTrue("hash codes for the same object differ", code1 == code2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test hash codes for equal objects.
|
||||
*/
|
||||
@Test
|
||||
public void testEqualObjects() {
|
||||
String value1 = "12378246728727834290276457386374882976782849";
|
||||
String value2 = "12378246728727834290276457386374882976782849";
|
||||
BigInteger aNumber1 = new BigInteger(value1);
|
||||
BigInteger aNumber2 = new BigInteger(value2);
|
||||
int code1 = aNumber1.hashCode();
|
||||
int code2 = aNumber2.hashCode();
|
||||
if (aNumber1.equals(aNumber2)) {
|
||||
assertTrue("hash codes for equal objects are unequal", code1 == code2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test hash codes for unequal objects.
|
||||
* The codes are unequal.
|
||||
*/
|
||||
@Test
|
||||
public void testUnequalObjectsUnequal() {
|
||||
String value1 = "12378246728727834290276457386374882976782849";
|
||||
String value2 = "-5634562095872038262928728727834290276457386374882976782849";
|
||||
BigInteger aNumber1 = new BigInteger(value1);
|
||||
BigInteger aNumber2 = new BigInteger(value2);
|
||||
int code1 = aNumber1.hashCode();
|
||||
int code2 = aNumber2.hashCode();
|
||||
if (!aNumber1.equals(aNumber2)) {
|
||||
assertTrue("hash codes for unequal objects are equal", code1 != code2);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,368 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigInteger Methods: modPow, modInverse, and gcd
|
||||
*/
|
||||
public class BigIntegerModPowTest {
|
||||
/**
|
||||
* modPow: non-positive modulus
|
||||
*/
|
||||
@Test
|
||||
public void testModPowException() {
|
||||
byte aBytes[] = { 1, 2, 3, 4, 5, 6, 7 };
|
||||
byte eBytes[] = { 1, 2, 3, 4, 5 };
|
||||
byte mBytes[] = { 1, 2, 3 };
|
||||
int aSign = 1;
|
||||
int eSign = 1;
|
||||
int mSign = -1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger exp = new BigInteger(eSign, eBytes);
|
||||
BigInteger modulus = new BigInteger(mSign, mBytes);
|
||||
try {
|
||||
aNumber.modPow(exp, modulus);
|
||||
fail("ArithmeticException has not been caught");
|
||||
} catch (ArithmeticException e) {
|
||||
assertEquals("Improper exception message", "BigInteger: modulus not positive", e.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
BigInteger.ZERO.modPow(new BigInteger("-1"), new BigInteger("10"));
|
||||
fail("ArithmeticException has not been caught");
|
||||
} catch (ArithmeticException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* modPow: positive exponent
|
||||
*/
|
||||
@Test
|
||||
public void testModPowPosExp() {
|
||||
byte aBytes[] = { -127, 100, 56, 7, 98, -1, 39, -128, 127, 75, 48, -7 };
|
||||
byte eBytes[] = { 27, -15, 65, 39 };
|
||||
byte mBytes[] = { -128, 2, 3, 4, 5 };
|
||||
int aSign = 1;
|
||||
int eSign = 1;
|
||||
int mSign = 1;
|
||||
byte rBytes[] = { 113, 100, -84, -28, -85 };
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger exp = new BigInteger(eSign, eBytes);
|
||||
BigInteger modulus = new BigInteger(mSign, mBytes);
|
||||
BigInteger result = aNumber.modPow(exp, modulus);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for (int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* modPow: negative exponent
|
||||
*/
|
||||
@Test
|
||||
public void testModPowNegExp() {
|
||||
byte aBytes[] = { -127, 100, 56, 7, 98, -1, 39, -128, 127, 75, 48, -7 };
|
||||
byte eBytes[] = { 27, -15, 65, 39 };
|
||||
byte mBytes[] = { -128, 2, 3, 4, 5 };
|
||||
int aSign = 1;
|
||||
int eSign = -1;
|
||||
int mSign = 1;
|
||||
byte rBytes[] = { 12, 118, 46, 86, 92 };
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger exp = new BigInteger(eSign, eBytes);
|
||||
BigInteger modulus = new BigInteger(mSign, mBytes);
|
||||
BigInteger result = aNumber.modPow(exp, modulus);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for (int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testModPowZeroExp() {
|
||||
BigInteger exp = new BigInteger("0");
|
||||
BigInteger[] base = new BigInteger[] { new BigInteger("-1"), new BigInteger("0"), new BigInteger("1") };
|
||||
BigInteger[] mod = new BigInteger[] { new BigInteger("2"), new BigInteger("10"), new BigInteger("2147483648") };
|
||||
|
||||
for (int i = 0; i < base.length; ++i) {
|
||||
for (int j = 0; j < mod.length; ++j) {
|
||||
assertEquals(base[i] + " modePow(" + exp + ", " + mod[j] + ") should be " + BigInteger.ONE,
|
||||
BigInteger.ONE, base[i].modPow(exp, mod[j]));
|
||||
}
|
||||
}
|
||||
|
||||
mod = new BigInteger[] { new BigInteger("1") };
|
||||
for (int i = 0; i < base.length; ++i) {
|
||||
for (int j = 0; j < mod.length; ++j) {
|
||||
assertEquals(base[i] + " modePow(" + exp + ", " + mod[j] + ") should be " + BigInteger.ZERO,
|
||||
BigInteger.ZERO, base[i].modPow(exp, mod[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* modInverse: non-positive modulus
|
||||
*/
|
||||
@Test
|
||||
public void testmodInverseException() {
|
||||
byte aBytes[] = { 1, 2, 3, 4, 5, 6, 7 };
|
||||
byte mBytes[] = { 1, 2, 3 };
|
||||
int aSign = 1;
|
||||
int mSign = -1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger modulus = new BigInteger(mSign, mBytes);
|
||||
try {
|
||||
aNumber.modInverse(modulus);
|
||||
fail("ArithmeticException has not been caught");
|
||||
} catch (ArithmeticException e) {
|
||||
assertEquals("Improper exception message", "BigInteger: modulus not positive", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* modInverse: non-invertible number
|
||||
*/
|
||||
@Test
|
||||
public void testmodInverseNonInvertible() {
|
||||
byte aBytes[] = { -15, 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127 };
|
||||
byte mBytes[] = { -12, 1, 0, 0, 0, 23, 44, 55, 66 };
|
||||
int aSign = 1;
|
||||
int mSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger modulus = new BigInteger(mSign, mBytes);
|
||||
try {
|
||||
aNumber.modInverse(modulus);
|
||||
fail("ArithmeticException has not been caught");
|
||||
} catch (ArithmeticException e) {
|
||||
assertEquals("Improper exception message", "BigInteger not invertible.", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* modInverse: positive number
|
||||
*/
|
||||
@Test
|
||||
public void testmodInversePos1() {
|
||||
byte aBytes[] = { 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127 };
|
||||
byte mBytes[] = { 122, 45, 36, 100, 122, 45 };
|
||||
int aSign = 1;
|
||||
int mSign = 1;
|
||||
byte rBytes[] = { 47, 3, 96, 62, 87, 19 };
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger modulus = new BigInteger(mSign, mBytes);
|
||||
BigInteger result = aNumber.modInverse(modulus);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for (int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* modInverse: positive number (another case: a < 0)
|
||||
*/
|
||||
@Test
|
||||
public void testmodInversePos2() {
|
||||
byte aBytes[] = { 15, 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127 };
|
||||
byte mBytes[] = { 2, 122, 45, 36, 100 };
|
||||
int aSign = 1;
|
||||
int mSign = 1;
|
||||
byte rBytes[] = { 1, -93, 40, 127, 73 };
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger modulus = new BigInteger(mSign, mBytes);
|
||||
BigInteger result = aNumber.modInverse(modulus);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for (int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* modInverse: negative number
|
||||
*/
|
||||
@Test
|
||||
public void testmodInverseNeg1() {
|
||||
byte aBytes[] = { 15, 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127 };
|
||||
byte mBytes[] = { 2, 122, 45, 36, 100 };
|
||||
int aSign = -1;
|
||||
int mSign = 1;
|
||||
byte rBytes[] = { 0, -41, 4, -91, 27 };
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger modulus = new BigInteger(mSign, mBytes);
|
||||
BigInteger result = aNumber.modInverse(modulus);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for (int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* modInverse: negative number (another case: x < 0)
|
||||
*/
|
||||
@Test
|
||||
public void testmodInverseNeg2() {
|
||||
byte aBytes[] = { -15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57 };
|
||||
byte mBytes[] = { 122, 2, 4, 122, 2, 4 };
|
||||
byte rBytes[] = { 85, 47, 127, 4, -128, 45 };
|
||||
BigInteger aNumber = new BigInteger(aBytes);
|
||||
BigInteger modulus = new BigInteger(mBytes);
|
||||
BigInteger result = aNumber.modInverse(modulus);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for (int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* gcd: the second number is zero
|
||||
*/
|
||||
@Test
|
||||
public void testGcdSecondZero() {
|
||||
byte aBytes[] = { 15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57 };
|
||||
byte bBytes[] = { 0 };
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = { 15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57 };
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.gcd(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for (int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* gcd: the first number is zero
|
||||
*/
|
||||
@Test
|
||||
public void testGcdFirstZero() {
|
||||
byte aBytes[] = { 0 };
|
||||
byte bBytes[] = { 15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57 };
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = { 15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57 };
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.gcd(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for (int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* gcd: the first number is ZERO
|
||||
*/
|
||||
@Test
|
||||
public void testGcdFirstZERO() {
|
||||
byte bBytes[] = { 15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57 };
|
||||
int bSign = 1;
|
||||
byte rBytes[] = { 15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57 };
|
||||
BigInteger aNumber = BigInteger.ZERO;
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.gcd(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for (int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* gcd: both numbers are zeros
|
||||
*/
|
||||
@Test
|
||||
public void testGcdBothZeros() {
|
||||
byte rBytes[] = { 0 };
|
||||
BigInteger aNumber = new BigInteger("0");
|
||||
BigInteger bNumber = BigInteger.valueOf(0L);
|
||||
BigInteger result = aNumber.gcd(bNumber);
|
||||
byte resBytes[] = result.toByteArray();
|
||||
for (int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* gcd: the first number is longer
|
||||
*/
|
||||
@Test
|
||||
public void testGcdFirstLonger() {
|
||||
byte aBytes[] = { -15, 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127 };
|
||||
byte bBytes[] = { -12, 1, 0, 0, 0, 23, 44, 55, 66 };
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = { 7 };
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.gcd(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for (int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* gcd: the second number is longer
|
||||
*/
|
||||
@Test
|
||||
public void testGcdSecondLonger() {
|
||||
byte aBytes[] = { -12, 1, 0, 0, 0, 23, 44, 55, 66 };
|
||||
byte bBytes[] = { -15, 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127 };
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = { 7 };
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.gcd(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for (int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,408 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigInteger
|
||||
* Method: multiply
|
||||
*/
|
||||
public class BigIntegerMultiplyTest {
|
||||
/**
|
||||
* Multiply two negative numbers of the same length
|
||||
*/
|
||||
@Test
|
||||
public void testCase1() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {10, 40, 100, -55, 96, 51, 76, 40, -45, 85, 105, 4, 28, -86, -117, -52, 100, 120, 90};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.multiply(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply two numbers of the same length and different signs.
|
||||
* The first is negative.
|
||||
*/
|
||||
@Test
|
||||
public void testCase2() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-11, -41, -101, 54, -97, -52, -77, -41, 44, -86, -106, -5, -29, 85, 116, 51, -101, -121, -90};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.multiply(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply two positive numbers of different length.
|
||||
* The first is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase3() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {10, 40, 100, -55, 96, 51, 76, 40, -45, 85, 115, 44, -127,
|
||||
115, -21, -62, -15, 85, 64, -87, -2, -36, -36, -106};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.multiply(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply two positive numbers of different length.
|
||||
* The second is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase4() {
|
||||
byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {10, 40, 100, -55, 96, 51, 76, 40, -45, 85, 115, 44, -127,
|
||||
115, -21, -62, -15, 85, 64, -87, -2, -36, -36, -106};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.multiply(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply two numbers of different length and different signs.
|
||||
* The first is positive.
|
||||
* The first is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase5() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-11, -41, -101, 54, -97, -52, -77, -41, 44, -86, -116, -45, 126,
|
||||
-116, 20, 61, 14, -86, -65, 86, 1, 35, 35, 106};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.multiply(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply two numbers of different length and different signs.
|
||||
* The first is positive.
|
||||
* The second is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase6() {
|
||||
byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-11, -41, -101, 54, -97, -52, -77, -41, 44, -86, -116, -45, 126,
|
||||
-116, 20, 61, 14, -86, -65, 86, 1, 35, 35, 106};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.multiply(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply a number by zero.
|
||||
*/
|
||||
@Test
|
||||
public void testCase7() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
|
||||
byte bBytes[] = {0};
|
||||
int aSign = 1;
|
||||
int bSign = 0;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.multiply(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply a number by ZERO.
|
||||
*/
|
||||
@Test
|
||||
public void testCase8() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = BigInteger.ZERO;
|
||||
BigInteger result = aNumber.multiply(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply a positive number by ONE.
|
||||
*/
|
||||
@Test
|
||||
public void testCase9() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = BigInteger.ONE;
|
||||
BigInteger result = aNumber.multiply(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply a negative number by ONE.
|
||||
*/
|
||||
@Test
|
||||
public void testCase10() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 1, 2, 3, 4, 5};
|
||||
int aSign = -1;
|
||||
byte rBytes[] = {-2, -3, -4, -5, -6, -7, -8, -2, -3, -4, -2, -3, -4, -5, -5};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = BigInteger.ONE;
|
||||
BigInteger result = aNumber.multiply(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply two numbers of 4 bytes length.
|
||||
*/
|
||||
@Test
|
||||
public void testIntbyInt1() {
|
||||
byte aBytes[] = {10, 20, 30, 40};
|
||||
byte bBytes[] = {1, 2, 3, 4};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-11, -41, -101, 55, 5, 15, 96};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.multiply(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply two numbers of 4 bytes length.
|
||||
*/
|
||||
@Test
|
||||
public void testIntbyInt2() {
|
||||
byte aBytes[] = {-1, -1, -1, -1};
|
||||
byte bBytes[] = {-1, -1, -1, -1};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0, -1, -1, -1, -2, 0, 0, 0, 1};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.multiply(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Negative exponent.
|
||||
*/
|
||||
@Test
|
||||
public void testPowException() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
|
||||
int aSign = 1;
|
||||
int exp = -5;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
try {
|
||||
aNumber.pow(exp);
|
||||
fail("ArithmeticException has not been caught");
|
||||
} catch (ArithmeticException e) {
|
||||
assertEquals("Improper exception message", "Negative exponent", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exponentiation of a negative number to an odd exponent.
|
||||
*/
|
||||
@Test
|
||||
public void testPowNegativeNumToOddExp() {
|
||||
byte aBytes[] = {50, -26, 90, 69, 120, 32, 63, -103, -14, 35};
|
||||
int aSign = -1;
|
||||
int exp = 5;
|
||||
byte rBytes[] = {-21, -94, -42, -15, -127, 113, -50, -88, 115, -35, 3,
|
||||
59, -92, 111, -75, 103, -42, 41, 34, -114, 99, -32, 105, -59, 127,
|
||||
45, 108, 74, -93, 105, 33, 12, -5, -20, 17, -21, -119, -127, -115,
|
||||
27, -122, 26, -67, 109, -125, 16, 91, -70, 109};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger result = aNumber.pow(exp);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Exponentiation of a negative number to an even exponent.
|
||||
*/
|
||||
@Test
|
||||
public void testPowNegativeNumToEvenExp() {
|
||||
byte aBytes[] = {50, -26, 90, 69, 120, 32, 63, -103, -14, 35};
|
||||
int aSign = -1;
|
||||
int exp = 4;
|
||||
byte rBytes[] = {102, 107, -122, -43, -52, -20, -27, 25, -9, 88, -13,
|
||||
75, 78, 81, -33, -77, 39, 27, -37, 106, 121, -73, 108, -47, -101,
|
||||
80, -25, 71, 13, 94, -7, -33, 1, -17, -65, -70, -61, -3, -47};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger result = aNumber.pow(exp);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Exponentiation of a negative number to zero exponent.
|
||||
*/
|
||||
@Test
|
||||
public void testPowNegativeNumToZeroExp() {
|
||||
byte aBytes[] = {50, -26, 90, 69, 120, 32, 63, -103, -14, 35};
|
||||
int aSign = -1;
|
||||
int exp = 0;
|
||||
byte rBytes[] = {1};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger result = aNumber.pow(exp);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Exponentiation of a positive number.
|
||||
*/
|
||||
@Test
|
||||
public void testPowPositiveNum() {
|
||||
byte aBytes[] = {50, -26, 90, 69, 120, 32, 63, -103, -14, 35};
|
||||
int aSign = 1;
|
||||
int exp = 5;
|
||||
byte rBytes[] = {20, 93, 41, 14, 126, -114, 49, 87, -116, 34, -4, -60,
|
||||
91, -112, 74, -104, 41, -42, -35, 113, -100, 31, -106, 58, -128,
|
||||
-46, -109, -75, 92, -106, -34, -13, 4, 19, -18, 20, 118, 126, 114,
|
||||
-28, 121, -27, 66, -110, 124, -17, -92, 69, -109};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger result = aNumber.pow(exp);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Exponentiation of a negative number to zero exponent.
|
||||
*/
|
||||
@Test
|
||||
public void testPowPositiveNumToZeroExp() {
|
||||
byte aBytes[] = {50, -26, 90, 69, 120, 32, 63, -103, -14, 35};
|
||||
int aSign = 1;
|
||||
int exp = 0;
|
||||
byte rBytes[] = {1};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger result = aNumber.pow(exp);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigInteger
|
||||
* Methods: and, andNot
|
||||
*/
|
||||
public class BigIntegerNotTest {
|
||||
/**
|
||||
* andNot for two positive numbers; the first is longer
|
||||
*/
|
||||
@Test
|
||||
public void testAndNotPosPosFirstLonger() {
|
||||
byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0, -128, 9, 56, 100, 0, 0, 1, 1, 90, 1, -32, 0, 10, -126, 21, 82, -31, -96};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.andNot(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* andNot for two positive numbers; the first is shorter
|
||||
*/
|
||||
@Test
|
||||
public void testAndNotPosPosFirstShorter() {
|
||||
byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {73, -92, -48, 4, 12, 6, 4, 32, 48, 64, 0, 8, 2};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.andNot(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* andNot for two negative numbers; the first is longer
|
||||
*/
|
||||
@Test
|
||||
public void testAndNotNegNegFirstLonger() {
|
||||
byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {73, -92, -48, 4, 12, 6, 4, 32, 48, 64, 0, 8, 2};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.andNot(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* andNot for a negative and a positive numbers; the first is longer
|
||||
*/
|
||||
@Test
|
||||
public void testNegPosFirstLonger() {
|
||||
byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-1, 127, -10, -57, -101, 1, 2, 2, 2, -96, -16, 8, -40, -59, 68, -88, -88, 16, 72};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.andNot(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Not for ZERO
|
||||
*/
|
||||
@Test
|
||||
public void testNotZero() {
|
||||
byte rBytes[] = {-1};
|
||||
BigInteger aNumber = BigInteger.ZERO;
|
||||
BigInteger result = aNumber.not();
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Not for ONE
|
||||
*/
|
||||
@Test
|
||||
public void testNotOne() {
|
||||
byte rBytes[] = {-2};
|
||||
BigInteger aNumber = BigInteger.ONE;
|
||||
BigInteger result = aNumber.not();
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Not for a positive number
|
||||
*/
|
||||
@Test
|
||||
public void testNotPos() {
|
||||
byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {-1, 127, -57, -101, 1, 75, -90, -46, -92, -4, 14, -36, -27, 116};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger result = aNumber.not();
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Not for a negative number
|
||||
*/
|
||||
@Test
|
||||
public void testNotNeg() {
|
||||
byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
|
||||
int aSign = -1;
|
||||
byte rBytes[] = {0, -128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -118};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger result = aNumber.not();
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Not for a negative number
|
||||
*/
|
||||
@Test
|
||||
public void testNotSpecialCase() {
|
||||
byte aBytes[] = {-1, -1, -1, -1};
|
||||
int aSign = 1;
|
||||
byte rBytes[] = {-1, 0, 0, 0, 0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger result = aNumber.not();
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,440 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigInteger
|
||||
* Method: or
|
||||
*/
|
||||
public class BigIntegerOrTest {
|
||||
/**
|
||||
* Or for zero and a positive number
|
||||
*/
|
||||
@Test
|
||||
public void testZeroPos() {
|
||||
byte aBytes[] = {0};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = 0;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0, -2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for zero and a negative number
|
||||
*/
|
||||
@Test
|
||||
public void testZeroNeg() {
|
||||
byte aBytes[] = {0};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = 0;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-1, 1, 2, 3, 3, -6, -15, -24, -40, -49, -58, -67, -6, -15, -23};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for a positive number and zero
|
||||
*/
|
||||
@Test
|
||||
public void testPosZero() {
|
||||
byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
byte bBytes[] = {0};
|
||||
int aSign = 1;
|
||||
int bSign = 0;
|
||||
byte rBytes[] = {0, -2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for a negative number and zero
|
||||
*/
|
||||
@Test
|
||||
public void testNegPos() {
|
||||
byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
byte bBytes[] = {0};
|
||||
int aSign = -1;
|
||||
int bSign = 0;
|
||||
byte rBytes[] = {-1, 1, 2, 3, 3, -6, -15, -24, -40, -49, -58, -67, -6, -15, -23};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for zero and zero
|
||||
*/
|
||||
@Test
|
||||
public void testZeroZero() {
|
||||
byte aBytes[] = {0};
|
||||
byte bBytes[] = {0};
|
||||
int aSign = 0;
|
||||
int bSign = 0;
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for zero and one
|
||||
*/
|
||||
@Test
|
||||
public void testZeroOne() {
|
||||
byte aBytes[] = {0};
|
||||
byte bBytes[] = {1};
|
||||
int aSign = 0;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {1};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for one and one
|
||||
*/
|
||||
@Test
|
||||
public void testOneOne() {
|
||||
byte aBytes[] = {1};
|
||||
byte bBytes[] = {1};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {1};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for two positive numbers of the same length
|
||||
*/
|
||||
@Test
|
||||
public void testPosPosSameLength() {
|
||||
byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0, -2, -3, -4, -4, -1, -66, 95, 47, 123, 59, -13, 39, 30, -97};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for two positive numbers; the first is longer
|
||||
*/
|
||||
@Test
|
||||
public void testPosPosFirstLonger() {
|
||||
byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0, -128, 9, 56, 100, -2, -3, -3, -3, 95, 15, -9, 39, 58, -69, 87, 87, -17, -73};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for two positive numbers; the first is shorter
|
||||
*/
|
||||
@Test
|
||||
public void testPosPosFirstShorter() {
|
||||
byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {0, -128, 9, 56, 100, -2, -3, -3, -3, 95, 15, -9, 39, 58, -69, 87, 87, -17, -73};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", 1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for two negative numbers of the same length
|
||||
*/
|
||||
@Test
|
||||
public void testNegNegSameLength() {
|
||||
byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-1, 127, -57, -101, -5, -5, -18, -38, -17, -2, -65, -2, -11, -3};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for two negative numbers; the first is longer
|
||||
*/
|
||||
@Test
|
||||
public void testNegNegFirstLonger() {
|
||||
byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-1, 1, 75, -89, -45, -2, -3, -18, -36, -17, -10, -3, -6, -7, -21};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for two negative numbers; the first is shorter
|
||||
*/
|
||||
@Test
|
||||
public void testNegNegFirstShorter() {
|
||||
byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-1, 1, 75, -89, -45, -2, -3, -18, -36, -17, -10, -3, -6, -7, -21};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for two numbers of different signs and the same length
|
||||
*/
|
||||
@Test
|
||||
public void testPosNegSameLength() {
|
||||
byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-1, 1, -126, 59, 103, -2, -11, -7, -3, -33, -57, -3, -5, -5, -21};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for two numbers of different signs and the same length
|
||||
*/
|
||||
@Test
|
||||
public void testNegPosSameLength() {
|
||||
byte aBytes[] = {-128, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-1, 5, 79, -73, -9, -76, -3, 78, -35, -17, 119};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for a negative and a positive numbers; the first is longer
|
||||
*/
|
||||
@Test
|
||||
public void testNegPosFirstLonger() {
|
||||
byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-1, 127, -10, -57, -101, -1, -1, -2, -2, -91, -2, 31, -1, -11, 125, -22, -83, 30, 95};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for two negative numbers; the first is shorter
|
||||
*/
|
||||
@Test
|
||||
public void testNegPosFirstShorter() {
|
||||
byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-74, 91, 47, -5, -13, -7, -5, -33, -49, -65, -1, -9, -3};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for a positive and a negative numbers; the first is longer
|
||||
*/
|
||||
@Test
|
||||
public void testPosNegFirstLonger() {
|
||||
byte aBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
byte bBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-74, 91, 47, -5, -13, -7, -5, -33, -49, -65, -1, -9, -3};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Or for a positive and a negative number; the first is shorter
|
||||
*/
|
||||
@Test
|
||||
public void testPosNegFirstShorter() {
|
||||
byte aBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
byte bBytes[] = {-128, 9, 56, 100, -2, -76, 89, 45, 91, 3, -15, 35, 26, -117, 23, 87, -25, -75};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-1, 127, -10, -57, -101, -1, -1, -2, -2, -91, -2, 31, -1, -11, 125, -22, -83, 30, 95};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.or(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals("incorrect sign", -1, result.signum());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRegression() {
|
||||
// Regression test for HARMONY-1996
|
||||
BigInteger x = new BigInteger("-1023");
|
||||
BigInteger r1 = x.and((BigInteger.ZERO.not()).shiftLeft(32));
|
||||
BigInteger r3 = x.and((BigInteger.ZERO.not().shiftLeft(32) ).not());
|
||||
BigInteger result = r1.or(r3);
|
||||
assertEquals(x, result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,573 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigInteger
|
||||
* Method: subtract
|
||||
*/
|
||||
public class BigIntegerSubtractTest {
|
||||
/**
|
||||
* Subtract two positive numbers of the same length.
|
||||
* The first is greater.
|
||||
*/
|
||||
@Test
|
||||
public void testCase1() {
|
||||
byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {9, 18, 27, 36, 45, 54, 63, 9, 18, 27};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two positive numbers of the same length.
|
||||
* The second is greater.
|
||||
*/
|
||||
@Test
|
||||
public void testCase2() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-10, -19, -28, -37, -46, -55, -64, -10, -19, -27};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(-1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two numbers of the same length and different signs.
|
||||
* The first is positive.
|
||||
* The first is greater in absolute value.
|
||||
*/
|
||||
@Test
|
||||
public void testCase3() {
|
||||
byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {11, 22, 33, 44, 55, 66, 77, 11, 22, 33};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two numbers of the same length and different signs.
|
||||
* The first is positive.
|
||||
* The second is greater in absolute value.
|
||||
*/
|
||||
@Test
|
||||
public void testCase4() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {11, 22, 33, 44, 55, 66, 77, 11, 22, 33};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two negative numbers of the same length.
|
||||
* The first is greater in absolute value.
|
||||
*/
|
||||
@Test
|
||||
public void testCase5() {
|
||||
byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-10, -19, -28, -37, -46, -55, -64, -10, -19, -27};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(-1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two negative numbers of the same length.
|
||||
* The second is greater in absolute value.
|
||||
*/
|
||||
@Test
|
||||
public void testCase6() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {9, 18, 27, 36, 45, 54, 63, 9, 18, 27};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two numbers of the same length and different signs.
|
||||
* The first is negative.
|
||||
* The first is greater in absolute value.
|
||||
*/
|
||||
@Test
|
||||
public void testCase7() {
|
||||
byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-12, -23, -34, -45, -56, -67, -78, -12, -23, -33};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(-1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two numbers of the same length and different signs.
|
||||
* The first is negative.
|
||||
* The second is greater in absolute value.
|
||||
*/
|
||||
@Test
|
||||
public void testCase8() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-12, -23, -34, -45, -56, -67, -78, -12, -23, -33};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(-1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two positive numbers of different length.
|
||||
* The first is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase9() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {1, 2, 3, 3, -6, -15, -24, -40, -49, -58, -67, -6, -15, -23};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two positive numbers of different length.
|
||||
* The second is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase10() {
|
||||
byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(-1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two numbers of different length and different signs.
|
||||
* The first is positive.
|
||||
* The first is greater in absolute value.
|
||||
*/
|
||||
@Test
|
||||
public void testCase11() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {1, 2, 3, 4, 15, 26, 37, 41, 52, 63, 74, 15, 26, 37};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two numbers of the same length and different signs.
|
||||
* The first is positive.
|
||||
* The second is greater in absolute value.
|
||||
*/
|
||||
@Test
|
||||
public void testCase12() {
|
||||
byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
int aSign = 1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {1, 2, 3, 4, 15, 26, 37, 41, 52, 63, 74, 15, 26, 37};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two numbers of different length and different signs.
|
||||
* The first is negative.
|
||||
* The first is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase13() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-2, -3, -4, -5, -16, -27, -38, -42, -53, -64, -75, -16, -27, -37};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(-1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two numbers of the same length and different signs.
|
||||
* The first is negative.
|
||||
* The second is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase14() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = -1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-2, -3, -4, -5, -16, -27, -38, -42, -53, -64, -75, -16, -27, -37};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(-1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two negative numbers of different length.
|
||||
* The first is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase15() {
|
||||
byte aBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
byte bBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {-2, -3, -4, -4, 5, 14, 23, 39, 48, 57, 66, 5, 14, 23};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(-1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two negative numbers of different length.
|
||||
* The second is longer.
|
||||
*/
|
||||
@Test
|
||||
public void testCase16() {
|
||||
byte aBytes[] = {10, 20, 30, 40, 50, 60, 70, 10, 20, 30};
|
||||
byte bBytes[] = {1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7};
|
||||
int aSign = -1;
|
||||
int bSign = -1;
|
||||
byte rBytes[] = {1, 2, 3, 3, -6, -15, -24, -40, -49, -58, -67, -6, -15, -23};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two positive equal in absolute value numbers.
|
||||
*/
|
||||
@Test
|
||||
public void testCase17() {
|
||||
byte aBytes[] = {-120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
|
||||
byte bBytes[] = {-120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
|
||||
byte rBytes[] = {0};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract zero from a number.
|
||||
* The number is positive.
|
||||
*/
|
||||
@Test
|
||||
public void testCase18() {
|
||||
byte aBytes[] = {120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
|
||||
byte bBytes[] = {0};
|
||||
byte rBytes[] = {120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
|
||||
int aSign = 1;
|
||||
int bSign = 0;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract a number from zero.
|
||||
* The number is negative.
|
||||
*/
|
||||
@Test
|
||||
public void testCase19() {
|
||||
byte aBytes[] = {0};
|
||||
byte bBytes[] = {120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
|
||||
byte rBytes[] = {120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
|
||||
int aSign = 0;
|
||||
int bSign = -1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract zero from zero.
|
||||
*/
|
||||
@Test
|
||||
public void testCase20() {
|
||||
byte aBytes[] = {0};
|
||||
byte bBytes[] = {0};
|
||||
byte rBytes[] = {0};
|
||||
int aSign = 0;
|
||||
int bSign = 0;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract ZERO from a number.
|
||||
* The number is positive.
|
||||
*/
|
||||
@Test
|
||||
public void testCase21() {
|
||||
byte aBytes[] = {120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
|
||||
byte rBytes[] = {120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
|
||||
int aSign = 1;
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = BigInteger.ZERO;
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract a number from ZERO.
|
||||
* The number is negative.
|
||||
*/
|
||||
@Test
|
||||
public void testCase22() {
|
||||
byte bBytes[] = {120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
|
||||
byte rBytes[] = {120, 34, 78, -23, -111, 45, 127, 23, 45, -3};
|
||||
int bSign = -1;
|
||||
BigInteger aNumber = BigInteger.ZERO;
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(1, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract ZERO from ZERO.
|
||||
*/
|
||||
@Test
|
||||
public void testCase23() {
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = BigInteger.ZERO;
|
||||
BigInteger bNumber = BigInteger.ZERO;
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract ONE from ONE.
|
||||
*/
|
||||
@Test
|
||||
public void testCase24() {
|
||||
byte rBytes[] = {0};
|
||||
BigInteger aNumber = BigInteger.ONE;
|
||||
BigInteger bNumber = BigInteger.ONE;
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(0, result.signum());
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract two numbers so that borrow is 1.
|
||||
*/
|
||||
@Test
|
||||
public void testCase25() {
|
||||
byte aBytes[] = {-1, -1, -1, -1, -1, -1, -1, -1};
|
||||
byte bBytes[] = {-128, -128, -128, -128, -128, -128, -128, -128, -128};
|
||||
int aSign = 1;
|
||||
int bSign = 1;
|
||||
byte rBytes[] = {-128, 127, 127, 127, 127, 127, 127, 127, 127};
|
||||
BigInteger aNumber = new BigInteger(aSign, aBytes);
|
||||
BigInteger bNumber = new BigInteger(bSign, bBytes);
|
||||
BigInteger result = aNumber.subtract(bNumber);
|
||||
byte resBytes[] = new byte[rBytes.length];
|
||||
resBytes = result.toByteArray();
|
||||
for(int i = 0; i < resBytes.length; i++) {
|
||||
assertTrue(resBytes[i] == rBytes[i]);
|
||||
}
|
||||
assertEquals(-1, result.signum());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigInteger
|
||||
* Method: toString(int radix)
|
||||
*/
|
||||
public class BigIntegerToStringTest {
|
||||
/**
|
||||
* If 36 < radix < 2 it should be set to 10
|
||||
*/
|
||||
@Test
|
||||
public void testRadixOutOfRange() {
|
||||
String value = "442429234853876401";
|
||||
int radix = 10;
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
String result = aNumber.toString(45);
|
||||
assertTrue(result.equals(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* test negative number of radix 2
|
||||
*/
|
||||
@Test
|
||||
public void testRadix2Neg() {
|
||||
String value = "-101001100010010001001010101110000101010110001010010101010101010101010101010101010101010101010010101";
|
||||
int radix = 2;
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
String result = aNumber.toString(radix);
|
||||
assertTrue(result.equals(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* test positive number of radix 2
|
||||
*/
|
||||
@Test
|
||||
public void testRadix2Pos() {
|
||||
String value = "101000011111000000110101010101010101010001001010101010101010010101010101010000100010010";
|
||||
int radix = 2;
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
String result = aNumber.toString(radix);
|
||||
assertTrue(result.equals(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* test negative number of radix 10
|
||||
*/
|
||||
@Test
|
||||
public void testRadix10Neg() {
|
||||
String value = "-2489756308572364789878394872984";
|
||||
int radix = 16;
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
String result = aNumber.toString(radix);
|
||||
assertTrue(result.equals(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* test positive number of radix 10
|
||||
*/
|
||||
@Test
|
||||
public void testRadix10Pos() {
|
||||
String value = "2387627892347567398736473476";
|
||||
int radix = 16;
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
String result = aNumber.toString(radix);
|
||||
assertTrue(result.equals(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* test negative number of radix 16
|
||||
*/
|
||||
@Test
|
||||
public void testRadix16Neg() {
|
||||
String value = "-287628a883451b800865c67e8d7ff20";
|
||||
int radix = 16;
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
String result = aNumber.toString(radix);
|
||||
assertTrue(result.equals(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* test positive number of radix 16
|
||||
*/
|
||||
@Test
|
||||
public void testRadix16Pos() {
|
||||
String value = "287628a883451b800865c67e8d7ff20";
|
||||
int radix = 16;
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
String result = aNumber.toString(radix);
|
||||
assertTrue(result.equals(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* test negative number of radix 24
|
||||
*/
|
||||
@Test
|
||||
public void testRadix24Neg() {
|
||||
String value = "-287628a88gmn3451b8ijk00865c67e8d7ff20";
|
||||
int radix = 24;
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
String result = aNumber.toString(radix);
|
||||
assertTrue(result.equals(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* test positive number of radix 24
|
||||
*/
|
||||
@Test
|
||||
public void testRadix24Pos() {
|
||||
String value = "287628a883451bg80ijhk0865c67e8d7ff20";
|
||||
int radix = 24;
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
String result = aNumber.toString(radix);
|
||||
assertTrue(result.equals(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* test negative number of radix 24
|
||||
*/
|
||||
@Test
|
||||
public void testRadix36Neg() {
|
||||
String value = "-uhguweut98iu4h3478tq3985pq98yeiuth33485yq4aiuhalai485yiaehasdkr8tywi5uhslei8";
|
||||
int radix = 36;
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
String result = aNumber.toString(radix);
|
||||
assertTrue(result.equals(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* test positive number of radix 24
|
||||
*/
|
||||
@Test
|
||||
public void testRadix36Pos() {
|
||||
String value = "23895lt45y6vhgliuwhgi45y845htsuerhsi4586ysuerhtsio5y68peruhgsil4568ypeorihtse48y6";
|
||||
int radix = 36;
|
||||
BigInteger aNumber = new BigInteger(value, radix);
|
||||
String result = aNumber.toString(radix);
|
||||
assertTrue(result.equals(value));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
/**
|
||||
* @author Elena Semukhina
|
||||
*/
|
||||
|
||||
package org.teavm.classlib.java.math;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Class: java.math.BigInteger
|
||||
* Method: xor
|
||||
*/
|
||||
public class BigIntegerXorTest {
|
||||
/**
|
||||
* Xor for zero and a positive number
|
||||
*/
|
||||
@Test
|
||||
public void testZeroPos() {
|
||||
String numA = "0";
|
||||
String numB = "27384627835298756289327365";
|
||||
String res = "27384627835298756289327365";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for zero and a negative number
|
||||
*/
|
||||
@Test
|
||||
public void testZeroNeg() {
|
||||
String numA = "0";
|
||||
String numB = "-27384627835298756289327365";
|
||||
String res = "-27384627835298756289327365";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for a positive number and zero
|
||||
*/
|
||||
@Test
|
||||
public void testPosZero() {
|
||||
String numA = "27384627835298756289327365";
|
||||
String numB = "0";
|
||||
String res = "27384627835298756289327365";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for a negative number and zero
|
||||
*/
|
||||
@Test
|
||||
public void testNegPos() {
|
||||
String numA = "-27384627835298756289327365";
|
||||
String numB = "0";
|
||||
String res = "-27384627835298756289327365";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for zero and zero
|
||||
*/
|
||||
@Test
|
||||
public void testZeroZero() {
|
||||
String numA = "0";
|
||||
String numB = "0";
|
||||
String res = "0";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for zero and one
|
||||
*/
|
||||
@Test
|
||||
public void testZeroOne() {
|
||||
String numA = "0";
|
||||
String numB = "1";
|
||||
String res = "1";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for one and one
|
||||
*/
|
||||
@Test
|
||||
public void testOneOne() {
|
||||
String numA = "1";
|
||||
String numB = "1";
|
||||
String res = "0";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for two positive numbers of the same length
|
||||
*/
|
||||
@Test
|
||||
public void testPosPosSameLength() {
|
||||
String numA = "283746278342837476784564875684767";
|
||||
String numB = "293478573489347658763745839457637";
|
||||
String res = "71412358434940908477702819237626";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for two positive numbers; the first is longer
|
||||
*/
|
||||
@Test
|
||||
public void testPosPosFirstLonger() {
|
||||
String numA = "2837462783428374767845648748973847593874837948575684767";
|
||||
String numB = "293478573489347658763745839457637";
|
||||
String res = "2837462783428374767845615168483972194300564226167553530";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for two positive numbers; the first is shorter
|
||||
*/
|
||||
@Test
|
||||
public void testPosPosFirstShorter() {
|
||||
String numA = "293478573489347658763745839457637";
|
||||
String numB = "2837462783428374767845648748973847593874837948575684767";
|
||||
String res = "2837462783428374767845615168483972194300564226167553530";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for two negative numbers of the same length
|
||||
*/
|
||||
@Test
|
||||
public void testNegNegSameLength() {
|
||||
String numA = "-283746278342837476784564875684767";
|
||||
String numB = "-293478573489347658763745839457637";
|
||||
String res = "71412358434940908477702819237626";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for two negative numbers; the first is longer
|
||||
*/
|
||||
@Test
|
||||
public void testNegNegFirstLonger() {
|
||||
String numA = "-2837462783428374767845648748973847593874837948575684767";
|
||||
String numB = "-293478573489347658763745839457637";
|
||||
String res = "2837462783428374767845615168483972194300564226167553530";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for two negative numbers; the first is shorter
|
||||
*/
|
||||
@Test
|
||||
public void testNegNegFirstShorter() {
|
||||
String numA = "293478573489347658763745839457637";
|
||||
String numB = "2837462783428374767845648748973847593874837948575684767";
|
||||
String res = "2837462783428374767845615168483972194300564226167553530";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for two numbers of different signs and the same length
|
||||
*/
|
||||
@Test
|
||||
public void testPosNegSameLength() {
|
||||
String numA = "283746278342837476784564875684767";
|
||||
String numB = "-293478573489347658763745839457637";
|
||||
String res = "-71412358434940908477702819237628";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for two numbers of different signs and the same length
|
||||
*/
|
||||
@Test
|
||||
public void testNegPosSameLength() {
|
||||
String numA = "-283746278342837476784564875684767";
|
||||
String numB = "293478573489347658763745839457637";
|
||||
String res = "-71412358434940908477702819237628";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for a negative and a positive numbers; the first is longer
|
||||
*/
|
||||
@Test
|
||||
public void testNegPosFirstLonger() {
|
||||
String numA = "-2837462783428374767845648748973847593874837948575684767";
|
||||
String numB = "293478573489347658763745839457637";
|
||||
String res = "-2837462783428374767845615168483972194300564226167553532";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for two negative numbers; the first is shorter
|
||||
*/
|
||||
@Test
|
||||
public void testNegPosFirstShorter() {
|
||||
String numA = "-293478573489347658763745839457637";
|
||||
String numB = "2837462783428374767845648748973847593874837948575684767";
|
||||
String res = "-2837462783428374767845615168483972194300564226167553532";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for a positive and a negative numbers; the first is longer
|
||||
*/
|
||||
@Test
|
||||
public void testPosNegFirstLonger() {
|
||||
String numA = "2837462783428374767845648748973847593874837948575684767";
|
||||
String numB = "-293478573489347658763745839457637";
|
||||
String res = "-2837462783428374767845615168483972194300564226167553532";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Xor for a positive and a negative number; the first is shorter
|
||||
*/
|
||||
@Test
|
||||
public void testPosNegFirstShorter() {
|
||||
String numA = "293478573489347658763745839457637";
|
||||
String numB = "-2837462783428374767845648748973847593874837948575684767";
|
||||
String res = "-2837462783428374767845615168483972194300564226167553532";
|
||||
BigInteger aNumber = new BigInteger(numA);
|
||||
BigInteger bNumber = new BigInteger(numB);
|
||||
BigInteger result = aNumber.xor(bNumber);
|
||||
assertTrue(res.equals(result.toString()));
|
||||
}
|
||||
}
|
|
@ -62,7 +62,7 @@ class ResourceProgramTransformer {
|
|||
return Arrays.<Instruction>asList(accessInsn);
|
||||
}
|
||||
ClassReader iface = innerSource.get(method.getClassName());
|
||||
if (!isSubclass(iface, Resource.class.getName())) {
|
||||
if (iface == null || !isSubclass(iface, Resource.class.getName())) {
|
||||
return null;
|
||||
}
|
||||
if (method.getName().startsWith("get")) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user