Math.random()
Содержание:
- How does Random.js alleviate these problems?
- Using Java API
- The Math.random() method
- Проверка: isFinite и isNaN
- Игра в кости с использованием модуля random в Python
- Генерация случайных чисел с помощью класса Math
- Зачем нужны функции getstate() и setstate() ?
- Math.Random() Example
- Alternate API
- Псевдослучайные числа
- Method Summary
How does Random.js alleviate these problems?
Random.js provides a set of «engines» for producing random integers, which consistently provide values within , i.e. 32 bits of randomness.
One is also free to implement their own engine as long as it returns 32-bit integers, either signed or unsigned.
Some common, biased, incorrect tool for generating random integers is as follows:
The problem with both of these approaches is that the distribution of integers that it returns is not uniform. That is, it might be more biased to return rather than , making it inherently broken.
may more evenly distribute its biased, but it is still wrong. , at least in the example given, is heavily biased to return over .
In order to eliminate bias, sometimes the engine which random data is pulled from may need to be used more than once.
Random.js provides a series of distributions to alleviate this.
Using Java API
The Java API provides us with several ways to achieve our purpose. Let’s see some of them.
2.1. java.lang.Math
The random method of the Math class will return a double value in a range from 0.0 (inclusive) to 1.0 (exclusive). Let’s see how we’d use it to get a random number in a given range defined by min and max:
2.2. java.util.Random
Before Java 1.7, the most popular way of generating random numbers was using nextInt. There were two ways of using this method, with and without parameters. The no-parameter invocation returns any of the int values with approximately equal probability. So, it’s very likely that we’ll get negative numbers:
If we use the netxInt invocation with the bound parameter, we’ll get numbers within a range:
This will give us a number between 0 (inclusive) and parameter (exclusive). So, the bound parameter must be greater than 0. Otherwise, we’ll get a java.lang.IllegalArgumentException.
Java 8 introduced the new ints methods that return a java.util.stream.IntStream. Let’s see how to use them.
The ints method without parameters returns an unlimited stream of int values:
We can also pass in a single parameter to limit the stream size:
And, of course, we can set the maximum and minimum for the generated range:
2.3. java.util.concurrent.ThreadLocalRandom
Java 1.7 release brought us a new and more efficient way of generating random numbers via the ThreadLocalRandom class. This one has three important differences from the Random class:
- We don’t need to explicitly initiate a new instance of ThreadLocalRandom. This helps us to avoid mistakes of creating lots of useless instances and wasting garbage collector time
- We can’t set the seed for ThreadLocalRandom, which can lead to a real problem. If we need to set the seed, then we should avoid this way of generating random numbers
- Random class doesn’t perform well in multi-threaded environments
Now, let’s see how it works:
With Java 8 or above, we have new possibilities. Firstly, we have two variations for the nextInt method:
Secondly, and more importantly, we can use the ints method:
2.4. java.util.SplittableRandom
Java 8 has also brought us a really fast generator — the SplittableRandom class.
As we can see in the JavaDoc, this is a generator for use in parallel computations. It’s important to know that the instances are not thread-safe. So, we have to take care when using this class.
We have available the nextInt and ints methods. With nextInt we can set directly the top and bottom range using the two parameters invocation:
This way of using checks that the max parameter is bigger than min. Otherwise, we’ll get an IllegalArgumentException. However, it doesn’t check if we work with positive or negative numbers. So, any of the parameters can be negative. Also, we have available one- and zero-parameter invocations. Those work in the same way as we have described before.
We have available the ints methods, too. This means that we can easily get a stream of int values. To clarify, we can choose to have a limited or unlimited stream. For a limited stream, we can set the top and bottom for the number generation range:
2.5. java.security.SecureRandom
If we have security-sensitive applications, we should consider using SecureRandom. This is a cryptographically strong generator. Default-constructed instances don’t use cryptographically random seeds. So, we should either:
- Set the seed — consequently, the seed will be unpredictable
- Set the java.util.secureRandomSeed system property to true
This class inherits from java.util.Random. So, we have available all the methods we saw above. For example, if we need to get any of the int values, then we’ll call nextInt without parameters:
On the other hand, if we need to set the range, we can call it with the bound parameter:
We must remember that this way of using it throws IllegalArgumentException if the parameter is not bigger than zero.
The Math.random() method
The object in JavaScript is a built-in object that has properties and methods for performing mathematical calculations.
A common use of the object is to create a random number using the method.
But the method doesn’t actually return a whole number. Instead, it returns a floating-point value between 0 (inclusive) and 1 (exclusive). Also, note that the value returned from is pseudo-random in nature.
Random numbers generated by might seem random, but those numbers will repeat and eventually display a non-random pattern over a period of time.
This is because algorithmic random number generation can never be truly random in nature. This is why we call them pseudo-random number generators (PRNGs).
To learn more about the method you can check out this guide.
Проверка: isFinite и isNaN
Помните эти специальные числовые значения?
- (и ) — особенное численное значение, которое ведёт себя в точности как математическая бесконечность ∞.
- представляет ошибку.
Эти числовые значения принадлежат типу , но они не являются «обычными» числами, поэтому есть функции для их проверки:
-
преобразует значение в число и проверяет является ли оно :
Нужна ли нам эта функция? Разве не можем ли мы просто сравнить ? К сожалению, нет. Значение уникально тем, что оно не является равным ни чему другому, даже самому себе:
-
преобразует аргумент в число и возвращает , если оно является обычным числом, т.е. не :
Иногда используется для проверки, содержится ли в строке число:
Помните, что пустая строка интерпретируется как во всех числовых функциях, включая.
Сравнение
Существует специальный метод Object.is, который сравнивает значения примерно как , но более надёжен в двух особых ситуациях:
- Работает с : , здесь он хорош.
- Значения и разные: , это редко используется, но технически эти значения разные.
Во всех других случаях идентичен .
Этот способ сравнения часто используется в спецификации JavaScript. Когда внутреннему алгоритму необходимо сравнить 2 значения на предмет точного совпадения, он использует (Определение ).
Игра в кости с использованием модуля random в Python
Далее представлен код простой игры в кости, которая поможет понять принцип работы функций модуля random. В игре два участника и два кубика.
- Участники по очереди бросают кубики, предварительно встряхнув их;
- Алгоритм высчитывает сумму значений кубиков каждого участника и добавляет полученный результат на доску с результатами;
- Участник, у которого в результате большее количество очков, выигрывает.
Код программы для игры в кости Python:
Python
import random
PlayerOne = «Анна»
PlayerTwo = «Алекс»
AnnaScore = 0
AlexScore = 0
# У каждого кубика шесть возможных значений
diceOne =
diceTwo =
def playDiceGame():
«»»Оба участника, Анна и Алекс, бросают кубик, используя метод shuffle»»»
for i in range(5):
#оба кубика встряхиваются 5 раз
random.shuffle(diceOne)
random.shuffle(diceTwo)
firstNumber = random.choice(diceOne) # использование метода choice для выбора случайного значения
SecondNumber = random.choice(diceTwo)
return firstNumber + SecondNumber
print(«Игра в кости использует модуль random\n»)
#Давайте сыграем в кости три раза
for i in range(3):
# определим, кто будет бросать кости первым
AlexTossNumber = random.randint(1, 100) # генерация случайного числа от 1 до 100, включая 100
AnnaTossNumber = random.randrange(1, 101, 1) # генерация случайного числа от 1 до 100, не включая 101
if( AlexTossNumber > AnnaTossNumber):
print(«Алекс выиграл жеребьевку.»)
AlexScore = playDiceGame()
AnnaScore = playDiceGame()
else:
print(«Анна выиграла жеребьевку.»)
AnnaScore = playDiceGame()
AlexScore = playDiceGame()
if(AlexScore > AnnaScore):
print («Алекс выиграл игру в кости. Финальный счет Алекса:», AlexScore, «Финальный счет Анны:», AnnaScore, «\n»)
else:
print(«Анна выиграла игру в кости. Финальный счет Анны:», AnnaScore, «Финальный счет Алекса:», AlexScore, «\n»)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
importrandom PlayerOne=»Анна» PlayerTwo=»Алекс» AnnaScore= AlexScore= diceOne=1,2,3,4,5,6 diceTwo=1,2,3,4,5,6 defplayDiceGame() «»»Оба участника, Анна и Алекс, бросают кубик, используя метод shuffle»»» foriinrange(5) #оба кубика встряхиваются 5 раз random.shuffle(diceOne) random.shuffle(diceTwo) firstNumber=random.choice(diceOne)# использование метода choice для выбора случайного значения SecondNumber=random.choice(diceTwo) returnfirstNumber+SecondNumber print(«Игра в кости использует модуль random\n») foriinrange(3) # определим, кто будет бросать кости первым AlexTossNumber=random.randint(1,100)# генерация случайного числа от 1 до 100, включая 100 AnnaTossNumber=random.randrange(1,101,1)# генерация случайного числа от 1 до 100, не включая 101 if(AlexTossNumber>AnnaTossNumber) print(«Алекс выиграл жеребьевку.») AlexScore=playDiceGame() AnnaScore=playDiceGame() else print(«Анна выиграла жеребьевку.») AnnaScore=playDiceGame() AlexScore=playDiceGame() if(AlexScore>AnnaScore) print(«Алекс выиграл игру в кости. Финальный счет Алекса:»,AlexScore,»Финальный счет Анны:»,AnnaScore,»\n») else print(«Анна выиграла игру в кости. Финальный счет Анны:»,AnnaScore,»Финальный счет Алекса:»,AlexScore,»\n») |
Вывод:
Shell
Игра в кости использует модуль random
Анна выиграла жеребьевку.
Анна выиграла игру в кости. Финальный счет Анны: 5 Финальный счет Алекса: 2
Анна выиграла жеребьевку.
Анна выиграла игру в кости. Финальный счет Анны: 10 Финальный счет Алекса: 2
Алекс выиграл жеребьевку.
Анна выиграла игру в кости. Финальный счет Анны: 10 Финальный счет Алекса: 8
1 2 3 4 5 6 7 8 9 10 |
Игравкостииспользуетмодульrandom Аннавыигралаигрувкости.ФинальныйсчетАнны5ФинальныйсчетАлекса2 Аннавыигралаигрувкости.ФинальныйсчетАнны10ФинальныйсчетАлекса2 Аннавыигралаигрувкости.ФинальныйсчетАнны10ФинальныйсчетАлекса8 |
Вот и все. Оставить комментарии можете в секции ниже.
Генерация случайных чисел с помощью класса Math
Чтобы сгенерировать случайное число Java предоставляет класс Math, доступный в пакете java.util. Этот класс содержит статичный метод Math.random(), предназначенный для генерации случайных чисел типа double .
Метод random( ) возвращает положительное число большее или равное 0,0 и меньшее 1,0. При вызове данного метода создается объект генератора псевдослучайных чисел java.util.Random.
Math.random() можно использовать с параметрами и без. В параметрах задается диапазон чисел, в пределах которого будут генерироваться случайные значения.
Пример использования Math.random():
public static double getRandomNumber(){ double x = Math.random(); return x; }
Метод getRandomNumber( ) использует Math.random() для возврата положительного числа, которое больше или равно 0,0 или меньше 1,0 .
Результат выполнения кода:
Double between 0.0 and 1.0: SimpleRandomNumber = 0.21753313144345698
Случайные числа в заданном диапазоне
Для генерации случайных чисел в заданном диапазоне необходимо указать диапазон. Синтаксис:
(Math.random() * ((max - min) + 1)) + min
Разобьем это выражение на части:
- Сначала умножаем диапазон значений на результат, который генерирует метод random().Math.random() * (max — min)возвращает значение в диапазоне , где max не входит в заданные рамки. Например, выражение Math.random()*5 вернет значение в диапазоне , в который 5 не входит.
- Расширяем охват до нужного диапазона. Это делается с помощью минимального значения.
(Math.random() * ( max - min )) + min
Но выражение по-прежнему не охватывает максимальное значение.
Чтобы получить максимальное значение, прибавьте 1 к параметру диапазона (max — min). Это вернет случайное число в указанном диапазоне.
double x = (Math.random()*((max-min)+1))+min;
Существуют различные способы реализации приведенного выше выражения. Рассмотрим некоторые из них.
Случайное двойное число в заданном диапазоне
По умолчанию метод Math.random() при каждом вызове возвращает случайное число типа double . Например:
public static double getRandomDoubleBetweenRange(double min, double max){ double x = (Math.random()*((max-min)+1))+min; return x; }
Вы можете вызвать предыдущий метод из метода main, передав аргументы, подобные этому.
System.out.println("Double between 5.0 and 10.00: RandomDoubleNumber = "+getRandomDoubleBetweenRange(5.0, 10.00));
Результат.
System.out.println("Double between 5.0 and 10.00: RandomDoubleNumber = "+getRandomDoubleBetweenRange(5.0, 10.00));
Случайное целое число в заданном диапазоне
Пример генерации случайного целочисленного значения в указанном диапазоне:
public static double getRandomIntegerBetweenRange(double min, double max){ double x = (int)(Math.random()*((max-min)+1))+min; return x; }
Метод getRandomIntegerBetweenRange() создает случайное целое число в указанном диапазоне. Так как Math.random() генерирует случайные числа с плавающей запятой, то нужно привести полученное значение к типу int. Этот метод можно вызвать из метода main, передав ему аргументы следующим образом:
System.out.println("Integer between 2 and 6: RandomIntegerNumber = "+getRandomIntegerBetweenRange(2,6));
Результат.
Integer between 2 and 6: RandomIntegerNumber = 5
Примечание. В аргументах также можно передать диапазон отрицательных значений, чтобы сгенерировать случайное отрицательное число в этом диапазоне.
Зачем нужны функции getstate() и setstate() ?
Если вы получили предыдущее состояние и восстановили его, тогда вы сможете оперировать одними и теми же случайными данными раз за разом. Помните, что использовать другую функцию random в данном случае нельзя. Также нельзя изменить значения заданных параметров. Сделав это, вы измените значение состояния .
Для закрепления понимания принципов работы и в генераторе случайных данных Python рассмотрим следующий пример:
Python
import random
number_list =
print(«Первая выборка «, random.sample(number_list,k=5))
# хранит текущее состояние в объекте state
state = random.getstate()
print(«Вторая выборка «, random.sample(number_list,k=5))
# Восстанавливает состояние state, используя setstate
random.setstate(state)
#Теперь будет выведен тот же список второй выборки
print(«Третья выборка «, random.sample(number_list,k=5))
# Восстанавливает текущее состояние state
random.setstate(state)
# Вновь будет выведен тот же список второй выборки
print(«Четвертая выборка «, random.sample(number_list,k=5))
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
importrandom number_list=3,6,9,12,15,18,21,24,27,30 print(«Первая выборка «,random.sample(number_list,k=5)) state=random.getstate() print(«Вторая выборка «,random.sample(number_list,k=5)) random.setstate(state) print(«Третья выборка «,random.sample(number_list,k=5)) random.setstate(state) print(«Четвертая выборка «,random.sample(number_list,k=5)) |
Вывод:
Shell
Первая выборка
Вторая выборка
Третья выборка
Четвертая выборка
1 2 3 4 |
Перваявыборка18,15,30,9,6 Втораявыборка27,15,12,9,6 Третьявыборка27,15,12,9,6 Четвертаявыборка27,15,12,9,6 |
Как можно заметить в результате вывода — мы получили одинаковые наборы данных. Это произошло из-за сброса генератора случайных данных.
Math.Random() Example
Here’s an example of the method in action:
import java.lang.Math; class Main { public static void main(String[] args) { double number = Math.random(); System.out.println("Random number: " + number); } }
Our code returns:
As you can see, our program has returned a random number between 0 and 1. However, this number is not very useful in its current form. If we want to generate a random number for a guessing game, for instance, we would not want to have a decimal number.
In order to produce a whole number with our pseudorandom number generator, we can multiply our random number by another number and round it to the nearest whole number. For instance, suppose we wanted to generate a random number between 1 and 10. We could do so using this code:
class Main { public static void main(String[] args) { int number = (int)(Math.random() * 10); System.out.println("Random number: " + number); } }
Here is the result of our program after running it three times:
4
6
2
As you can see, our program returns a random integer, or whole number.
Let’s break down our code. First, we declared a class called Main which stores the code for our program.
Then we used the method to generate a random number, and we multiplied that number by 10. After we multiplied the result by 10, we converted it to an integer, which rounds it to the nearest decimal place and gives us a whole number.
Then, on the final line, we print out the message “Random number: “ to the console, followed by the random number our program generated.
If we wanted to generate a larger number, we could replace the * 10 parts of our code with another number. For instance, say we wanted to generate a number between 1 and 1000. We could do so by replacing * 10 with * 1000 like this:
class Main { public static void main(String[] args) { int number = (int)(Math.random() * 1000); System.out.println("Random number: " + number); } }
After executing our program three times, the following response was returned:
181
914
939
Alternate API
There is an alternate API which may be easier to use, but may be less performant. In scenarios where performance is paramount, it is recommended to use the aforementioned API.
const random = new Random( MersenneTwister19937.seedWithArray(0x12345678, 0x90abcdef) ); const value = r.integer(, 99); const otherRandom = new Random(); // same as new Random(nativeMath)
This abstracts the concepts of engines and distributions.
- : Produce an integer within the inclusive range . can be at its minimum -9007199254740992 (2 ** 53). can be at its maximum 9007199254740992 (2 ** 53). The special number is never returned.
- : Produce a floating point number within the range . Uses 53 bits of randomness.
- : Produce a boolean with a 50% chance of it being .
- : Produce a boolean with the specified chance causing it to be .
- : Produce a boolean with / chance of it being true.
- : Return a random value within the provided within the sliced bounds of and .
- : Shuffle the provided (in-place). Similar to .
- : From the array, produce an array with elements that are randomly chosen without repeats.
- : Same as
- : Produce an array of length with as many rolls.
- : Produce a random string using numbers, uppercase and lowercase letters, , and of length .
- : Produce a random string using the provided string as the possible characters to choose from of length .
- or : Produce a random string comprised of numbers or the characters of length .
- : Produce a random string comprised of numbers or the characters of length .
- : Produce a random within the inclusive range of . and must both be s.
Псевдослучайные числа
Иногда программист сталкивается с простыми, казалось бы, задачами: «отобрать случайный фильм для вечернего просмотра из определенного списка», «выбрать победителя лотереи», «перемешать список песен при тряске смартфона», «выбрать случайное число для шифрования сообщения», и каждый раз у него возникает очень закономерный вопрос: а как получить это самое случайное число?
Вообще-то, если вам нужно получить «настоящее случайное число», сделать это довольно-таки трудно. Вплоть до того, что в компьютер встраивают специальные математические сопроцессоры, которые умеют генерировать такие числа, с выполнением всех требований к «истинной случайности».
Поэтому программисты придумали свое решение — псевдослучайные числа. Псевдослучайные числа — это некая последовательность, числа в которой на первый взгляд кажутся случайными, но специалист при детальном анализе сможет найти в них определенные закономерности. Для шифрования секретных документов такие числа не подойдут, а для имитации бросания кубика в игре — вполне.
Есть много алгоритмов генерации последовательности псевдослучайных чисел и почти все из них генерируют следующее случайное число на основе предыдущего и еще каких-то вспомогательных чисел.
Например, данная программа выведет на экран неповторяющихся чисел:
Кстати, мы говорим не о псевдослучайных числах, а именно о последовательности таких чисел. Т.к. глядя на одно число невозможно понять, случайное оно или нет.
Случайное число ведь можно получить разными способами:
Method Summary
All MethodsInstance MethodsConcrete Methods
Modifier and Type | Method | Description |
---|---|---|
Returns an effectively unlimited stream of pseudorandom values, each between zero (inclusive) and one (exclusive). |
||
Returns an effectively unlimited stream of pseudorandom values, each conforming to the given origin (inclusive) and bound (exclusive). |
||
Returns a stream producing the given number of pseudorandom values, each between zero (inclusive) and one (exclusive). |
||
Returns a stream producing the given number of pseudorandom values, each conforming to the given origin (inclusive) and bound (exclusive). |
||
Returns an effectively unlimited stream of pseudorandom values. |
||
Returns an effectively unlimited stream of pseudorandom values, each conforming to the given origin (inclusive) and bound (exclusive). |
||
Returns a stream producing the given number of pseudorandom values. |
||
Returns a stream producing the given number of pseudorandom values, each conforming to the given origin (inclusive) and bound (exclusive). |
||
Returns an effectively unlimited stream of pseudorandom values. |
||
Returns a stream producing the given number of pseudorandom values. |
||
Returns an effectively unlimited stream of pseudorandom values, each conforming to the given origin (inclusive) and bound (exclusive). |
||
Returns a stream producing the given number of pseudorandom , each conforming to the given origin (inclusive) and bound (exclusive). |
||
Generates the next pseudorandom number. | ||
Returns the next pseudorandom, uniformly distributed value from this random number generator’s sequence. |
||
Generates random bytes and places them into a user-supplied byte array. |
||
Returns the next pseudorandom, uniformly distributed value between and from this random number generator’s sequence. |
||
Returns the next pseudorandom, uniformly distributed value between and from this random number generator’s sequence. |
||
Returns the next pseudorandom, Gaussian («normally») distributed value with mean and standard deviation from this random number generator’s sequence. |
||
Returns the next pseudorandom, uniformly distributed value from this random number generator’s sequence. |
||
Returns a pseudorandom, uniformly distributed value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator’s sequence. |
||
Returns the next pseudorandom, uniformly distributed value from this random number generator’s sequence. |
||
Sets the seed of this random number generator using a single seed. |