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;