Math.random() v/s Random class [duplicate] - java

This question already has answers here:
Math.random() versus Random.nextInt(int)
(4 answers)
Closed 7 years ago.
The Math class in Java has a method, Math.random() which returns a pseudorandom number between 0 and 1.
There is also a class java.util.Random which has various methods like nextInt(), nextFloat(), nextDouble(), nextLong()etc.
My question is that if I want to get a random number in a range (say, 30-70), then which way should I go? The factors under consideration are speed and randomness.

If you look at the implementation of Math.random(), you'll see that it uses an instance of the Random class :
public static double random() {
return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
}
private static final class RandomNumberGeneratorHolder {
static final Random randomNumberGenerator = new Random();
}
Therefore the randomness would be the same.
That said, since you need an int and not a double, you'd better use the nextInt method of the Random class, since it would save you the multiplication and casting of a double to int.
Random rnd = new Random();
int num = rnd.nextInt(41)+30;

I personally would go with the random class, because, in my opinion, it's way easier to use and to influence with parameters, for example for a random number between 30-79
Random r = new Random(); int i = r.nextInt(40)+30;
I hope that helped at least a bit

Math.random() does rely on the Random class. Depending on the case and data type you are using you can use either. For an int Random.nextInt() would probably be the best choice.
Speaking of randomness, a more secure random class is SecureRandom. SecureRandom does not rely on the system time unlike Random, so if your application has a security element to it definitely use SecureRandom. Same method names, except
SecureRandom secureRandom = new SecureRandom() instead of
Random random = new Random().

Related

Random Class with seed

long seed = 0;
Random rand = new Random(seed);
int rand100 = 0;
for(int i = 0; i < 100; i++)
rand100 = rand.nextInt();
System.out.println(rand100);
I wrote this code to get 100th random integer value of given seed. I want to know if there is a way to get 100th random integer value of given seed without calling nextInt() 100 times.
I want to know if there is a way to get 100-th random integer value of given seed without calling nextInt() 100 times.
No, there is no way to directly get the 100-th random number of the sequence without first generating the other 99 values. That's simply because of how the generation works in Java, the values depend on their previous values.
If you want to go into details, take a look at the source code. The internal seed changes with every call of the next method, using the previous seed:
nextseed = (oldseed * multiplier + addend) & mask;
So in order to get the seed for the 100-th value, you need to know the seed for the 99-th value, which needs the seed for the 98-th value and so on.
However, you can easily get the 100-th value with a more compact statement like
long seed = ...
int amount = 100;
Random rnd = new Random(seed);
// Generate sequence of 100 random values, discard 99 and get the last
int val = rnd.ints(100).skip(amount - 1).findFirst().orElse(-1);
Keep in mind that this still computes all previous values, as explained. It just discards them.
After you have computed that value for the first time, you could just hardcode it into your program. Let's suppose you have tested it and it yields 123. Then, if the seed does not change, the value will always be 123. So you could just do
int val = 123;
The sequences remain the same through multiple instance of the JVM, so the value will always be valid for this seed. Don't know about release cycles though, I think it's allowed for Random to change its behavior through different versions of Java.
Yes. As long as the seed is constant, then the result of executing this 100 times will yield the same result every time. As such, you can just do
int rand100 = -1331702554;
If I got you correct, you search for some seeded method like
int[] giveMeInts(int amount, long seed);
There exists something very similar, the Stream methods of Random (documentation):
long seed = ...
int amount = 100;
Random rnd = new Random(seed);
IntStream values = rnd.ints(amount);
You could collect the stream values in collections like List<Integer> or an int[] array:
List<Integer> values = rnd.ints(amount).collect(Collectors.toList());
int[] values = rnd.ints(amount).toArray();
The methods will use the seed of the Random object, so if fed with the same seed they will always produce the same sequence of values.

Seed in java.util.Random [duplicate]

This question already has answers here:
Java random numbers using a seed
(7 answers)
Closed 5 years ago.
If I set seed in Random why always get same random number in below code:
private static void createArray(int[] x) {
for(int i =0; i<x.length; i++){
Random random = new Random(500l);
x[i] = random.nextInt(100000); //53695
}
}
I am getting 53695 for every run and entire loop.
Because that's what happens when you use the same seed in a pseudo-randomnumber generator. It's not random, it just looks "random enough", but it's all thanks to a deterministic mathematical formula.
Use SecureRandom if you need better randomness.
Here are some examples of seeds that provide "interesting" "random" numbers:
http://insights.dice.com/2014/01/24/generating-random-numbers-javas-random-class/

