Java Случайное отображение отрицательных чисел
У меня возникают проблемы с классом Javas Random
, если я это делаю:
Random rng = new Random(seed) // seed == 29 in this example
String ss = "";
for(int i = 0; i < 10; i++)
{
int s = rng.nextInt();
ss += Integer.toString(s);
ss +="\n";
}
Это то, что я верну:
-1169335537
-2076183625
1478047223
1914482305
722089687
2094672350
-1234724057
-1614953544
-321574001
1000360613
Из того, что я прочитал, нужно только возвращать положительные числа для начала?
Это может быть немного надуманным, но не может иметь ничего общего с запуском 64-битной машины на 64-разрядной версии Windows 7?
Любая помощь вообще была бы огромной необходимостью, чтобы это закончилось для руки задания сегодня!
Ответы
Ответ 1
Из Java-документы для nextInt()
:
Все 2 32 возможные значения int производятся с (приблизительно) равной вероятностью.
Один из подходов состоит в использовании следующего преобразования:
s = rng.nextInt() & Integer.MAX_VALUE; // zero out the sign bit
Причиной чего-то вроде этого (в отличие от использования абсолютного значения или отрицания) является то, что Integer.MIN_VALUE
слишком велико по абсолютной величине для превращения в положительное целое число. То есть из-за переполнения, Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE
и Integer.MIN_VALUE == -Integer.MIN_VALUE
. Вышеприведенное преобразование сохраняет приблизительно равномерное свойство распределения: если вы написали цикл генерации и тестирования, который просто выбросил Integer.MIN_VALUE
и вернул абсолютное значение всего остального, тогда положительные целые числа были бы в два раза более вероятными, чем ноль. Путем отображения Integer.MIN_VALUE
в ноль, что приносит вероятность нуля в прямую с положительными целыми числами.
Вот еще один подход, который на самом деле может быть немного быстрее (хотя я его не сравнивал):
int s = rng.next(Integer.SIZE - 1); // Integer.SIZE == 32
Это приведет к генерации целого числа с 31 случайным младшим битом (и 0 как бит 32 nd гарантирующий неотрицательное значение). Однако (как указано в комментарии jjb), поскольку next(int)
является protected
методом Random
, вам нужно подклассифицировать Random
, чтобы разоблачить метод (или предоставить подходящий прокси для метода ):
public class MyRandom extends Random {
public MyRandom() {}
public MyRandom(int seed) { super(seed); }
public int nextNonNegative() {
return next(Integer.SIZE - 1);
}
}
Другой подход - использовать ByteBuffer
, который обертывает 4-байтовый массив. Затем вы можете создать случайные четыре байта (вызывая nextBytes(byte[])
), обнулить знаковый бит и затем прочитать значение как int
. Я не думаю, что это дает какое-либо преимущество над вышеизложенным, но я думал, что просто выброшу его. Это в основном то же самое, что и мое первое решение (которое маскируется с Integer.MAX_VALUE
).
В более ранней версии этого ответа я предложил использовать:
int s = rng.nextInt(Integer.MAX_VALUE);
Однако, согласно docs, он будет генерировать целые числа в диапазоне 0 (включительно) до Integer.MAX_VALUE
(эксклюзивный). Другими словами, он не будет генерировать значение Integer.MAX_VALUE
. Кроме того, оказывается, что next(int)
всегда будет быстрее, чем nextInt(int)
.
Ответ 2
Поскольку существует равная вероятность положительных или отрицательных чисел, почему бы не просто:
Math.abs(rand.nextInt())
Приятно и легко!
Ответ 3
Отрицательные числа разрешены - возможно, вы прочитали аналогичный метод Random nextInt (int), который ограничивает возвращаемые значения равными нулю или больше.
Ответ 4
Посмотрите документацию для java.util.Random:
http://download.oracle.com/javase/6/docs/api/java/util/Random.html
Вы пытаетесь получить случайные числа от 0 до 28? Если это так, вам нужно использовать nextInt (int), как упоминалось ранее. Семена не влияют на диапазон возможных выходов или их относительные вероятности.
Ответ 5
В документации http://download.oracle.com/javase/6/docs/api/java/util/Random.html#nextInt():
Возвращает следующее псевдослучайное равномерно распределенное значение int из этой последовательности генераторов случайных чисел. Общий договор nextInt состоит в том, что одно значение int псевдослучайно генерируется и возвращается. Все 2 ^ 32 возможных значений int производятся с (приблизительно) равной вероятностью.
Просто умножьте на -1, если значение отрицательно
Ответ 6
Вы также можете использовать Math.random(), который возвращает значения от 0 до 1
Ответ 7
int s = rng.nextInt(seed); //seed 29 in this case
Это будет иметь границу 0 до 29.
Ответ 8
Если вам приходится работать с числами, которые имеют возможность иметь отрицательное значение, вы можете автоматически превратить его в положительное значение, используя условное объявление, умножив значение на отрицательное. Вы также можете включить положительное значение в отрицательное значение с помощью этого же метода.
Ниже приведены примеры.
// Turn a negative value into its positive correspondent value.
// If the value is already a positive value, nothing will happen to it.
int a = -5;
a = a < 0? a * -1 : a;
// Turn a positive value into its negative correspondent value.
// If the value is already a negative value, nothing will happen to it.
int b = 5;
b = b > 0? b * -1 : b;