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

Bug: Uniform Distribution of Integers does not work if range is >= Integer.MAX_VALUE #544

Closed
jlink opened this issue Jan 5, 2024 · 2 comments
Labels

Comments

@jlink
Copy link
Collaborator

jlink commented Jan 5, 2024

Testing Problem

Consider the following test:

@Example
void integers() {
    IntegerArbitrary integers = Arbitraries.integers().withDistribution(RandomDistribution.uniform());
    integers.sampleStream().limit(50).forEach(System.out::println);
}

Which will only create three different values:

-2147483647
-2147483648
1

Discussion

The problem is the implementation of SmallUniformGenerator:

class SmallUniformNumericGenerator implements RandomDistribution.RandomNumericGenerator {

	private final int min;
	private final int max;

	SmallUniformNumericGenerator(BigInteger min, BigInteger max) {
		this.min = min.intValueExact();
		this.max = max.intValueExact();
	}

	@Override
	public BigInteger next(Random random) {
		int bound = Math.abs(max - min) + 1;
		int value = random.nextInt(bound >= 0 ? bound : Integer.MAX_VALUE) + min;
		return BigInteger.valueOf(value);
	}
}

which should only be used if max-min < Integer.MAX_VALUE. See:

public class UniformRandomDistribution implements RandomDistribution {

	@Override
	public RandomNumericGenerator createGenerator(
		int genSize,
		BigInteger min,
		BigInteger max,
		BigInteger center
	) {
		// Small number generation can be faster
		if (isWithinIntegerRange(min, max)) {
			return new SmallUniformNumericGenerator(min, max);
		} else {
			return new BigUniformNumericGenerator(min, max);
		}

	}

	private static boolean isWithinIntegerRange(BigInteger min, BigInteger max) {
		return min.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) >= 0
			&& max.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) <= 0;
	}
}
@jlink jlink added the bug label Jan 5, 2024
jlink added a commit that referenced this issue Feb 1, 2024
@jlink
Copy link
Collaborator Author

jlink commented Feb 1, 2024

Fixed in 0313063

@jlink
Copy link
Collaborator Author

jlink commented Feb 1, 2024

Released in 1.8.3-SNAPSHOT

@jlink jlink closed this as completed Feb 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant