Adds java.math support

This commit is contained in:
konsoletyper 2014-06-27 18:04:42 +04:00
parent 08c912e80f
commit e5a4e3fa62
33 changed files with 20686 additions and 1 deletions

View File

@ -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

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View File

@ -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=&lt;precision&gt; roundingMode=&lt;roundingMode&gt;"
* 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=&lt;precision&gt; roundingMode=&lt;roundingMode&gt;"
* } where {@code &lt;precision&gt;} is an integer describing the number
* of digits used for operations and {@code &lt;roundingMode&gt;} 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();
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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");
}
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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);
}
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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());
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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));
}
}

View File

@ -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()));
}
}

View File

@ -62,7 +62,7 @@ class ResourceProgramTransformer {
return Arrays.<Instruction>asList(accessInsn);
}
ClassReader iface = innerSource.get(method.getClassName());
if (!isSubclass(iface, Resource.class.getName())) {
if (iface == null || !isSubclass(iface, Resource.class.getName())) {
return null;
}
if (method.getName().startsWith("get")) {