Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ARROW-61: [Java] Method can return the value bigger than long MAX_VALUE #4266

Merged
merged 1 commit into from May 9, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -25,113 +25,8 @@

public class DecimalUtility {

public static final int MAX_DIGITS = 9;
public static final int DIGITS_BASE = 1000000000;
public static final int DIGITS_MAX = 999999999;
public static final int INTEGER_SIZE = (Integer.SIZE / 8);

public static final String[] decimalToString = {"",
"0",
"00",
"000",
"0000",
"00000",
"000000",
"0000000",
"00000000",
"000000000"};

public static final long[] scale_long_constants = {
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000,
10000000000L,
100000000000L,
1000000000000L,
10000000000000L,
100000000000000L,
1000000000000000L,
10000000000000000L,
100000000000000000L,
1000000000000000000L};

public static final int DECIMAL_BYTE_LENGTH = 16;

/**
* Simple function that returns the static precomputed
* power of ten, instead of using Math.pow.
*/
public static long getPowerOfTen(int power) {
assert power >= 0 && power < scale_long_constants.length;
return scale_long_constants[(power)];
}

/**
* Math.pow returns a double and while multiplying with large digits
* in the decimal data type we encounter noise. So instead of multiplying
* with Math.pow we use the static constants to perform the multiplication
*/
public static long adjustScaleMultiply(long input, int factor) {
int index = Math.abs(factor);
assert index >= 0 && index < scale_long_constants.length;
if (factor >= 0) {
return input * scale_long_constants[index];
} else {
return input / scale_long_constants[index];
}
}

public static long adjustScaleDivide(long input, int factor) {
int index = Math.abs(factor);
assert index >= 0 && index < scale_long_constants.length;
if (factor >= 0) {
return input / scale_long_constants[index];
} else {
return input * scale_long_constants[index];
}
}

/**
* Returns a string representation of the given integer.
* If the length of the given integer is less than the
* passed length, this function will prepend zeroes to the string
*/
public static StringBuilder toStringWithZeroes(int number, int desiredLength) {
String value = ((Integer) number).toString();
int length = value.length();

StringBuilder str = new StringBuilder();
str.append(decimalToString[desiredLength - length]);
str.append(value);

return str;
}

public static StringBuilder toStringWithZeroes(long number, int desiredLength) {
String value = ((Long) number).toString();
int length = value.length();

StringBuilder str = new StringBuilder();

// Desired length can be > MAX_DIGITS
int zeroesLength = desiredLength - length;
while (zeroesLength > MAX_DIGITS) {
str.append(decimalToString[MAX_DIGITS]);
zeroesLength -= MAX_DIGITS;
}
str.append(decimalToString[zeroesLength]);
str.append(value);

return str;
}

/**
* Read an ArrowType.Decimal at the given value index in the ArrowBuf and convert to a BigDecimal
* with the given scale.
Expand Down