in commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/DiscreteUniformSampler.java [383:420]
public static SharedStateDiscreteSampler of(UniformRandomProvider rng,
int lower,
int upper) {
if (lower > upper) {
throw new IllegalArgumentException(lower + " > " + upper);
}
// Choose the algorithm depending on the range
// Edge case for no range.
// This must be done first as the methods to handle lower == 0
// do not handle upper == 0.
if (upper == lower) {
return new FixedDiscreteUniformSampler(lower);
}
// Algorithms to ignore the lower bound if it is zero.
if (lower == 0) {
return createZeroBoundedSampler(rng, upper);
}
final int range = (upper - lower) + 1;
// Check power of 2 first to handle range == 2^31.
if (isPowerOf2(range)) {
return new OffsetDiscreteUniformSampler(lower,
new PowerOf2RangeDiscreteUniformSampler(rng, range));
}
if (range <= 0) {
// The range is too wide to fit in a positive int (larger
// than 2^31); use a simple rejection method.
// Note: if range == 0 then the input is [Integer.MIN_VALUE, Integer.MAX_VALUE].
// No specialisation exists for this and it is handled as a large range.
return new LargeRangeDiscreteUniformSampler(rng, lower, upper);
}
// Use a sample from the range added to the lower bound.
return new OffsetDiscreteUniformSampler(lower,
new SmallRangeDiscreteUniformSampler(rng, range));
}