Случайная функция int

Может кто-нибудь объяснить, почему (int) (Math.random()*12-3) возвращает значения от -2 до 8, а (int) (Math.random()*12)-3 возвращает от -3 до 8?

Разница заключается в размещении скобок, но я не знаю "скрытую" причину, по которой это имеет значение. Если наименьшее значение, которое может вернуть Math.random(), равно 0, это 0 * 12 = 0, и оба должны иметь как минимум -3. Я предполагаю, что это связано с приведением к типу int и от 0.x к 1. Это просто (теоретически) невозможно достичь 0,00000000 ...?

Вы абсолютно уверены, что просто случайно не увидели -3, когда выполняли первый расчет? Попробуйте поместить Math.random() в double и выполнить оба вычисления, распечатав в sysout. Теоретически они должны возвращать один и тот же номер.

David Culbreth 29.11.2018 01:31

Это хороший вопрос. Приведенные ниже ответы, надеюсь, иллюстрируют эффекты приведения к int в разное время в расчете. Обратите внимание, что Math.random() может возвращать 0, но не 1.

Krease 29.11.2018 01:45

Я протестировал это, запустив цикл while, который останавливался только при достижении -3. Он работал около часа без остановки. Я преподаю AP CSA и задаю / тестирую это, потому что вопрос появился в учебном пособии, и в нем утверждалось, что -2 - это минимум для первой функции. Когда я протестировал вторую функцию, она довольно быстро сгенерировала -3.

Lee Jones 29.11.2018 02:03

Вполне возможно запускать его часами и часами и не генерировать 0, но все же это возможно. Другой был намного быстрее, поскольку генерация случайного значения меньше 1/12 гораздо более вероятно, чем одно, точно равное 0.

Krease 29.11.2018 02:42
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
5
4
99
4

Ответы 4

Первый может вернуть -3, это маловероятно.

Math.random():

Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0.

Итак, когда у вас есть (int) (Math.random()*12-3), внутри внутренних круглых скобок результат будет двойным, который вы приведете к int. Это усекает десятичные разряды, поэтому, если Math.random() * 12 не вернет точно 0 (а затем, как только вы вычтите 3, чтобы получить ровно -3), Math.random() * 12 -3 вернется с наименьшим значением 2.{...} и будет усечено до -2.

Когда вы это сделаете:

(int) (Math.random()*12)-3

Приведение имеет большее значение приоритет, чем вычитание, поэтому вероятность усечения до 0 выше. Затем вы вычитаете три, что дает -3.

Приведение к int с помощью (int) обрезает значение с плавающей запятой до 0. Таким образом, с (int) (Math.random()*12-3), даже если мы получаем -2,9999, (int) -2.9999 = -2. В то время как, если мы вычисляем (int) (Math.random()*12), мы можем усечь, например, 0,5 до 0, а затем 0-3 = -3.

Это связано с порядком операций, а также с тем, что (int) someNumberусекаетsomeNumber, если это double. Это означает, что в первом случае крайне маловероятно (но возможно), что Math.random() вернет ноль, в таком случае выражение будет оценивать как -3. Однако любое другое маленькое значение дает (int) -2.[...], который становится -2, потому что он усечен (десятичные дроби просто обрезаются).

В другом случае (int) применяется к Math.random()*12, затем из результата вычитается 3. Здесь каждый раз, когда Math.random()*12 < 1, вы получаете 0 - 3 = -3 в качестве результата. Это случается с 1/12 в большинстве случаев, поэтому вы часто видите, что он дает -3.

Они оба могут достигать -3.

Math.random() возвращает double от 0 (включительно) до 1 (исключая)

При преобразовании в int значение обрезается ближе к 0: (int)(-2.9) == -2 и (int)(2.9) == 2. Фактически, он делает отрицательные числа «больше», а положительные числа «меньше».

Разница в том, что (int) (Math.random()*12)-3 оценивает только часть Math.random()*12, а затем преобразует ее в int - любое случайное значение меньше 1/12 приведет к результату 0 при преобразовании в int с последующим вычитанием 3 листьев -3.

Исходный случай может привести к -3, но ТОЛЬКО когда Math.random() дает результат 0 - гораздо реже, чем предоставление значения меньше 1/12.

Другие вопросы по теме