Generate random number with constraint in java [duplicate]

This question already has answers here:
How do I generate random integers within a specific range in Java?
(72 answers)
Math.random() explanation
(5 answers)
Closed 8 years ago.
I need to generate a random integer with Java but random in a one sided bounded specific range. For example, a range from 15+ means that the only constraint is that the lowest value the integer can take is 15.
Random rand = new Random();
int min=15;
int randomNum = rand.nextInt((2147483647 - min) + 1)+ min;
You can create a simple randomInRange function like this:
Yyou want to create the Random object only once so it doesn't have to re-seed each time you call the randomInRange() function.
Random rand;
// ...
// where you initialize stuff (for example the class constructor)
rand = new Random();
// ...
int randomInRange(int min, int max) {
return rand.nextInt((max - min) + 1) + min;
}
If you want to only have the minimum value, maybe create another method like:
int randomFrom(int min) {
return randomInRange(min, Integer.MAX_VALUE);
}
I suggest you make a separate Utilities class that will contain these methods as static and you can call them by saying Utilities.randomInRange()
You can of course make them static in your class as well if these are the only utility methods you will need

Random Number In A Range

I have an app I am writing for iOS and Android. On startup I am trying to get a random number between 1 and 6.
iOS (Objective-C):
int random = rand() % (6 - 1) + 1;
Android (Java):
Random random = new Random();
int num = random.nextInt(6)+1;
In both cases they return 3 every time.
From other questions I have read, people are having the same issue because they are looping through randoms and keep reinstantiating the Random object. But I just want one random number, so I am only instantiating it once.
So, how can I get either of these pieces of code to get a number 1-6 instead of just 3?
For the Objective-C part, I can tell you that you have to seed the random, like this:
srand(time(0)); // seed it using the current time
And for the Java part, the new Random() constructor automatically seeds it in the default JVM for desktop applications, but not on Android. On Android, it uses a default seed value.
Random rand = new Random(System.nanoTime());
In Objective-C, you could alternately use the recommended arc4random() function that does not need to be seeded. You would use it like this:
int random = (arc4random() % 5) + 1;
A huge benefit of this function over rand() is that is has twice the range of rand(), thus allowing for "more random" numbers.
The best solution is to use arc4random_uniform if possible, it is available in iOS 4.3 and above. It eliminates bias that is usually introduced by the mod operator.
+ (u_int32_t)randomInRangeLo:(u_int32_t)loBound toHi:(u_int32_t)hiBound {
int32_t range = hiBound - loBound + 1;
return loBound + arc4random_uniform(range);
}
Note that no seeding is necessary and it produces cryptographic quality random numbers.
Not sure about Random on Android, but in other cases, you probably want to seed the Random instance with something reasonably unique, like the system time.
Random r = new Random(System.currentTimeMillis());
I tried the Java part and it works OK for me, but you can try to instantiate Random using time as a seed:
java.util.Date d = new java.util.Date();
Random random = new Random(d.getTime());
int num = random.nextInt(6)+1;
System.out.println(num);

Java Random Number Generator using a Seed [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java random always returns the same number when I set the seed?
Java Random Numbers Using a Seed
Hi,
This is my code. I am trying to generate 2 random numbers simultaneously using a seed i.e. 15416640. The numbers that are getting generate are not really random.
Random radiusGenerator = new Random(15416640);
Random angleGenerator = new Random(15416640);
try
{
for(int i=1; i<=sequenceNumber; i++)
{
double radius = (0.5 - (0.5 * Math.sqrt(1-radiusGenerator.nextDouble())));
double angle = angleGenerator.nextDouble();
angle = angle*(Math.PI*2);
System.out.print(radius+" "+ angle +"\n");
}
Please Help...Thanks!
That's totally normal and a feature : in a Pseudo Random Generator, the seed defines the sequence of numbers that will be generated.
Use one Random object, and generate everything you want. Since you initialize 2 Random object with the same seed, they will generate the same number if you call with the same method.

Categories

Resources