use of java.math.BigInteger in project hive by apache.
the class FastHiveDecimalImpl method fastLongValueClip.
// We use "Clip" in the name because this method will return a corrupted value when
// fastIsLong returns false.
public static long fastLongValueClip(int fastSignum, long fast0, long fast1, long fast2, int fastIntegerDigitCount, int fastScale) {
if (fastSignum == 0) {
return 0;
}
if (fastScale == 0) {
// Do first comparison as unsigned.
if (fastCompareTo(1, fast0, fast1, fast2, fastScale, FASTHIVEDECIMAL_MAX_LONG_VALUE) <= 0) {
if (fastSignum == 1) {
return fast1 * MULTIPLER_LONGWORD_DECIMAL + fast0;
} else {
return -(fast1 * MULTIPLER_LONGWORD_DECIMAL + fast0);
}
}
if (fastEquals(fastSignum, fast0, fast1, fast2, fastScale, FASTHIVEDECIMAL_MIN_LONG_VALUE)) {
return Long.MIN_VALUE;
} else {
// SLOW: Do remainder with BigInteger.
BigInteger bigInteger = fastBigIntegerValueUnscaled(fastSignum, fast0, fast1, fast2);
return bigInteger.remainder(BIG_INTEGER_UNSIGNED_LONG_MAX_VALUE).longValue();
}
} else {
// Adjust all longs using power 10 division/remainder.
long result0;
long result1;
long result2;
if (fastScale < LONGWORD_DECIMAL_DIGITS) {
// Part of lowest word survives.
final long divideFactor = powerOfTenTable[fastScale];
final long multiplyFactor = powerOfTenTable[LONGWORD_DECIMAL_DIGITS - fastScale];
result0 = fast0 / divideFactor + ((fast1 % divideFactor) * multiplyFactor);
result1 = fast1 / divideFactor + ((fast2 % divideFactor) * multiplyFactor);
result2 = fast2 / divideFactor;
} else if (fastScale < TWO_X_LONGWORD_DECIMAL_DIGITS) {
// Throw away lowest word.
final int adjustedScaleDown = fastScale - LONGWORD_DECIMAL_DIGITS;
final long divideFactor = powerOfTenTable[adjustedScaleDown];
final long multiplyFactor = powerOfTenTable[LONGWORD_DECIMAL_DIGITS - adjustedScaleDown];
result0 = fast1 / divideFactor + ((fast2 % divideFactor) * multiplyFactor);
result1 = fast2 / divideFactor;
result2 = 0;
} else {
// Throw away middle and lowest words.
final int adjustedScaleDown = fastScale - 2 * LONGWORD_DECIMAL_DIGITS;
result0 = fast2 / powerOfTenTable[adjustedScaleDown];
result1 = 0;
result2 = 0;
}
// Do first comparison as UNSIGNED.
if (fastCompareTo(1, result0, result1, result2, /* fastScale */
0, FASTHIVEDECIMAL_MAX_LONG_VALUE) <= 0) {
if (fastSignum == 1) {
return result1 * MULTIPLER_LONGWORD_DECIMAL + result0;
} else {
return -(result1 * MULTIPLER_LONGWORD_DECIMAL + result0);
}
}
if (fastEquals(fastSignum, result0, result1, result2, /* fastScale */
0, FASTHIVEDECIMAL_MIN_LONG_VALUE)) {
// SIGNED comparison to Long.MIN_VALUE decimal.
return Long.MIN_VALUE;
} else {
// SLOW: Do remainder with BigInteger.
BigInteger bigInteger = fastBigIntegerValueUnscaled(fastSignum, result0, result1, result2);
return bigInteger.remainder(BIG_INTEGER_UNSIGNED_LONG_MAX_VALUE).longValue();
}
}
}
use of java.math.BigInteger in project hive by apache.
the class FastHiveDecimalImpl method fastSetFromBigInteger.
/**
* Creates a fast decimal from a BigInteger with a specified scale.
*
* NOTE: The fastSetFromBigInteger method requires the caller to pass a fastResult
* parameter has been reset for better performance.
*
* @param bigInteger the value to set as an integer
* @param scale the scale to use
* @param fastResult an object to reuse
* @return True if the BigInteger and scale were successfully converted to a decimal.
*/
public static boolean fastSetFromBigInteger(BigInteger bigInteger, int scale, FastHiveDecimal fastResult) {
if (scale < 0) {
// Multiply by 10^(-scale) to normalize. We do not use negative scale in our representation.
//
// Example:
// 4.172529E+20 has a negative scale -20 since scale is number of digits below the dot.
// 417252900000000000000 normalized as scale 0.
//
bigInteger = bigInteger.multiply(BIG_INTEGER_TEN.pow(-scale));
scale = 0;
}
int signum = bigInteger.signum();
if (signum == 0) {
// Zero.
return true;
} else if (signum == -1) {
// Normalize to positive.
bigInteger = bigInteger.negate();
}
// A slow way to get the number of decimal digits.
int precision = bigInteger.toString().length();
// System.out.println("FAST_SET_FROM_BIG_INTEGER adjusted bigInteger " + bigInteger + " precision " + precision);
int integerDigitCount = precision - scale;
// System.out.println("FAST_SET_FROM_BIG_INTEGER integerDigitCount " + integerDigitCount + " scale " + scale);
int maxScale;
if (integerDigitCount >= 0) {
if (integerDigitCount > HiveDecimal.MAX_PRECISION) {
return false;
}
maxScale = HiveDecimal.MAX_SCALE - integerDigitCount;
} else {
maxScale = HiveDecimal.MAX_SCALE;
}
if (scale > maxScale) {
// A larger scale is ok -- we will knock off lower digits and round.
final int trimAwayCount = scale - maxScale;
// System.out.println("FAST_SET_FROM_BIG_INTEGER trimAwayCount " + trimAwayCount);
if (trimAwayCount > 1) {
// First, throw away digits below round digit.
BigInteger bigIntegerThrowAwayBelowRoundDigitDivisor = BIG_INTEGER_TEN.pow(trimAwayCount - 1);
bigInteger = bigInteger.divide(bigIntegerThrowAwayBelowRoundDigitDivisor);
}
// System.out.println("FAST_SET_FROM_BIG_INTEGER with round digit bigInteger " + bigInteger + " length " + bigInteger.toString().length());
BigInteger[] quotientAndRemainder = bigInteger.divideAndRemainder(BIG_INTEGER_TEN);
// System.out.println("FAST_SET_FROM_BIG_INTEGER quotientAndRemainder " + Arrays.toString(quotientAndRemainder));
BigInteger quotient = quotientAndRemainder[0];
if (quotientAndRemainder[1].intValue() >= 5) {
if (quotient.equals(BIG_INTEGER_MAX_DECIMAL)) {
if (maxScale == 0) {
// No room above for rounding.
return false;
}
// System.out.println("FAST_SET_FROM_BIG_INTEGER reached here... scale " + scale + " maxScale " + maxScale);
// Rounding results in 10^N.
bigInteger = BIG_INTEGER_TEN.pow(integerDigitCount);
maxScale = 0;
} else {
// Round up.
bigInteger = quotient.add(BigInteger.ONE);
}
} else {
// No rounding.
bigInteger = quotient;
}
scale = maxScale;
}
if (!fastSetFromBigInteger(bigInteger, fastResult)) {
return false;
}
if (fastResult.fast0 == 0 && fastResult.fast1 == 0 && fastResult.fast2 == 0) {
fastResult.fastSignum = 0;
} else {
fastResult.fastSignum = signum;
fastResult.fastIntegerDigitCount = Math.max(0, fastResult.fastIntegerDigitCount - scale);
fastResult.fastScale = scale;
final int trailingZeroCount = fastTrailingDecimalZeroCount(fastResult.fast0, fastResult.fast1, fastResult.fast2, fastResult.fastIntegerDigitCount, scale);
if (trailingZeroCount > 0) {
doFastScaleDown(fastResult, trailingZeroCount, fastResult);
fastResult.fastScale -= trailingZeroCount;
}
}
return true;
}
use of java.math.BigInteger in project hive by apache.
the class FastHiveDecimalImpl method fastShortValueClip.
// We use "Clip" in the name because this method will return a corrupted value when
// fastIsShort returns false.
public static short fastShortValueClip(int fastSignum, long fast0, long fast1, long fast2, int fastIntegerDigitCount, int fastScale) {
if (fastScale == 0) {
if (fast1 == 0 && fast2 == 0) {
if (fastSignum == 1) {
if (fast0 <= Short.MAX_VALUE) {
return (short) fast0;
}
} else {
if (-fast0 >= Short.MIN_VALUE) {
return (short) -fast0;
}
;
}
}
// SLOW: Do remainder with BigInteger.
BigInteger bigInteger = fastBigIntegerValueUnscaled(fastSignum, fast0, fast1, fast2);
return bigInteger.remainder(BIG_INTEGER_UNSIGNED_SHORT_MAX_VALUE).shortValue();
} else {
// Adjust all longs using power 10 division/remainder.
long result0;
long result1;
long result2;
if (fastScale < LONGWORD_DECIMAL_DIGITS) {
// Part of lowest word survives.
final long divideFactor = powerOfTenTable[fastScale];
final long multiplyFactor = powerOfTenTable[LONGWORD_DECIMAL_DIGITS - fastScale];
result0 = fast0 / divideFactor + ((fast1 % divideFactor) * multiplyFactor);
result1 = fast1 / divideFactor + ((fast2 % divideFactor) * multiplyFactor);
result2 = fast2 / divideFactor;
} else if (fastScale < TWO_X_LONGWORD_DECIMAL_DIGITS) {
// Throw away lowest word.
final int adjustedScaleDown = fastScale - LONGWORD_DECIMAL_DIGITS;
final long divideFactor = powerOfTenTable[adjustedScaleDown];
final long multiplyFactor = powerOfTenTable[LONGWORD_DECIMAL_DIGITS - adjustedScaleDown];
result0 = fast1 / divideFactor + ((fast2 % divideFactor) * multiplyFactor);
result1 = fast2 / divideFactor;
result2 = 0;
} else {
// Throw away middle and lowest words.
final int adjustedScaleDown = fastScale - 2 * LONGWORD_DECIMAL_DIGITS;
result0 = fast2 / powerOfTenTable[adjustedScaleDown];
result1 = 0;
result2 = 0;
}
if (result1 == 0 && result2 == 0) {
if (fastSignum == 1) {
if (result0 <= Short.MAX_VALUE) {
return (short) result0;
}
} else {
if (-result0 >= Short.MIN_VALUE) {
return (short) -result0;
}
;
}
}
// SLOW: Do remainder with BigInteger.
BigInteger bigInteger = fastBigIntegerValueUnscaled(fastSignum, result0, result1, result2);
return bigInteger.remainder(BIG_INTEGER_UNSIGNED_SHORT_MAX_VALUE).shortValue();
}
}
use of java.math.BigInteger in project hive by apache.
the class FastHiveDecimalImpl method doAlternateSetFromBigIntegerBytesAndScale.
/**
* When fastSetFromBigIntegerBytesAndScale can handle the input because it is too large,
* we fall back to this.
*/
private static boolean doAlternateSetFromBigIntegerBytesAndScale(byte[] bytes, int offset, int length, int scale, FastHiveDecimal fastResult) {
byte[] byteArray = Arrays.copyOfRange(bytes, offset, offset + length);
BigInteger bigInteger = new BigInteger(byteArray);
// System.out.println("doAlternateSetFromBigIntegerBytesAndScale bigInteger " + bigInteger);
BigDecimal bigDecimal = new BigDecimal(bigInteger, scale);
// System.out.println("doAlternateSetFromBigIntegerBytesAndScale bigDecimal " + bigDecimal);
fastResult.fastReset();
return fastSetFromBigDecimal(bigDecimal, true, fastResult);
}
use of java.math.BigInteger in project kafka by apache.
the class JsonConverterTest method decimalToConnect.
@Test
public void decimalToConnect() {
Schema schema = Decimal.schema(2);
BigDecimal reference = new BigDecimal(new BigInteger("156"), 2);
// Payload is base64 encoded byte[]{0, -100}, which is the two's complement encoding of 156.
String msg = "{ \"schema\": { \"type\": \"bytes\", \"name\": \"org.apache.kafka.connect.data.Decimal\", \"version\": 1, \"parameters\": { \"scale\": \"2\" } }, \"payload\": \"AJw=\" }";
SchemaAndValue schemaAndValue = converter.toConnectData(TOPIC, msg.getBytes());
BigDecimal converted = (BigDecimal) schemaAndValue.value();
assertEquals(schema, schemaAndValue.schema());
assertEquals(reference, converted);
}
Aggregations