Я создал класс с именем QuickRandom
, и его задача - быстро генерировать случайные числа. Это действительно просто: просто возьмите старое значение, умножьте на a double
и возьмите десятичную часть.
Вот мой QuickRandom
класс в полном объеме:
public class QuickRandom {
private double prevNum;
private double magicNumber;
public QuickRandom(double seed1, double seed2) {
if (seed1 >= 1 || seed1 < 0) throw new IllegalArgumentException("Seed 1 must be >= 0 and < 1, not " + seed1);
prevNum = seed1;
if (seed2 <= 1 || seed2 > 10) throw new IllegalArgumentException("Seed 2 must be > 1 and <= 10, not " + seed2);
magicNumber = seed2;
}
public QuickRandom() {
this(Math.random(), Math.random() * 10);
}
public double random() {
return prevNum = (prevNum*magicNumber)%1;
}
}
И вот код, который я написал, чтобы проверить это:
public static void main(String[] args) {
QuickRandom qr = new QuickRandom();
/*for (int i = 0; i < 20; i ++) {
System.out.println(qr.random());
}*/
//Warm up
for (int i = 0; i < 10000000; i ++) {
Math.random();
qr.random();
System.nanoTime();
}
long oldTime;
oldTime = System.nanoTime();
for (int i = 0; i < 100000000; i ++) {
Math.random();
}
System.out.println(System.nanoTime() - oldTime);
oldTime = System.nanoTime();
for (int i = 0; i < 100000000; i ++) {
qr.random();
}
System.out.println(System.nanoTime() - oldTime);
}
Это очень простой алгоритм, который просто умножает предыдущий двойной на «магическое число» двойной. Я бросил это вместе довольно быстро, так что я, вероятно, мог сделать это лучше, но странно, это, кажется, работает хорошо.
Это пример вывода закомментированных строк в main
методе:
0.612201846732229
0.5823974655091941
0.31062451498865684
0.8324473610354004
0.5907187526770246
0.38650264675748947
0.5243464344127049
0.7812828761272188
0.12417247811074805
0.1322738256858378
0.20614642573072284
0.8797579436677381
0.022122999476108518
0.2017298328387873
0.8394849894162446
0.6548917685640614
0.971667953190428
0.8602096647696964
0.8438709031160894
0.694884972852229
Гектометр Довольно случайно. Фактически, это сработало бы для генератора случайных чисел в игре.
Вот пример вывода некомментированной части:
5456313909
1427223941
Вот Это Да! Он работает почти в 4 раза быстрее, чемMath.random
.
Я помню, как читал где-то, что Math.random
использовало System.nanoTime()
множество тонных модулей и делений Это действительно необходимо? Мой алгоритм работает намного быстрее и кажется довольно случайным.
У меня есть два вопроса:
- Является ли мой алгоритм «достаточно хорошим» (например, для игры, где действительно случайные числа не слишком важны)?
- Почему
Math.random
так много, когда кажется, что достаточно простого умножения и вырезания десятичной дроби?
new QuickRandom(0,5)
или new QuickRandom(.5, 2)
. Они оба будут неоднократно выводить 0 для вашего номера.