Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ public final class MathFunctions
private static final Int128[] DECIMAL_HALF_UNSCALED_FOR_SCALE;
private static final Int128[] DECIMAL_ALMOST_HALF_UNSCALED_FOR_SCALE;

// Lookup table of 10^n as double for small non-negative n. Values are bit-exact matches of Math.pow(10, n)
// for n in [0, 18]; see Pow10 verification in the session notes. Hot-path round(double, long) and
// roundReal(long, long) use this to avoid calling Math.pow for the typical decimals range.
private static final double[] POWERS_OF_TEN_DOUBLE = new double[] {
1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 10000000.0, 100000000.0, 1000000000.0,
10000000000.0, 100000000000.0, 1000000000000.0, 10000000000000.0, 100000000000000.0,
1000000000000000.0, 10000000000000000.0, 100000000000000000.0, 1000000000000000000.0
};

static {
DECIMAL_HALF_UNSCALED_FOR_SCALE = new Int128[Decimals.MAX_PRECISION];
DECIMAL_ALMOST_HALF_UNSCALED_FOR_SCALE = new Int128[Decimals.MAX_PRECISION];
Expand All @@ -102,6 +111,14 @@ public final class MathFunctions
}
}

private static double powerOfTen(long decimals)
{
if (decimals >= 0 && decimals < POWERS_OF_TEN_DOUBLE.length) {
return POWERS_OF_TEN_DOUBLE[(int) decimals];
}
return Math.pow(10, decimals);
}

private MathFunctions() {}

@Description("Absolute value")
Expand Down Expand Up @@ -899,7 +916,7 @@ public static double round(@SqlType(StandardTypes.DOUBLE) double num, @SqlType(S
return num;
}

double factor = Math.pow(10, decimals);
double factor = powerOfTen(decimals);
int sign = (num < 0) ? -1 : 1;
double rescaled = sign * num * factor;
long rescaledRound = Math.round(rescaled);
Expand All @@ -926,7 +943,7 @@ public static long roundReal(@SqlType(StandardTypes.REAL) long num, @SqlType(Sta
return num;
}

double factor = Math.pow(10, decimals);
double factor = powerOfTen(decimals);
int sign = (numInFloat < 0) ? -1 : 1;
double result;
double rescaled = sign * numInFloat * factor;
Expand Down