in commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/FastLoadedDiceRollerDiscreteSampler.java [579:603]
private static void scaleWeights(long[] values, int[] exponents) {
// Find the minimum exponent and common trailing zeros.
int minExponent = Integer.MAX_VALUE;
for (int i = 0; i < exponents.length; i++) {
if (values[i] != 0) {
minExponent = Math.min(minExponent, exponents[i]);
}
}
// Trailing zeros occur when the original weights have a representation with
// less than 52 binary digits, e.g. {1.5, 0.5, 0.25}.
int trailingZeros = Long.SIZE;
for (int i = 0; i < values.length && trailingZeros != 0; i++) {
trailingZeros = Math.min(trailingZeros, Long.numberOfTrailingZeros(values[i]));
}
// Scale by a power of 2 so the minimum exponent is zero.
for (int i = 0; i < exponents.length; i++) {
exponents[i] -= minExponent;
}
// Remove common trailing zeros.
if (trailingZeros != 0) {
for (int i = 0; i < values.length; i++) {
values[i] >>>= trailingZeros;
}
}
}