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);
|
return Arrays.<Instruction>asList(accessInsn);
|
||||||
}
|
}
|
||||||
ClassReader iface = innerSource.get(method.getClassName());
|
ClassReader iface = innerSource.get(method.getClassName());
|
||||||
if (!isSubclass(iface, Resource.class.getName())) {
|
if (iface == null || !isSubclass(iface, Resource.class.getName())) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (method.getName().startsWith("get")) {
|
if (method.getName().startsWith("get")) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user