Может ли случайная функция Java быть равна нулю?
Просто из любопытства, может ли Math.random() когда-либо быть нулевым?
Например, если бы у меня было:
while (true){
if (Math.random() == 0)
return 1;
}
Неужели я действительно верну его? Там также ошибка округления, потому что Math.random() возвращает double.
Я спрашиваю, потому что мой профессор CS заявил, что random() идет от 0 до 1 включительно, и я всегда считал, что это эксклюзивно.
Ответы
Ответ 1
В соответствии с документация, "Возвращает двойное значение с положительным знаком, большим или равным 0.0 и меньше 1.0." Это означает, что он может быть равен нулю.
Как Хэнк написал, он является эксклюзивным на верхней границе (никогда не может быть 1), так что, возможно, где ваше замешательство происходит из: -).
Ответ 2
Да, это действительно так. Math.random()
создает глобальный java.util.Random
-генератор с семенем (System.currentTimeMillis() ^ 0x5DEECE66DL) & ((1L << 48) - 1)
и вызывает для него nextDouble()
. Если его семя достигнет состояния 107048004364969L
(и оно будет, так как java.util.Random
имеет полный период), следующий double
сгенерированный будет 0.0
.
Хотя с неудачей вы можете оказаться в неправильном соотношении в цикле, потому что
Random.nextDouble()
продвигает состояние дважды. С небольшим количеством неудач вы могли бы генерировать 2 ^ 47 случайных чисел до того, как цикл завершится, так как я не нашел никаких других семян, которые дают 0.0
.
Семя продвигается, как будто seed = (seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
и удваивается с использованием 26 и 27 верхних бит двух последовательных значений семени. В примере два следующих значения семени будут 0L
и 11L
.
Если вам удастся создать глобальный генератор с System.currentTimeMillis()==107038380838084L
, ваш код немедленно вернется. Вы можете имитировать это:
java.util.Random k = new java.util.Random(107038380838084L);
System.out.println(k.nextDouble()==0);
Ответ 3
Вполне возможно, что он никогда не вернет ровно нуль. Java включен PRNG - это 48-битный LCG, из которого только 32 бит используются. Для всех 53 бит a double
mantissa будет равен нулю, вам по существу нужен хотя бы один вызов next()
, где верхние 32 бита равны нулю, а другая, где большинство из них. (Если я не ошибаюсь, я бы сказал, что это никогда не случится с тем, как работает генератор, но поздно, я устал, и я не буду много на него накладывать.)
Так как в документации метода явно указано, как получены случайные числа, для других реализаций среды выполнения Java также мало возможностей для получения разных результатов. В контракте можно сказать, что номер, который вы получаете, - от [0, 1). Но на практике существует довольно много значений, которые вы никогда не будете бить (потому что вам нужны два последовательных значения от генератора, которые приводят к линейной зависимости между последовательными значениями - всего 48 бит состояния. Вы не можете генерировать все разные 53-битные комбинации из этого - по крайней мере, не так, как это сделано.).
Конечно, поскольку Math.random()
автоматически семя статический экземпляр Random
, нам также может потребоваться рассмотреть семя здесь, что может потребоваться очень специфично для тестового примера. И это может означать, что этот точный момент времени может быть несколько десятилетий или тысячелетий.
Ответ 4
Он включает нуль, исключая один, например, [0, 1)
или 0 <= x < 1
, в зависимости от того, какую нотацию вы предпочитаете.
Ответ 5
В теории, он может вернуть нулевое значение.
На практике вам может потребоваться очень долгое время, чтобы получить ровно нуль. Если генератор случайных чисел хорошо реализован, он имеет не менее 56 бит внутреннего состояния (иначе все биты возвращаемого результата не будут случайными). И это означает, что если распределение значений, созданных случайным, является плоским, то у вас есть максимум один шанс в 2 ^ 56 вернуть значение, все биты которого равны нулю. Это примерно 10 ^ -19. Я бы не затаил дыхание.
(Другие по праву заметили, что, как описано в теории [и предположительно на практике], оно не может вернуть значение 1.0).
Ответ 6
Из java API.
Возвращает двойное значение с положительным знаком, большим или равным 0,0 и менее 1,0
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Math.html#random()
Так что да, возможно.
Ответ 7
Math.random() documented, чтобы вернуть "двойное значение с положительным знаком, большим или равным 0.0 и меньше, чем 1,0"
То есть, включая 0,0, но не 1,0
Ответ 8
также возможно, в совместимой реализации JRE, что он НИКОГДА не возвращает 0.
Ответ 9
Теоретически возможно, что math.random() вернет нулевое значение, но в реальном мире вы можете рассчитывать на то, что это практически никогда не происходит.
Я когда-то запускал свой компьютер в течение недели, ожидая его, он генерировал около десяти триллионов случайных чисел, без нулей.
Но более прямо, это практически эксклюзивно в обоих направлениях.
Ответ 10
От http://java.sun.com/javase/6/docs/api/java/lang/Math.html
random() Возвращает двойное значение с положительным знаком, большим или равным 0.0 и менее 1.0.
Да, это может быть ноль, но не 1. Другими словами, предпочитайте документацию Java через своего профессора CS =)