А именно, он никогда не будет генерировать более 16 четных чисел в строке с некоторыми конкретными параметрами upperBound
:
Random random = new Random();
int c = 0;
int max = 17;
int upperBound = 18;
while (c <= max) {
int nextInt = random.nextInt(upperBound);
boolean even = nextInt % 2 == 0;
if (even) {
c++;
} else {
c = 0;
}
}
В этом примере код будет циклическим навсегда, тогда как upperBound
, например, 16, он быстро завершается.
Что может быть причиной такого поведения? В методе javadoc есть некоторые примечания, но я их не понял.
UPD1: код, кажется, заканчивается с нечетными верхними границами, но может зависеть даже от четных
UPD2:
Я изменил код, чтобы зафиксировать статистику c
, как это предложено в комментариях:
Random random = new Random();
int c = 0;
long trials = 1 << 58;
int max = 20;
int[] stat = new int[max + 1];
while (trials > 0) {
while (c <= max && trials > 0) {
int nextInt = random.nextInt(18);
boolean even = nextInt % 2 == 0;
if (even) {
c++;
} else {
stat[c] = stat[c] + 1;
c = 0;
}
trials--;
}
}
System.out.println(Arrays.toString(stat));
Теперь он пытается достичь 20
evens в строке - чтобы получить лучшую статистику, а upperBound
по-прежнему 18
.
Результаты оказались более чем удивительными:
[16776448, 8386560, 4195328, 2104576, 1044736,
518144, 264704, 132096, 68864, 29952, 15104,
12032, 1792, 3072, 256, 512, 0, 256, 0, 0]
Сначала он уменьшается, как ожидалось, в 2 раза, но обратите внимание на последнюю строку! Здесь он сходит с ума, и захваченная статистика кажется совершенно странной.
Вот график штриховки в шкале журнала:
Как c
получает значение 17
256 раз - еще одна загадка